Skip to content

Loading application code from Memory Dump

Nikolay Mitikov edited this page Aug 16, 2018 · 4 revisions

A memory dump represents all memory taken by the process at a set of time.

Since user code (modules/assemblies) must be loaded into process to be executed, there should be a chance to find them in a snapshot.

Getting started

The entry point on travelling via memory snapshots is SOS Debugging Extension, and I would hope it has something might be useful for us :

SaveModule <Base address> <Filename>

The command writes an image, which is loaded in memory at the specified address, to the specified file.

All is left to find a mystic Base address - place where module is located in memory.

Skipping boring parts

To cut long story short for_each_module command is exactly what we need, thus resulting WinDbg script would look like:

!for_each_module .if ($spat ("${@#ImageName}","*.exe")) { !SaveModule ${@#Base} C:\Dumps\${@#ModuleName}.exe } .else { !SaveModule ${@#Base} C:\Dumps\${@#ModuleName}.dll }

The script would enumerate the modules loaded into the process, and will save them to c:\Dumps\ folder.

Life is not that easy

CLR is getting optimized heavily these days - the command might not know anything about recent changes and could produce an incomplete list of assemblies.

The issue can be tackled by requesting data via Microsoft.Diagnostics.Runtime native debugger interface - you'll get accurate pointers to loaded assembly.

The remaining part is to read stream & save it - cudos to ManagedDumpAssembliesFetcher.

Comments

  1. The command does not differentiate between native and managed assemblies, so will save all
  2. ASP.NET will dynamically compile code into modules, thereby dynamically generated assemblies would also be saved
Clone this wiki locally