Is it possible to dump arbitrary (including dynamically created) assembly into a file from windbg?
Asked Answered
D

3

7

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.

Duwe answered 12/11, 2013 at 18:29 Comment(0)
M
6

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.

Mccarter answered 16/11, 2013 at 2:48 Comment(1)
My question is to how dump a dynamic assembly to file. I do not see how this answers it.Duwe
D
2

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.

Denishadenison answered 26/12, 2013 at 21:29 Comment(1)
I have this same problem again. Please, see my EDIT 1. Any help is appreciated.Duwe
H
1

You need to use the !SaveModule command available in SOS. It takes two arguments: 1) the start address and 2) export path. You may find the start address by examining the module details with lmv.

For example, if you want to export clr.dll, first type lmv m clr to verify the start address. Lets say that it is 000007fe`f9b40000. Lets save it to c:\clr.dll. The command now becomes as follows:

!sos.SaveModule 000007fe`f9b40000 c:\clr.dll

Now check the export path for the module. This will work from a live debugging session as well as full (/ma) dump.

I am not sure about dynamic assemblies. If they appear in the lm list, then it should not be a problem. If not, then you will need to locate where it is loaded into memory and use that as the start address.

Hildick answered 13/11, 2013 at 3:10 Comment(1)
!lmv does not list dynamic .NET assemblies, which is the essence of this question.Duwe

© 2022 - 2024 — McMap. All rights reserved.