DMP File Structure

| 7 Comments
Microsoft's debuggers and the NT kernel's crashdump facility generate memory images in a proprietary yet useful format. This article provides you with some internals about the file format and explains how to find a given physical address in the memory image.
Finding a given physical address in a memory dump is easy - as long as you're dealing with plain "dd style" memory dumps. Microsoft has chosen to generate memory images in a proprietary format along with some status informations aiding in debugging. One should remember that the format has been invented for debugging and not for forensic purposes. The file starts with a header of 4096 bytes, which is the size of a memory page. I'm documenting parts of this header here. Inquiring minds can get the full information from the kernel's program database (PDB) file. However I observed that not every of the three dump formats will utilize all available fields.
OffsetTypeFieldRemarks
0x000charSignature[4]'PAGE'
0x004charValidDump[4]'DUMP'
0x008uint32MajorVersion
0x00cuint32MinorVersionwindows build no.
0x010uint32DirectoryTableBase
0x014uint32PfnDataBase
0x018uint32PsLoadedModuleList
0x01cuint32PsActiveProcessHead
0x020uint32MachineImageType
0x024uint32NumberProcessors
...
0x05ccharPaeEnabled
...
0x064charPhysicalMemoryBlockBuffer[700]
...
0xf88uint32DumpType1 = full dump, 2 = kernel dump (smaller)
...
0xfa0int64RequiredDumpSpaceshould equal dump file size
...
0xfb8int64SystemUpTimemeasured in units of 100 ns
0xfc0int64SystemTimeFILETIME
...
And here is what a dump file header looks like in a hex editor. You'll notice that several unused regions are filled with "PAGEDUMP". Dump File Header I'll focus on the PhysicalMemoryBlockBuffer, because I expect this sub-structure to provide the needed mapping between physical addresses and file offsets. If you run dumpchk from the Microsoft Debugging Tools on a memory dump, among a plenty of other things you'll get something like:
Physical Memory Description:
Number of runs: 4
          FileOffset  Start Address  Length
           00001000     00002000     0001e000
           0001f000     00030000     0006f000
           0008e000     00100000     00eff000
           00f8d000     01000000     2e740000
Last Page: 2f6cc000     2f73f000
That looks exactly like the information needed so badly! But how can one extract it from the dump file? In the above hex view I've marked the relevant portion of the dump file header in blue. I also drafted a small template for the 010 Editor to clear up the view. Here are the structures which were applied to the PhysicalMemoryBlockBuffer:
typedef struct {
	uint32 BasePage;
	uint32 PageCount;
} _PHYSICAL_MEMORY_RUN32;
 
typedef struct {
	uint32 NumberOfRuns;
	uint32 NumberOfPages;
	_PHYSICAL_MEMORY_RUN32 Run[NumberOfRuns];
} _PHYSICAL_MEMORY_DESCRIPTOR32;
And here is the result: The parsed PhysicalMemoryBlockBuffer. All lengths and offsets are given in pages, that is in units of 4096 bytes (0x1000 in hex). As you can see, the dump provides no continuous image of the physical memory. There are even some holes, meaning the dump does not contain the whole physical memory. Take the first run for example. It starts at page 2 for 0x1e pages. So the last page contained in the dump is 0x1f. The next run starts at page 0x30. So pages from 0x20 to 0x2f are missing. Let's check that in the debugger (please note the exclamation mark in the following statement which denotes a physical address instead of a virtual):
kd> !db 20000
Physical memory read at 20000 failed
If you know the caching attributes used for the memory,
try specifying [c], [uc] or [wc], as in !dd [c] .
WARNING: Incorrect use of these flags will cause unpredictable
processor corruption.  This may immediately (or at any time in
the future until reboot) result in a system hang, incorrect data
being displayed or other strange crashes and corruption.
0x20 pages offset in run 2 + 0x6f pages in run 1 + 0x1e pages in run 0 + 0x01 page for the dump file header = 0xae pages = 0xae * 0x1000 bytes = 0xae000 bytes offset into the dump file. Finally add the string's offset in its page: 0xae000 + 0x56 = 0xae056. That's the final offset. The sought-after string in the hex editor. For comparison here's the same memory region viewed in the debugger: The same memory region viewed in the debugger. Hopefully this description will enable authors of memory analysis tools to support the DMP file format. 10/09/2006: The Microsoft Kernel Memory Space Analyzer comes in handy to analyze the dump. 06/25/2007: Corrected a typo in offset of RequiredDumpSpace. Thanks to "raj_r" for reporting! 02/28/2008: Please see also the posting about 64bit crash dumps.

7 Comments

This is good information. I am trying to write a dump file viewer in Visual Basic and am having issues. The viewer is only getting MDMPҤ(Q . You said that the dump file is in a proprietary format. Does this make it impossible for me?

Neil,

No, it's not impossible. Essentially a crashdump file is a set of 1:1 copies of party of the physical memory. There might be some holes in it, though. All you need is in the PhysicalMemoryBlockBuffer array.

Just to be sure: Are we both talking about Windows memory forensics? MDMP sounds like Counterstrike to me.

Cheers, Andreas

I would be interested in testing dumps with the Kernel Memory Space Analyzer from Microsoft but I was wondering if a tool exist to convert file.dd->file.dmp?

Nicolas,

crash dumps (DMP fiels) and raw images (as generated by dd) both contain the main memory (to different extends, but that's not the issue here). The DMP file additionally contains the CPU's state.

So in order to turn a raw dump into a crash dump you'd have to provide the CPU state on your own. This might not be a trivila task but I know some people are working on this.

For starters I recommend to read "Windows Internals", chapter 6 (especially the section about context switching).

Cheers,
Andreas

i think there is typo in there

0x7a0 int64 RequiredDumpSpace should equal dump file size

it should be 0xfa0 i think

anyway this size doesnt match the size of memory.dmp created after
successfully booting from a crash and the raw pagefile.sys

if that is what this size indicated

i was interested in truncating a raw copied pagefile to memory.dmp
manually and was looking
for the size of dmp some where in the headers

i think ill have to add up
the sizes indicated in dumpchk and see if this matches the file size
that was created by savedump.exe


thanks and regards

raj_r

Raj,

thanks for reporting the typo.

Another way to calculate the dump file size is to get NumberOfPages (at file ofs 0x68) from the _PHYSICAL_MEMORY_DESCRIPTOR32 structure; then add 1 for the dump file header and multiply with the page size (4096 bytes). This will give you the dump file size in bytes.

Cheers,
Andreas

FYI, the "MDMP" dumps are mini-dumps created by visual studio and contain a different file format than crash dumps created by the kernel.

Archives

Imprint

This blog is a project of:
Andreas Schuster
Im Äuelchen 45
D-53177 Bonn
impressum@forensikblog.de

Copyright © 2005-2012 by
Andreas Schuster
All rights reserved.
Powered by Movable Type 5.12