Archive for October 25th, 2006

userdump.exe on x64

Wednesday, October 25th, 2006

If you install the latest Microsoft user mode process dumper on x64 Windows you would see both x86 and x64 folders. 

Advice: do not dump 32-bit applications and services (shown as *32 in Task Manager) using userdump.exe from x64 folder: use userdump.exe from x86 folder. 32-bit application runs in WOW64 emulation layer on x64 Windows and that emulation layer is itself native 64-bit process so x64 userdump.exe saves that emulation layer not your original 32-bit application. If you open that dump in WinDbg you would see WOW64 thread stacks not thread stacks from your original 32-bit application. 

In summary, on x64 Windows

to save a dump of 64-bit application use:

  • x64\userdump.exe
  • \Windows\System32\ntsd.exe
  • 64-bit version of WinDbg.exe

to save a dump of 32-bit application use:

  • x86\userdump.exe
  • \Windows\SysWOW64\ntsd.exe
  • 32-bit WinDbg.exe  

- Dmitry Vostokov -

Crash Dumps for Dummies (Part 3)

Wednesday, October 25th, 2006

This part follows Dumps for Dummies (Part 2) and here I’ll try to explain crashes, dumps and postmortem debuggers. 

Sometimes a computer (CPU, Central Processing Unit) cannot perform its job because the instruction it gets to do some calculations, read or write data is wrong. Imagine a situation when you get an address to deliver a message to and you find that it doesn’t exist…  The following idealized picture shows this situation (if memory locations/addresses are indexed from 0 then -1 is obviously wrong address):

When referencing invalid address CPU executes special sequence of actions (called trap) that ultimately leads to saving memory so you could later examine its contents and find out which instruction was invalid. If crash happens inside Windows operating system then you see blue screen and then a kernel memory or full computer physical memory is saved in a file (called either kernel or complete memory dump respectively). If you have a crash in a running application or service then its memory contents are saved in a file (called user dump). The latter file is also called a postmortem dump and we call a program which saves it a postmortem debugger. There can be several such programs and the one which is specified in the registry to execute whenever a crash happens in a running application or service is called a default postmortem debugger. The following picture illustrates this (here spooler service, spoolsv.exe, crashed by faulty printer driver):

By default it is Dr. Watson (drwtsn32.exe) but sometimes it doesn’t work in terminal services environment and has limitations so we always recommend setting NTSD (ntsd.exe) as a default postmortem debugger:

How to Set NTSD as a Default Windows Postmortem Debugger

I prefer to call both user and kernel/complete memory dumps postmortem (not only user dumps) because they are saved after application, service or system is dead already (crash or fatal error already happened). This distinguishes them from live memory dumps saved manually whenever we want them. This brings us to dump classification that I show you in forthcoming parts. 

- Dmitry Vostokov @ DumpAnalysis.org -

The Smallest Program

Wednesday, October 25th, 2006

Can the smallest program that crashes be smaller than the smallest program that doesn’t? Depends on a platform and a compiler/linker set. I’ve chosen x64 and MASM64 for my experiments. The smallest working program I came up first was this:

; ml64 /Zi TheSmallestProgram64.asm /link
;   /entry:main /SUBSYSTEM:CONSOLE

_text SEGMENT
main PROC
ret
main ENDP
_text ENDS

END

It compiles and links to an executable with only one byte instruction in its main function:

0:000> u main
TheSmallestProgram64!main:
00000000`00401010 c3              ret
00000000`00401011 cc              int     3
00000000`00401012 cc              int     3
00000000`00401013 cc              int     3
00000000`00401014 cc              int     3
00000000`00401015 cc              int     3
00000000`00401016 cc              int     3
00000000`00401017 cc              int     3

Then I thought about removing ret instruction and supposed that if we compile and link and try to execute the program with 0 bytes we get straight to int 3 instruction and in my case (I have NTSD set as a default postmortem debugger) a dump will be saved. So I did that but I found that unfortunately compiler inserts ret instruction if the procedure body is empty. So I cheated them by putting nop instruction (which is also one byte) and got my dump!

; ml64 /Zi TheSmallestProgramWithBug64.asm /link
;    /entry:main /SUBSYSTEM:CONSOLE

_text SEGMENT
main PROC
nop
main ENDP
_text ENDS

END

Loading Dump File [new_2006-10-25_12-40-06-500_076C.dmp]
…

0:000> kL
TheSmallestProgramWithBug64!main+0×1
kernel32!BaseProcessStart+0×29

0:000> u main
TheSmallestProgramWithBug64!main:
00000000`00401010 90              nop
00000000`00401011 cc              int     3
00000000`00401012 cc              int     3
00000000`00401013 cc              int     3
00000000`00401014 cc              int     3
00000000`00401015 cc              int     3
00000000`00401016 cc              int     3
00000000`00401017 cc              int     3

So one answer to my question: The smallest working program and the smallest crashing program have the same size unless we use some binary editors :-)

Then I tried MS Visual C++ (this time 32-bit project) and came up with the following C or C++ program without any prolog and epilog code:

__declspec(naked) void Main ()
{
}

I changed entry point from standard main function to my own capitalized Main function and compiler/link options:

Compiler:

/Od /GL /D "WIN32" /D "NDEBUG" /D "_CONSOLE"
/D "_UNICODE" /D "UNICODE" /D "_AFXDLL"
/FD /MD /GS- /Fo"Release\"
/Fd"Releasevc80.pdb" /W3 /nologo /c
/Wp64 /Zi /TP /errorReport:prompt

Linker:

/OUT:"SmallestProgram.exe" /INCREMENTAL:NO
/NOLOGO /MANIFEST:NO /NODEFAULTLIB /DEBUG
/PDB:"SmallestProgram.pdb" /SUBSYSTEM:CONSOLE
/OPT:REF /OPT:ICF /LTCG /ENTRY:"Main"
/ERRORREPORT:PROMPT

The program crashes immediately because the body is empty:

Loading Dump File [new_2006-10-25_15-18-03-109_13B0.dmp]

0:000> u Main
SmallestProgram!Main:
00401000 cc              int     3
00401001 0000            add     byte ptr [eax],al
00401003 0000            add     byte ptr [eax],al
00401005 0000            add     byte ptr [eax],al
00401007 0000            add     byte ptr [eax],al
00401009 0000            add     byte ptr [eax],al
0040100b 0000            add     byte ptr [eax],al
0040100d 0000            add     byte ptr [eax],al

0:000> kL
ChildEBP RetAddr
002cfff0 00000000 SmallestProgram!Main

0:000> dds esp
002cffc4  7d4e992a kernel32!BaseProcessStart+0x28
002cffc8  00000000
002cffcc  00000000
002cffd0  7efdf000
002cffd4  80000003
002cffd8  002cffc8
002cffdc  002cfbbc
002cffe0  ffffffff
002cffe4  7d4d8998 kernel32!_except_handler3
002cffe8  7d4e9938 kernel32!`string'+0x28
002cffec  00000000
002cfff0  00000000
002cfff4  00000000
002cfff8  00401000 SmallestProgram!Main
002cfffc  00000000

So another answer to my question: The smallest crashing program can be less than the smallest working program and is actually 0 bytes :-)

- Dmitry Vostokov -