I have a dump of a .NET application which creates and loads too many dynamic assemblies. I would like to inspect what is inside one of these assemblies.
For that, I want to dump such an assembly into a file and open it in Reflector.
The problem - I have no idea how to do it.
So, my question is this - given a full memory dump, how do I dump an arbitrary assembly to a file, in such a way that the new file is a valid .NET module or assembly itself?
A simpler variation - how do I do it from a live debugging session?
I am using WinDBG with SOS and SOSEX.
EDIT 1
So, 3 years later I need it again. Here is the relevant output from !DumpDomain
:
Assembly: 007f89a0 (Dynamic) []
ClassLoader: 00877998
SecurityDescriptor: 00879410
Module Name
054d0010 Dynamic Module
Starting with this information, how can I find the start and end of this assembly? Then I could use the .writemem
command.
Test code - http://www.dotnetspider.com/resources/22226-Creating-Dynamic-Assembly-A-Step-Ahead-Series.aspx
0:000> !DumpDomain
Assembly: 00680f48 (Dynamic) []
ClassLoader: 00681010
SecurityDescriptor: 00680eb0
Module Name
0058386c Dynamic Module
0:000> !DumpModule -mt 0058386c
Name: Unknown Module
Attributes: Reflection SupportsUpdateableMethods
Assembly: 00680f48
LoaderHeap: 00000000
TypeDefToMethodTableMap: 00581b54
TypeRefToMethodTableMap: 00581b68
MethodDefToDescMap: 00581b7c
FieldDefToDescMap: 00581ba4
MemberRefToDescMap: 00000000
FileReferencesMap: 00581bf4
AssemblyReferencesMap: 00581c08
Types defined in this module
MT TypeDef Name
------------------------------------------------------------------------------
00583c98 0x02000002 <Unloaded Type>
Types referenced in this module
MT TypeRef Name
------------------------------------------------------------------------------
726826a0 0x02000001 System.Object
72647e4c 0x02000002 System.Console
0:000> !DumpMT -md 00583c98
EEClass: 0060121c
Module: 0058386c
Name: <Unloaded Type>
mdToken: 02000002
File: Unknown Module
BaseSize: 0xc
ComponentSize: 0x0
Slots in VTable: 6
Number of IFaces in IFaceMap: 0
--------------------------------------
MethodDesc Table
Entry MethodDe JIT Name
7258a630 7227801c PreJIT System.Object.ToString()
7257f750 72278024 PreJIT System.Object.Equals(System.Object)
7257f380 72278044 PreJIT System.Object.GetHashCode()
7257f040 72278058 PreJIT System.Object.Finalize()
005f03d0 00583c90 JIT dynamicAssemblyClass..ctor()
005f03e8 00583c84 JIT dynamicAssemblyClass.HelloWorld()
0:000> !DumpIL 00583c84
FindIL failed
0:000> !U 005f03e8
Normal JIT generated code
dynamicAssemblyClass.HelloWorld()
Begin 005f03e8, size 1a
>>> 005f03e8 55 push ebp
005f03e9 8bec mov ebp,esp
005f03eb e8b856f871 call mscorlib_ni!System.Console.get_Out() (72575aa8)
005f03f0 8bc8 mov ecx,eax
005f03f2 8b15a0210703 mov edx,dword ptr ds:[30721A0h] ("Hello! This is a dynamic assembly.")
005f03f8 8b01 mov eax,dword ptr [ecx]
005f03fa 8b403c mov eax,dword ptr [eax+3Ch]
005f03fd ff5010 call dword ptr [eax+10h]
005f0400 5d pop ebp
005f0401 c3 ret
Not as nice as reflector, but you can see the types and methods.
You can scan the entire virtual memory for DLLs using .imgscan
. I did this while a dynamic assembly was in memory, but .imgscan
did not find it. It does not have the typical MZ
header, so the assembly created by reflection seems not to be a DLL file which could be saved to disk. Otherwise you could have use .writemem
to save it to disk.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With