Metadata Inspector
Browse, query, and compare .NET assembly metadata. Included with Demeanor Enterprise.
Overview
The Metadata Inspector is a standalone command-line tool for examining .NET assembly metadata, included with your Demeanor Enterprise subscription. It reads any .NET assembly (Framework, Core, .NET 5–10) and lets you explore its types, methods, fields, properties, events, custom attributes, IL code, and all 31 ECMA-335 metadata tables.
Use it to:
- Understand the structure of any .NET assembly
- Verify what an obfuscator preserved or renamed
- Compare assemblies before and after obfuscation
- Audit assemblies for specific attributes, interfaces, or patterns
- Decode custom attribute blobs without writing code
Installation
The inspector ships with the Demeanor Enterprise NuGet package:
inspect MyApp.dll
It can also be run directly from the build output:
dotnet path/to/inspect.dll MyApp.dll
Two Ways to Use It
One-shot mode (CLI flags)
Pass flags to get a specific view and exit:
inspect MyApp.dll --summary
inspect MyApp.dll --table typedef
inspect MyApp.dll --type WeatherForecast
inspect MyApp.dll --query "show public methods returning string"
Interactive mode (REPL)
Launch without flags to enter the interactive prompt. Type queries directly:
inspect MyApp.dll
inspect> summary
inspect> show public methods
inspect> which types implement IDisposable
inspect> describe OrderService
inspect> quit
Query Language
The inspector understands structured English queries. You don't need to memorize command syntax — just describe what you want to see. The inspector shows how it interpreted your query before displaying results.
Showing items
| Query | What it does |
summary | Assembly identity, version, and row counts |
show types | List all types |
show methods | List all methods |
show fields | List all fields |
show properties | List all properties |
show events | List all events |
show resources | List embedded resources |
show assembly references | List referenced assemblies |
show custom attributes | List custom attributes |
show interfaces | List interface types |
Filtering by accessibility
| Query | What it does |
show public types | Only public types |
show public methods | Only public methods |
show internal types | Only internal types |
show private methods | Only private methods |
Filtering by signature
| Query | What it does |
show methods returning string | Methods whose return type contains "string" |
show methods returning void | Methods returning void |
show methods that take int | Methods with a parameter type containing "int" |
show static methods | Static methods only |
show virtual methods | Virtual methods only |
show abstract methods | Abstract methods only |
Filtering by owner / location
| Query | What it does |
show methods on Calculator | Methods declared on types matching "Calculator" |
show fields on OrderService | Fields on types matching "OrderService" |
types in namespace MyApp.Models | Types in a specific namespace |
Filtering by type hierarchy
| Query | What it does |
which types implement IDisposable | Types implementing a specific interface |
types that inherit from Exception | Types with a specific base class |
types with attribute Serializable | Types decorated with a specific attribute |
show generic types | Types with generic parameters |
show sealed types | Sealed types |
Counting
| Query | What it does |
how many types | Count of types |
how many methods | Count of methods |
how many fields | Count of fields |
how many properties | Count of properties |
count resources | Count of embedded resources |
Detail views
| Query | What it does |
describe OrderService | Full type detail: base type, interfaces, fields, methods, properties |
show type Calculator | Same as describe |
what is WeatherForecast | Same as describe |
Searching
| Query | What it does |
find Calculator | Search all types, methods, fields, and properties for "Calculator" |
find Dispose | Search across all tables for "Dispose" |
How matching works
All name matching is case-insensitive and uses substring containment by default. show methods on Order matches OrderService, OrderRepository, and ReorderQueue.
AI-Assisted Inspection (MCP)
For complex queries or full obfuscation audits, connect the inspector to Claude Code, Claude Desktop, or any MCP-compatible AI assistant. Instead of learning query syntax, just ask questions in plain English — the AI constructs the right tool calls and gives you contextual answers.
You: "Analyze MyApp.dll and tell me what to exclude before obfuscation."
Claude: [calls inspect_types, inspect_attributes, inspect_properties]
I found 3 areas to review...
See the full AI-Assisted Inspection guide for setup and examples.
One-Shot CLI Options
All options work from the command line for scripting and CI/CD integration.
Display options
| Option | Description |
--summary | Assembly identity and statistics |
--metadata | Display all metadata tables |
--table <name> | Display specific table(s). Repeatable. |
--il | IL disassembly for all methods |
--dependencies | Assembly, type, and member references |
--type <pattern> | Unified type view: fields, methods, properties, events, attributes, MethodImpls |
--diff <other.dll> | Compare against another assembly |
--query <text>, -q | Natural language query (one-shot) |
Filters and formatting
| Option | Description |
--filter <text> | Filter rows by name substring. Supports scoped queries: type=Foo, parent=Bar, sig=string |
--public-only | Restrict output to public symbols |
--json | Output structured JSON for tooling. Forces one-shot mode. |
MCP server
| Option | Description |
--mcp | Start as an MCP server on stdio for AI-assisted inspection. See AI-Assisted Inspection. |
Metadata Tables
The inspector can display any of the 31 ECMA-335 metadata tables. Use --table <name> in one-shot mode.
Core tables
| Table name | Contents |
typedef | Types defined in this assembly (classes, interfaces, structs, enums, delegates) |
methoddef | Methods defined in this assembly |
fielddef | Fields defined in this assembly |
paramdef | Method parameters with names and default values |
property | Properties with getter/setter references |
event | Events with add/remove/fire accessors |
Reference tables
| Table name | Contents |
typeref | Types referenced from other assemblies |
memberref | Methods and fields referenced from other assemblies |
assemblyref | Referenced assemblies (dependencies) |
typespec | Instantiated generic types (e.g., List<string>) |
methodspec | Instantiated generic methods |
moduleref | Referenced modules (P/Invoke DLLs) |
Relationship tables
| Table name | Contents |
interfaceimpl | Which types implement which interfaces |
nestedclass | Nested type relationships |
methodimpl | Explicit method overrides (.override directives) |
methodsemantics | Property/event accessor mappings |
propertymap | Type → property group mappings |
eventmap | Type → event group mappings |
customattr | Custom attributes on any metadata row |
Generic tables
| Table name | Contents |
genericparam | Generic type/method parameters (T, TKey, etc.) |
Interop and layout tables
| Table name | Contents |
implmap | P/Invoke mappings (unmanaged function imports) |
classlayout | Explicit class size and packing |
fieldlayout | Explicit field offsets |
fieldrva | Fields with data stored at fixed RVAs |
fieldmarshal | Marshalling descriptors for interop |
declsecurity | Declarative security attributes |
standsig | Stand-alone signatures (local variable types) |
Assembly-level tables
| Table name | Contents |
resource | Embedded and linked manifest resources |
exportedtype | Types forwarded to other assemblies |
file | Files in a multi-file assembly |
constant | Compile-time constants (field/param/property defaults) |
Examples
Quick overview of an assembly
inspect MyApp.dll --summary
Compare before and after obfuscation
inspect obfuscated/MyApp.dll --diff original/MyApp.dll
Find all types that implement a specific interface
inspect MyApp.dll -q "which types implement IHostedService"
Audit for specific attributes
inspect MyApp.dll -q "types with attribute JsonSerializable"
Check what an obfuscator preserved
inspect obfuscated/MyApp.dll -q "show public properties"
Explore interactively
inspect MyApp.dll
inspect> summary
Assembly: MyApp
Types: 142
Methods: 891
...
inspect> show types implementing IDisposable
-> Show types implementing IDisposable
public class MyApp.Data.DbContext : System.Object
public class MyApp.Services.HttpClientPool : System.Object
(2 type(s))
inspect> describe DbContext
-> Show details of type DbContext
=== MyApp.Data.DbContext ===
Base: System.Object
Implements: System.IDisposable
Fields (3): ...
Methods (12): ...
inspect> show methods on DbContext
-> Show methods on DbContext
...
inspect> quit
Script-friendly JSON output
inspect MyApp.dll --json --summary
AI-assisted inspection
For complex queries, connect the inspector to Claude Code via MCP. See AI-Assisted Inspection.
# In Claude Code, just ask:
# "Show me all public methods that accept a CancellationToken and return Task"
# Claude calls the inspector tools and gives you the answer in context.
How Query Translation Works
Under the hood, every query (whether typed as English or passed via --table) is converted into a structured InspectQuery object with these fields:
| Field | Purpose | Values |
| Verb | What to do | Show, Find, Count, Detail, List |
| Target | What metadata to query | Types, Methods, Fields, Properties, Events, CustomAttributes, Interfaces, Resources, AssemblyRefs, Summary, All |
| Filters | Which items to include | Zero or more filter predicates (see below) |
| Limit | Max results | Any positive integer, or unlimited |
| Format | Output format | Table, Detail, Json, IL |
Available filter fields
Each filter has a field, an operator, and a value. Not every field applies to every target — the inspector validates compatibility and rejects mismatched combinations.
| Filter field | Applies to | Example |
Name | All targets | Methods named "Dispose" |
FullName | Types, Methods | Types with full name containing "Models" |
Namespace | Types | Types in namespace "MyApp.Data" |
ReturnType | Methods | Methods returning "string" |
ParameterType | Methods | Methods taking "CancellationToken" |
FieldType | Fields | Fields of type "Dictionary" |
PropertyType | Properties | Properties of type "string" |
BaseType | Types | Types inheriting from "Exception" |
Implements | Types | Types implementing "IDisposable" |
HasAttribute | Types, Methods | Types with [Serializable] |
Accessibility | Types, Methods | Public, private, internal, protected |
Owner | Methods, Fields | Methods on type "Calculator" |
IsStatic | Types, Methods, Fields | Static methods |
IsAbstract | Types, Methods | Abstract types or methods |
IsSealed | Types | Sealed types |
IsGeneric | Types | Generic types (with type parameters) |
IsVirtual | Methods | Virtual methods |
Text | All (search mode) | Free-text search across all names |
Filter operators
| Operator | Meaning |
Contains | Value appears anywhere in the field (default, case-insensitive) |
Equals | Exact match (case-insensitive) |
StartsWith | Field starts with the value |
EndsWith | Field ends with the value |
Not | Field does NOT contain the value |
GreaterThan | Numeric comparison (for count fields) |
LessThan | Numeric comparison (for count fields) |
When using AI-assisted inspection via MCP, the AI assistant constructs queries using these exact fields and operators. In the CLI, the -> interpretation line shows you how your English was parsed before execution.