Raw Stack Dump of all threads (part 2)
Monday, December 24th, 2007In the previous part I used WinDbg scripting to get raw stack data from user process dump. However the script needs to be modified if the dump is complete memory dump. Here I use !for_each_thread WinDbg extension command to dump stack trace and user space raw stack data for all threads except system threads because they don’t have user space stack counterpart and their TEB address is NULL:
!for_each_thread ".thread /r /p @#Thread; .if (@$teb != 0) {!thread @#Thread; r? $t1 = ((ntdll!_NT_TIB *)@$teb)->StackLimit; r? $t2 = ((ntdll!_NT_TIB *)@$teb)->StackBase; !teb; dps @$t1 @$t2}"
We need to open a log file. It will be huge and we might want to dump raw stack contents for specific process only. In such case we can filter the output of the script using $proc pseudo-register, the address of EPROCESS:
!for_each_thread ".thread /r /p @#Thread; .if (@$teb != 0 & @$proc == <EPROCESS>) {!thread @#Thread; r? $t1 = ((ntdll!_NT_TIB *)@$teb)->StackLimit; r? $t2 = ((ntdll!_NT_TIB *)@$teb)->StackBase; !teb; dps @$t1 @$t2}"
For example:
1: kd>!process 0 0
...
...
...
PROCESS 8596f9c8 SessionId: 0 Cid: 0fac Peb: 7ffde000 ParentCid: 0f3c
DirBase: 3fba6520 ObjectTable: d6654e28 HandleCount: 389.
Image: explorer.exe
…
…
…
1: kd> !for_each_thread ".thread /r /p @#Thread; .if (@$teb != 0 & @$proc == 8596f9c8) {!thread @#Thread; r? $t1 = ((ntdll!_NT_TIB *)@$teb)->StackLimit; r? $t2 = ((ntdll!_NT_TIB *)@$teb)->StackBase; !teb; dps @$t1 @$t2}”
Implicit thread is now 8659b208
Implicit process is now 8659b478
Loading User Symbols
Implicit thread is now 86599db0
Implicit process is now 8659b478
Loading User Symbols
...
...
...
Implicit thread is now 85b32db0
Implicit process is now 8596f9c8
Loading User Symbols
THREAD 85b32db0 Cid 0fac.0fb0 Teb: 7ffdd000 Win32Thread: bc0a6be8 WAIT: (Unknown) UserMode Non-Alertable
859bda20 SynchronizationEvent
Not impersonating
DeviceMap d743e440
Owning Process 8596f9c8 Image: explorer.exe
Wait Start TickCount 376275 Ticks: 102 (0:00:00:01.593)
Context Switch Count 3509 LargeStack
UserTime 00:00:00.078
KernelTime 00:00:00.203
Win32 Start Address Explorer!ModuleEntry (0x010148a4)
Start Address kernel32!BaseProcessStartThunk (0x77e617f8)
Stack Init ba5fe000 Current ba5fdc50 Base ba5fe000 Limit ba5f9000 Call 0
Priority 10 BasePriority 8 PriorityDecrement 0
ChildEBP RetAddr Args to Child
ba5fdc68 80833465 85b32db0 85b32e58 00000000 nt!KiSwapContext+0x26
ba5fdc94 80829a62 00000000 bc0a6be8 00000000 nt!KiSwapThread+0x2e5
ba5fdcdc bf89abe3 859bda20 0000000d 00000001 nt!KeWaitForSingleObject+0x346
ba5fdd38 bf89da53 000024ff 00000000 00000001 win32k!xxxSleepThread+0x1be
ba5fdd4c bf89e411 000024ff 00000000 0007fef8 win32k!xxxRealWaitMessageEx+0x12
ba5fdd5c 8088978c 0007ff08 7c8285ec badb0d00 win32k!NtUserWaitMessage+0x14
ba5fdd5c 7c8285ec 0007ff08 7c8285ec badb0d00 nt!KiFastCallEntry+0xfc (TrapFrame @ ba5fdd64)
0007feec 7739bf53 7c92addc 77e619d1 000d9298 ntdll!KiFastSystemCallRet
0007ff08 7c8fadbd 00000000 0007ff5c 0100fff1 USER32!NtUserWaitMessage+0xc
0007ff14 0100fff1 000d9298 7ffde000 0007ffc0 SHELL32!SHDesktopMessageLoop+0x24
0007ff5c 0101490c 00000000 00000000 000207fa Explorer!ExplorerWinMain+0x2c4
0007ffc0 77e6f23b 00000000 00000000 7ffde000 Explorer!ModuleEntry+0x6d
0007fff0 00000000 010148a4 00000000 78746341 kernel32!BaseProcessStart+0x23
Last set context:
TEB at 7ffdd000
ExceptionList: 0007ffe0
StackBase: 00080000
StackLimit: 00072000
SubSystemTib: 00000000
FiberData: 00001e00
ArbitraryUserPointer: 00000000
Self: 7ffdd000
EnvironmentPointer: 00000000
ClientId: 00000fac . 00000fb0
RpcHandle: 00000000
Tls Storage: 00000000
PEB Address: 7ffde000
LastErrorValue: 6
LastStatusValue: c0000008
Count Owned Locks: 0
HardErrorMode: 0
00072000 ????????
00072004 ????????
00072008 ????????
0007200c ????????
00072010 ????????
00072014 ????????
00072018 ????????
0007201c ????????
...
...
...
00079ff8 ????????
00079ffc ????????
0007a000 00000000
0007a004 00000000
0007a008 00000000
0007a00c 00000000
0007a010 00000000
0007a014 00000000
0007a018 00000000
0007a01c 00000000
0007a020 00000000
0007a024 00000000
0007a028 00000000
0007a02c 00000000
...
...
...
0007ff04 0007ff14
0007ff08 0007ff14
0007ff0c 7c8fadbd SHELL32!SHDesktopMessageLoop+0x24
0007ff10 00000000
0007ff14 0007ff5c
0007ff18 0100fff1 Explorer!ExplorerWinMain+0x2c4
0007ff1c 000d9298
0007ff20 7ffde000
0007ff24 0007ffc0
0007ff28 00000000
0007ff2c 0007fd28
0007ff30 0007ff50
0007ff34 7ffde000
0007ff38 7c82758b ntdll!ZwQueryInformationProcess+0xc
0007ff3c 77e6c336 kernel32!GetErrorMode+0x18
0007ff40 ffffffff
0007ff44 0000000c
0007ff48 00000000
0007ff4c 00018fb8
0007ff50 000000ec
0007ff54 00000001
0007ff58 000d9298
0007ff5c 0007ffc0
0007ff60 0101490c Explorer!ModuleEntry+0x6d
0007ff64 00000000
0007ff68 00000000
0007ff6c 000207fa
0007ff70 00000001
0007ff74 00000000
0007ff78 00000000
0007ff7c 00000044
0007ff80 0002084c
0007ff84 0002082c
0007ff88 000207fc
0007ff8c 00000000
0007ff90 00000000
0007ff94 00000000
0007ff98 00000000
0007ff9c f60e87fc
0007ffa0 00000002
0007ffa4 021a006a
0007ffa8 00000001
0007ffac 00000001
0007ffb0 00000000
0007ffb4 00000000
0007ffb8 00000000
0007ffbc 00000000
0007ffc0 0007fff0
0007ffc4 77e6f23b kernel32!BaseProcessStart+0x23
0007ffc8 00000000
0007ffcc 00000000
0007ffd0 7ffde000
0007ffd4 00000000
0007ffd8 0007ffc8
0007ffdc b9a94ce4
0007ffe0 ffffffff
0007ffe4 77e61a60 kernel32!_except_handler3
0007ffe8 77e6f248 kernel32!`string'+0x88
0007ffec 00000000
0007fff0 00000000
0007fff4 00000000
0007fff8 010148a4 Explorer!ModuleEntry
0007fffc 00000000
00080000 78746341
...
...
...
Because complete memory dumps contain only physical memory contents some pages of raw stack data can be in page files and therefore unavailable.
- Dmitry Vostokov @ DumpAnalysis.org -