Metadata Inspector

Browse, query, and compare .NET assembly metadata. Standalone command-line tool; no license required to use the inspector itself.

Overview

The Metadata Inspector is a standalone command-line tool for examining .NET assembly metadata. It ships as a separate global tool (WiseOwl.Inspector, command inspector) and requires no Demeanor license to run — installing WiseOwl.Demeanor auto-installs it on first use. 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

Installing Demeanor auto-installs the inspector the first time you run demeanor, so inspector is already on your PATH if you followed Getting Started. To install the inspector on its own (no Demeanor required):

dotnet tool install -g WiseOwl.Inspector

Then run:

inspector MyApp.dll

Two Ways to Use It

One-shot mode (CLI flags)

Pass flags to get a specific view and exit:

inspector MyApp.dll --summary
inspector MyApp.dll --table typedef
inspector MyApp.dll --type WeatherForecast
inspector MyApp.dll --query "show public methods returning string"

Interactive mode (REPL)

Launch without flags to enter the interactive prompt. Type queries directly:

inspector MyApp.dll

inspector> summary
inspector> show public methods
inspector> which types implement IDisposable
inspector> describe OrderService
inspector> quit

Query Language

The inspector understands structured English queries. You don't need to memorize command syntax — describe what you want to see. The inspector shows how it interpreted your query before displaying results.

Showing items

QueryWhat it does
summaryAssembly identity, version, and row counts
show typesList all types
show methodsList all methods
show fieldsList all fields
show propertiesList all properties
show eventsList all events
show resourcesList embedded resources
show assembly referencesList referenced assemblies
show custom attributesList custom attributes
show interfacesList interface types

Filtering by accessibility

QueryWhat it does
show public typesOnly public types
show public methodsOnly public methods
show internal typesOnly internal types
show private methodsOnly private methods

Filtering by signature

QueryWhat it does
show methods returning stringMethods whose return type contains "string"
show methods returning voidMethods returning void
show methods that take intMethods with a parameter type containing "int"
show static methodsStatic methods only
show virtual methodsVirtual methods only
show abstract methodsAbstract methods only

Filtering by owner / location

QueryWhat it does
show methods on CalculatorMethods declared on types matching "Calculator"
show fields on OrderServiceFields on types matching "OrderService"
types in namespace MyApp.ModelsTypes in a specific namespace

Filtering by type hierarchy

QueryWhat it does
which types implement IDisposableTypes implementing a specific interface
types that inherit from ExceptionTypes with a specific base class
types with attribute SerializableTypes decorated with a specific attribute
show generic typesTypes with generic parameters
show sealed typesSealed types

Counting

QueryWhat it does
how many typesCount of types
how many methodsCount of methods
how many fieldsCount of fields
how many propertiesCount of properties
count resourcesCount of embedded resources

Detail views

QueryWhat it does
describe OrderServiceFull type detail: base type, interfaces, fields, methods, properties
show type CalculatorSame as describe
what is WeatherForecastSame as describe

Searching

QueryWhat it does
find CalculatorSearch all types, methods, fields, and properties for "Calculator"
find DisposeSearch 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.

Driving the inspector from an AI assistant (optional)

This section is optional. The inspector’s primary interface is the CLI documented above — the REPL and one-shot commands cover every capability, and the structured English query language needs no AI to work.

If you already use an MCP-capable assistant (Claude Code, Claude Desktop, Cursor, Windsurf, Continue.dev, or any other MCP client), the inspector’s opt-in MCP server lets the assistant answer the same questions in conversation on your behalf. The inspector auto-registers with detected MCP clients the first time you install it — nothing to configure, no separate API key. Everything runs locally; no assembly data leaves your machine. Requires your own Claude subscription — not included with Demeanor.

Ask it anything

What should I exclude before obfuscating this assembly?
The assistant inspects serializable types, data-bound properties, reflection usage, and public API surfaces, then recommends exclusions with rationale.
Which types implement IHostedService?
The assistant queries the metadata and lists the matching types with a brief note on how each one is used.
Compare the pre- and post-obfuscation builds — did anything framework-critical get renamed?
The assistant diffs the two assemblies, separates public from internal renames, and flags anything that should have been frozen but wasn’t.
After obfuscation I’m getting a JSON deserialization error. What went wrong?
The assistant reads both builds, identifies which original type was renamed into the conflict, and suggests the fix.

See the conversational walkthrough for an end-to-end conversation where the assistant drives both the inspector and Demeanor’s audit surface in the same session.

One-Shot CLI Options

All options work from the command line for scripting and CI/CD integration.

Display options

OptionDescription
--summaryAssembly identity and statistics
--metadataDisplay all metadata tables
--table <name>Display specific table(s). Repeatable.
--ilIL disassembly for all methods
--dependenciesAssembly, type, and member references
--type <pattern>Unified type view: fields, methods, properties, events, attributes, MethodImpls
--diff <other.dll>Compare against another assembly
--query <text>, -qNatural language query (one-shot)

Filters and formatting

OptionDescription
--filter <text>Filter rows by name substring. Supports scoped queries: type=Foo, parent=Bar, sig=string
--public-onlyRestrict output to public symbols
--jsonOutput structured JSON for tooling. Forces one-shot mode.

MCP server (optional)

OptionDescription
--mcpStart as an MCP server on stdio so an MCP-capable AI assistant can drive the inspector. Optional; see Driving the inspector from an AI assistant.

Metadata Tables

The inspector can display any of the 31 ECMA-335 metadata tables. Use --table <name> in one-shot mode.

Core tables

Table nameContents
typedefTypes defined in this assembly (classes, interfaces, structs, enums, delegates)
methoddefMethods defined in this assembly
fielddefFields defined in this assembly
paramdefMethod parameters with names and default values
propertyProperties with getter/setter references
eventEvents with add/remove/fire accessors

Reference tables

Table nameContents
typerefTypes referenced from other assemblies
memberrefMethods and fields referenced from other assemblies
assemblyrefReferenced assemblies (dependencies)
typespecInstantiated generic types (e.g., List<string>)
methodspecInstantiated generic methods
modulerefReferenced modules (P/Invoke DLLs)

Relationship tables

Table nameContents
interfaceimplWhich types implement which interfaces
nestedclassNested type relationships
methodimplExplicit method overrides (.override directives)
methodsemanticsProperty/event accessor mappings
propertymapType → property group mappings
eventmapType → event group mappings
customattrCustom attributes on any metadata row

Generic tables

Table nameContents
genericparamGeneric type/method parameters (T, TKey, etc.)

Interop and layout tables

Table nameContents
implmapP/Invoke mappings (unmanaged function imports)
classlayoutExplicit class size and packing
fieldlayoutExplicit field offsets
fieldrvaFields with data stored at fixed RVAs
fieldmarshalMarshalling descriptors for interop
declsecurityDeclarative security attributes
standsigStand-alone signatures (local variable types)

Assembly-level tables

Table nameContents
resourceEmbedded and linked manifest resources
exportedtypeTypes forwarded to other assemblies
fileFiles in a multi-file assembly
constantCompile-time constants (field/param/property defaults)

Examples

Quick overview of an assembly

inspector MyApp.dll --summary

Compare before and after obfuscation

inspector obfuscated/MyApp.dll --diff original/MyApp.dll

Find all types that implement a specific interface

inspector MyApp.dll -q "which types implement IHostedService"

Audit for specific attributes

inspector MyApp.dll -q "types with attribute JsonSerializable"

Check what an obfuscator preserved

inspector obfuscated/MyApp.dll -q "show public properties"

Explore interactively

inspector MyApp.dll

inspector> summary
  Assembly:   MyApp
  Types:      142
  Methods:    891
  ...

inspector> 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))

inspector> describe DbContext
  -> Show details of type DbContext
  === MyApp.Data.DbContext ===
  Base: System.Object
  Implements: System.IDisposable
  Fields (3): ...
  Methods (12): ...

inspector> show methods on DbContext
  -> Show methods on DbContext
  ...

inspector> quit

Script-friendly JSON output

inspector MyApp.dll --json --summary

Drive from an AI assistant (optional)

If you already use an MCP-capable assistant, the inspector can be driven conversationally. See Driving the inspector from an AI assistant.

# Ask (if you use an MCP-capable assistant):
# "Show me all public methods that accept a CancellationToken and return Task"
# The assistant queries the inspector and answers 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:

FieldPurposeValues
VerbWhat to doShow, Find, Count, Detail, List
TargetWhat metadata to queryTypes, Methods, Fields, Properties, Events, CustomAttributes, Interfaces, Resources, AssemblyRefs, Summary, All
FiltersWhich items to includeZero or more filter predicates (see below)
LimitMax resultsAny positive integer, or unlimited
FormatOutput formatTable, 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 fieldApplies toExample
NameAll targetsMethods named "Dispose"
FullNameTypes, MethodsTypes with full name containing "Models"
NamespaceTypesTypes in namespace "MyApp.Data"
ReturnTypeMethodsMethods returning "string"
ParameterTypeMethodsMethods taking "CancellationToken"
FieldTypeFieldsFields of type "Dictionary"
PropertyTypePropertiesProperties of type "string"
BaseTypeTypesTypes inheriting from "Exception"
ImplementsTypesTypes implementing "IDisposable"
HasAttributeTypes, MethodsTypes with [Serializable]
AccessibilityTypes, MethodsPublic, private, internal, protected
OwnerMethods, FieldsMethods on type "Calculator"
IsStaticTypes, Methods, FieldsStatic methods
IsAbstractTypes, MethodsAbstract types or methods
IsSealedTypesSealed types
IsGenericTypesGeneric types (with type parameters)
IsVirtualMethodsVirtual methods
TextAll (search mode)Free-text search across all names

Filter operators

OperatorMeaning
ContainsValue appears anywhere in the field (default, case-insensitive)
EqualsExact match (case-insensitive)
StartsWithField starts with the value
EndsWithField ends with the value
NotField does NOT contain the value
GreaterThanNumeric comparison (for count fields)
LessThanNumeric comparison (for count fields)

In the CLI, the -> interpretation line shows you how your English was parsed before execution. When driving the inspector from an AI assistant, the assistant constructs queries using these same fields and operators.