Raw Stack Dump of WOW64 Process
Sometimes we need to dump raw stack data of the given thread to get correct function arguments or to see execution residue. If the process is WOW64 (32-bit running on x64 Windows) and its memory dump was saved using a 64-bit debugger or a process dumper like userdump.exe we have 2 stacks in it:
64-bit stack:
0:007> k
Child-SP RetAddr Call Site
00000000`030fee38 00000000`75fcab46 wow64cpu!WaitForMultipleObjects32+0x3a
00000000`030feee0 00000000`75fca14c wow64!RunCpuSimulation+0xa
00000000`030fef10 00000000`77d373db wow64!Wow64LdrpInitialize+0x4b4
00000000`030ff470 00000000`77cf85ce ntdll! ?? ::FNODOBFM::`string'+0x20061
00000000`030ff520 00000000`00000000 ntdll!LdrInitializeThunk+0xe
0:007> r
rax=0000000000000000 rbx=0000000000000002 rcx=0000000000000400
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
rip=0000000075ec374f rsp=00000000030fee38 rbp=0000000005baef38
r8=000000000000002b r9=0000000077e9057a r10=0000000000000000
r11=00000000030fee30 r12=000000007efad000 r13=00000000030ffd20
r14=00000000030fee70 r15=0000000075ec3380
iopl=0 nv up ei pl nz ac pe nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000212
wow64cpu!WaitForMultipleObjects32+0×3a:
00000000`75ec374f 418bbda0000000 mov edi,dword ptr [r13+0A0h] ds:00000000`030ffdc0=00000000
0:007> !teb
Wow64 TEB32 at 000000007efaf000
error InitTypeRead( wow64!_TEB32 )...
Wow64 TEB at 000000007efad000
ExceptionList: 000000007efaf000
StackBase: 00000000030ffd20
StackLimit: 00000000030f8000
SubSystemTib: 0000000000000000
FiberData: 0000000000001e00
ArbitraryUserPointer: 0000000000000000
Self: 000000007efad000
EnvironmentPointer: 0000000000000000
ClientId: 0000000000000b44 . 0000000000000b1c
RpcHandle: 0000000000000000
Tls Storage: 0000000000000000
PEB Address: 000000007efdf000
LastErrorValue: 0
LastStatusValue: c0000034
Count Owned Locks: 0
HardErrorMode: 0
32-bit stack:
0:007> .effmach x86
Effective machine: x86 compatible (x86)
0:007:x86> k
ChildEBP RetAddr
05baee9c 7756e91a ntdll_77e70000!NtWaitForMultipleObjects+0x15
05baef38 775649d9 kernel32!WaitForMultipleObjectsEx+0x11d
05baef54 7761573d kernel32!WaitForMultipleObjects+0x18
05baefc0 77615969 kernel32!WerpReportFaultInternal+0x16d
05baefd4 775ec66f kernel32!WerpReportFault+0x70
05baf060 77eed03e kernel32!UnhandledExceptionFilter+0x1b5
05baf068 77ebf2d0 ntdll_77e70000!__RtlUserThreadStart+0x6f
05baf07c 77f229b3 ntdll_77e70000!_EH4_CallFilterFunc+0x12
05baf0a4 77e93099 ntdll_77e70000!_except_handler4+0x8e
05baf0c8 77e9306b ntdll_77e70000!ExecuteHandler2+0x26
05baf178 77e92eff ntdll_77e70000!ExecuteHandler+0x24
05baf198 7757f328 ntdll_77e70000!KiUserExceptionDispatcher+0xf
05baf4fc 7155dead kernel32!RaiseException+0x58
WARNING: Stack unwind information not available. Following frames may be wrong.
05baf534 7155a59d ComponentA!DllUnregisterServer+0x1adbe0
[...]
0:007:x86> r
eax=00000000 ebx=00000002 ecx=00000003 edx=00000000 esi=00000000 edi=00000000
eip=77e90bc5 esp=05baeea0 ebp=05baef38 iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
ntdll_77e70000!NtWaitForMultipleObjects+0×15:
77e90bc5 c21400 ret 14h
Unfortunately there is an error when try to get its TEB (TEB32) using !teb command so we can either use dp command to discover stack base and limit:
0:007:x86> !teb
Wow64 TEB32 at 000000007efaf000
error InitTypeRead( wow64!_TEB32 )…
0:007:x86> dp 000000007efaf000 l3
7efaf000 05baef28 05bb0000 05b95000
or use WOW64 extension for this purpose:
0:007:x86> !wow64exts.info
PEB32: 0x7efde000
PEB64: 0x7efdf000
Wow64 information for current thread:
TEB32: 0×7efaf000
TEB64: 0×7efad000
32 bit, StackBase : 0×5bb0000
StackLimit : 0×5b95000
Deallocation: 0×5ab0000
64 bit, StackBase : 0x30ffd20
StackLimit : 0x30f8000
Deallocation: 0x30c0000
Wow64 TLS slots:
WOW64_TLS_STACKPTR64: 0x0000000000000000
WOW64_TLS_CPURESERVED: 0x00000000030ffd20
WOW64_TLS_INCPUSIMULATION: 0x0000000000000000
WOW64_TLS_LOCALTHREADHEAP: 0x0000000000000000
WOW64_TLS_EXCEPTIONADDR: 0x000000007757f328
WOW64_TLS_USERCALLBACKDATA: 0x0000000000000000
WOW64_TLS_EXTENDED_FLOAT: 0x0000000000000000
WOW64_TLS_APCLIST: 0x0000000000000000
WOW64_TLS_FILESYSREDIR: 0x0000000000000000
WOW64_TLS_LASTWOWCALL: 0x0000000000000000
WOW64_TLS_WOW64INFO: 0x000000007efde238
In case these methods don’t work and we want to quickly inspect raw memory around the current ESP value we can still use dps esp-xxx esp+xxx command, where xxx is some offset:
0:007:x86> dps esp-10 esp+10
05baee90 00000000
05baee94 00000000
05baee98 00000000
05baee9c 77e90bc5 ntdll_77e70000!NtWaitForMultipleObjects+0x15
05baeea0 7756e91a kernel32!WaitForMultipleObjectsEx+0x11d
05baeea4 00000002
05baeea8 05baeeec
05baeeac 00000001
05baeeb0 00000000
Remember that dp and dps are better to use here than dd, dds or dq, dqs: they automatically take into account the pointer size, 32-bit in x86 mode and 64-bit in native mode:
0:007:x86> .effmach amd64
Effective machine: x64 (AMD64)
0:007> dps esp-10 esp+10
00000000`030fee28 00000000`006d0008
00000000`030fee30 00000000`030ffd20
00000000`030fee38 00000000`7efad000
00000000`030fee40 00000000`00003da8
00000000`030fee48 00000000`75ec3688 wow64cpu!ServiceNoTurbo+0x28
- Dmitry Vostokov @ DumpAnalysis.org -
July 8th, 2009 at 8:55 pm
[…] .exptr command. However we can still use a technique described in Hidden Exception pattern using 32-bit raw stack to set the context and display the exception […]
January 8th, 2010 at 4:09 pm
[…] trick of sxd or sxi commands didn’t help either (probably because of single-step mode). The 32-bit raw stack had this fragment of exception processing […]