http://www.latenighthacking.com/projects/howtoDebug.html
These are my debugging notes.
The magic symbol path is SRV*c:/websymbols*http://msdl.microsoft.com/download/symbols
Given a crashed process:
0:001> kb ChildEBP RetAddr Args to Child 44fedb5c 77f7f49f 77e74bd8 00000002 44fedba8 SharedUserData+0x304 44fedb60 77e74bd8 00000002 44fedba8 00000001 ntdll!ZwWaitForMultipleObjects+0xc 44fedbfc 77e74c70 00000002 44fedcd0 00000000 kernel32!WaitForMultipleObjectsEx+0x12c 44fedc14 69455a73 00000002 44fedcd0 00000000 kernel32!WaitForMultipleObjects+0x17 44fee398 69456ba3 44fef96c ffffffff 00008310 faultrep!StartDWException+0x575 44fef400 77eb9d66 44fef96c ffffffff c0000005 faultrep!ReportFault+0x488 44fef924 77c313c8 44fef96c 77c140c8 00000000 kernel32!UnhandledExceptionFilter+0x2e2 44fef940 77c37fde 00000000 44fef96c 77c33efb MSVCRT!_XcptFilter+0x15f 44feffb4 77e802ed 00862e60 0006f96c 77f519f3 MSVCRT!_endthreadex+0xc6 44feffec 00000000 77c37f49 00862e60 00000000 kernel32!BaseThreadStart+0x37
The first param to kernel32!UnhandledExceptionFilter (44fef96c
) is a pointer to an EXCEPTION_POINTERS struct.
0:001> dd 44fef96c 44fef96c 44fefa5c 44fefa78 44fef998 77f833a0 44fef97c 44fefa5c 44feffa4 44fefa78 44fefa34 44fef98c 44feffa4 77f833b4 44feffa4 44fefa44
The second pointer in the struct is the pointer to the CONTEXT_RECORD. Use .cxr addr
to reset the debuggers context to the thread as it was when it faulted. (Use ~s
to return to the thread's current context.)
0:001> .cxr 44fefa78 eax=00000000 ebx=00000001 ecx=00000841 edx=44b9c1d8 esi=493dfad8 edi=44fefde4 eip=6d476a25 esp=44fefd44 ebp=44fefd74 iopl=0 nv up ei pl zr na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246 jvm!JVM_FindSignal+1ef27: 6d476a25 837cc21400 cmp dword ptr [edx+eax*8+0x14],0x0 ds:0023:44b9c1ec=????????
The first pointer in the struct is the pointer to the EXCEPTION_RECORD. Use .exr addr
to dump the struct.
0:001> .exr 44fefa5c ExceptionAddress: 6d476a25 (jvm!JVM_FindSignal+0x0001ef27) ExceptionCode: c0000005 ExceptionFlags: 00000000 NumberParameters: 2 Parameter[0]: 00000000 Parameter[1]: 44b9c1ec Attempt to read from address 44b9c1ec
More useful command examples:
x kernel32!*Ctrl* | search for symbol |
~*kb | dump stack of all threads |
bp 77e9658d "r eax=0;g" | create breakpoint that executes command when hit |
bl | list breakpoints |
u kernel32!CreateEventA | disassemble |
Push moves the stack pointer backward in memory (ie, esp -= 4
) and then writes the given value to location pointed at by the stack pointer.
Stack frame layout (no frame pointer optimization)
this function's ebp points here ------------/ ebp-0x8 ebp-0x4 ebp+0x0 ebp+0x4 ebp+0x8 ebp+0xC caller's return local1 local0 ebp addr param0 param1 ... 00000000 00000000 00000000 00000000 00000000 00000000 ...
All arguments are widened to 32 bits when they are passed. Return values are also widened to 32 bits and returned in the eax
register, except for 8-byte structures, which are returned in the edx:eax
register pair. Larger structures are returned in the eax
register as pointers to hidden return structures. Parameters are pushed onto the stack from right to left.
The compiler generates prolog and epilog code to save and restore the esi
, edi
, ebx
, and ebp
registers, if they are used in the function.
name | argument passing | stack cleanup | name decoration | int func(int a, double b) |
cdecl | on stack, reverse order / right to left (ebp+0x8 is param0, ebp+0xC is param1 ...) | caller | prefix: "_" | _func |
stdcall | on stack, reverse order / right to left (ebp+0x8 is param0, ebp+0xC is param1 ...) | callee | prefix: "_"; suffix: "@" followed by the number of bytes (in decimal) in the argument list. | _func@12 |
fastcall | The first two DWORD or smaller arguments are passed in ecx and edx registers; all other arguments are passed on stack, reverse order / right to left (ebp+0x8 is param2, ebp+0xC is param3 ...) | callee | prefix: "@"; suffix: "@" followed by the number of bytes (in decimal) in the argument list. | @func@12 |
thiscall | this in ecx ; all other arbuments are passed on stack, reverse order / right to left (ebp+0x8 is param0, ebp+0xC is param1 ...); | callee | (C++ mangling) |
__asm { int 3 } | hardcoded debug breakpoint |
#define TEB_OFFSET 4 void ** ppvStackBase; __asm { mov eax, fs:[TEB_OFFSET] } __asm { mov ppvStackBase, eax } | stack base from TEB |
void ** ppvFrame; _asm { mov ppvFrame, ebp } | frame pointer |
<script type="text/javascript"> function getMailto() { return "mailto:Louis K. Thomas ".replace(/foo/, "louisth").replace(/bar/,"hotmail"); } </script> Louis K. Thomas <louiNØSP@Msth@hotmÑOSP@Mail.coNÕSP@Mm> Fight Spam! | Auth | 2006-03-15 (44 days ago) |