What assembly is this RuntimeAssembly?

Say that you are debugging a .NET application in windbg and happen to have a System.Reflection.RuntimeAssembly (the actual implementation of System.Reflection.Assembly) and you want to find out which assembly it actually references. You could try dumping the object (i'm using the sosex extension here):

0:004> !mdt -r 05f7868c
05f7868c (System.Reflection.RuntimeAssembly)
_ModuleResolve:NULL (System.Reflection.ModuleResolveEventHandler)
m_fullname:NULL (System.String)
m_syncRoot:NULL (System.Object)
m_assembly:0eaa4ba8 (System.IntPtr)
m_flags:0x0 (ASSEMBLY_FLAGS_UNKNOWN) (System.Reflection.RuntimeAssembly+ASSEMBLY_FLAGS)

That wasn't very helpful. The object is just a thin wrapper around the native object pointed to by m_assembly. So what is this object? This is what it looks like:

0:004> dd 0eaa4ba8 L30
0eaa4ba8 692addec 014ad1b8 0f7307d8 00000000
0eaa4bb8 0fd49ca4 0000000c 0987de05 00000000
0eaa4bc8 00000007 00000001 00000000 00000000
0eaa4bd8 00000000 00000000 6d079b44 0987de01
0eaa4be8 0f842758 00000000 005508d0 00000002
0eaa4bf8 00000000 00000000 00000000 00000001
0eaa4c08 00000000 00000005 0eaa4ba8 f149a627
0eaa4c18 191e1826 33a15c96 1fa78d20 00000000
0eaa4c28 00000000 00000000 00000101 00000000
0eaa4c38 36664efa 8c001f00 692addec …

A good trick is to check whether the first value is a vtable pointer:

0:004> ln 692addec
(692addec) clr!DomainAssembly::`vftable’ …

So apparently the object is a DomainAssembly object, whatever that is (you can find some of these classes in the Rotor source, but the structure of them are vastly different). Using this trick combined with the !mln sosex command we find:

692addec: clr!DomainAssembly::`vftable’
014ad1b8: -> to clr!AppDomain
0f7307d8: -> to clr!PEAssembly
0fd49ca4: -> to clr!EditAndContinueModule
0987de05: Heap Object: 09877108[System.Object[]]
offset 00006cfd
0987de04 -> RuntimeModule (05f78868) : m_runtimeAssemblt = 05f7868c
6d079b44: not a pointer
0987de01: Heap Object: 09877108[System.Object[]]
offset 00006cf9
0987de01 -> RuntimeAssembly (05f7868c)
0f842758: -> to clr!AssemblySecurityDescriptor
0eaa4ba8: -> this
f149a627: not a pointer
191e1826: not a pointer
33a15c96: not a pointer
1fa78d20: not a pointer
36664efa: not a pointer
8c001f00: not a pointer

692addec: start of next clr!DomainAssembly object…

The PEAssembly object:

0:004> dd 0f7307d8 L100
0f7307d8 692e2a64 0f5cb928 0f5cc828 00000000
692e2a64: vtable (clr!PEAssembly::`vftable’)
0f5cb928: ???
0f5cc828: ??
0f7307e8 00000001 00000001 0149fc38 00000000
0149fc38: -> to clr!MDInternalRO
0f7307f8 00000000 00000000 00000000 00000000
0f730808 0f5b1340 00000006 00000000 00002002
0f5b1340: ??
0f730818 00000000 00000000 00000000 00000000
0f730828 ffffffff ffffffff 00000000 00000000
0f730838 00000000 020007d0 c0000000 00000000
020007d0: not a pointer
0f730848 00000000 00000000 0ea0b930 0f722e80
0ea0b930: -> to clr!CAssemblyName
0f722e80: -> to clr!CAssembly
0f730858 00000000 00000001 00000000 00000000
0f730868 00000000 00000002 00000000 00000001
0f730878 35f26672 88001820 692e2a64 00000000
35f26672: not a pointer
88001820: not a pointer
692e2a64: vtable pointer for next PEAssembly

CAssemblyName? That sounds promising, right?

0:004> dd 0ea0b930
0ea0b930 692b3210 692de934 454d414e 00000005
0ea0b940 504f5250 00000000 00000000 00000000
0ea0b950 00000000 00000000 00000000 0f722a58


0:004> du 0f722a58
0f722a58 “AxInterop.AcroPDFLib”

There was the name. And we had a pointer to the AppDomain earlier, so that should be sufficient to uniquely identify the assembly. I haven't figured out where the actual assembly or module objects as used by !DumpAssembly and !DumpModule resides, but they are probably somewhere in there (the modules are CModule objects, the assembly objects starts with a null pointer, so I couldn't tell the C++ class from that).

Leave a Reply

Your email address will not be published. Required fields are marked *


This site uses Akismet to reduce spam. Learn how your comment data is processed.