

Dmitry Vostokov, 12th of March, 2010
http://www.dumpanalysis.org
What kinds of threads are in a typical Windows system? The usual answer is kernel and user space threads[4]. The former originate in the kernel space and the latter originate in the user space. User thread stack trace can span both spaces with separate stacks (we highlight kernel space stack trace addresses in red, user space stack trace addresses in blue and taxonomic features in bold green):
THREAD fffffa8003bf1bb0 Cid 0004.0008 Teb: 0000000000000000 Win32Thread: 0000000000000000
GATEWAIT
Not impersonating
DeviceMap fffff88000007310
Owning Process fffffa8003bf1040 Image: System
Attached Process N/A Image: N/A
Wait Start TickCount 18550 Ticks: 17 (0:00:00:00.265)
Context Switch Count 905
UserTime 00:00:00.000
KernelTime 00:00:01.076
Win32 Start Address nt!Phase1Initialization (0xfffff80001c5f060)
Stack Init fffffa60005afdb0 Current fffffa60005afa20
Base fffffa60005b0000 Limit fffffa60005aa000 Call 0
Priority 1 BasePriority 0 PriorityDecrement 0 IoPriority 2 PagePriority 5
Child-SP RetAddr Call Site
fffffa60`005afa60 fffff800`0187a6fa nt!KiSwapContext+0x7f
fffffa60`005afba0 fffff800`0189e43e nt!KiSwapThread+0x13a
fffffa60`005afc10 fffff800`018a9c70 nt!KeWaitForGate+0x14e
fffffa60`005afc80 fffff800`01c5f06e nt!MmZeroPageThread+0x160
fffffa60`005afd20 fffff800`01a82ec7 nt!Phase1Initialization+0xe
fffffa60`005afd50 fffff800`018b5616 nt!PspSystemThreadStartup+0x57
fffffa60`005afd80 00000000`00000000 nt!KiStartSystemThread+0x16
THREAD fffffa8003bb5060 Cid 01a4.0528 Teb: 000007fffffda000 Win32Thread: 0000000000000000
WAIT: (WrQueue) UserMode Non-Alertable
fffffa80052eba90 QueueObject
fffffa8003bb5118 NotificationTimer
Not impersonating
DeviceMap fffff880080d8f30
Owning Process fffffa80052d5370 Image: svchost.exe
Attached Process N/A Image: N/A
Wait Start TickCount 15394 Ticks: 3173 (0:00:00:49.499)
Context Switch Count 65
UserTime 00:00:00.000
KernelTime 00:00:00.000
Win32 Start Address RPCRT4!ThreadStartRoutine (0x000007fefeb07780)
Stack Init fffffa6004a53db0 Current fffffa6004a537e0
Base fffffa6004a54000 Limit fffffa6004a4e000 Call 0
Priority 10 BasePriority 8 PriorityDecrement 0 IoPriority 2 PagePriority 5
Child-SP RetAddr Call Site
fffffa60`04a53820 fffff800`0187a6fa nt!KiSwapContext+0x7f
fffffa60`04a53960 fffff800`0187dba4 nt!KiSwapThread+0x13a
fffffa60`04a539d0 fffff800`01ada157 nt!KeRemoveQueueEx+0x4b4
fffffa60`04a53a80 fffff800`01ab012d nt!IoRemoveIoCompletion+0x47
fffffa60`04a53b00 fffff800`01877ef3 nt!NtRemoveIoCompletion+0x13d
fffffa60`04a53bb0 00000000`77476daa nt!KiSystemServiceCopyEnd+0x13 (TrapFrame @ fffffa60`04a53c20)
00000000`01b9f838 00000000`7731f65c ntdll!NtRemoveIoCompletion+0xa
00000000`01b9f840 000007fe`feb25d0d kernel32!GetQueuedCompletionStatus+0x48
00000000`01b9f8a0 000007fe`feb25b93 RPCRT4!COMMON_ProcessCalls+0x7d
00000000`01b9f930 000007fe`feb07769 RPCRT4!LOADABLE_TRANSPORT::ProcessIOEvents+0x133
00000000`01b9f9e0 000007fe`feb07714 RPCRT4!ProcessIOEventsWrapper+0x9
00000000`01b9fa10 000007fe`feb077a4 RPCRT4!BaseCachedThreadRoutine+0x94
00000000`01b9fa50 00000000`7731be3d RPCRT4!ThreadStartRoutine+0x24
00000000`01b9fa80 00000000`77456a51 kernel32!BaseThreadInitThunk+0xd
00000000`01b9fab0 00000000`00000000 ntdll!RtlUserThreadStart+0x1d
Other classification partitions threads into native platform and virtualized (WOW64):
THREAD fffffa800515b060 Cid 0af0.0b34 Teb: 000000007efd8000 Win32Thread: 0000000000000000
WAIT: (UserRequest) UserMode Non-Alertable
fffffa80051007d0 NotificationEvent
fffffa800515b118 NotificationTimer
Not impersonating
DeviceMap fffff88008479c90
Owning Process fffffa8005145820 Image: reader_sl.exe
Attached Process N/A Image: N/A
Wait Start TickCount 18516 Ticks: 51 (0:00:00:00.795)
Context Switch Count 1883
UserTime 00:00:00.015
KernelTime 00:00:00.000
Win32 Start Address reader_sl (0x0000000000401390)
Stack Init fffffa6003da2db0 Current fffffa6003da2940
Base fffffa6003da3000 Limit fffffa6003d9d000 Call 0
Priority 8 BasePriority 7 PriorityDecrement 0 IoPriority 2 PagePriority 5
Child-SP RetAddr Call Site
fffffa60`03da2980 fffff800`0187a6fa nt!KiSwapContext+0x7f
fffffa60`03da2ac0 fffff800`0186f35b nt!KiSwapThread+0x13a
fffffa60`03da2b30 fffff800`01ad8628 nt!KeWaitForSingleObject+0x2cb
fffffa60`03da2bc0 fffff800`01877ef3 nt!NtWaitForSingleObject+0x98
fffffa60`03da2c20 00000000`75543d09 nt!KiSystemServiceCopyEnd+0x13 (TrapFrame @ fffffa60`03da2c20)
00000000`003bf118 00000000`75543b06 wow64cpu!CpupSyscallStub+0x9
00000000`003bf120 00000000`7555ab46 wow64cpu!Thunk0ArgReloadState+0x1a
00000000`003bf190 00000000`7555a14c wow64!RunCpuSimulation+0xa
00000000`003bf1c0 00000000`774a05a8 wow64!Wow64LdrpInitialize+0x4b4
00000000`003bf720 00000000`774568de ntdll! ?? ::FNODOBFM::`string'+0x20aa1
00000000`003bf7d0 00000000`00000000 ntdll!LdrInitializeThunk+0xe
We can also partition threads into non-GUI and GUI (having a message loop):
THREAD fffffa800511c4d0 Cid 09ec.0a84 Teb: 000007fffffa0000 Win32Thread: fffff900c2950a20
WAIT: (WrUserRequest) UserMode Non-Alertable
fffffa8004e27a50 SynchronizationEvent
Not impersonating
DeviceMap fffff88008479c90
Owning Process fffffa8004e22c10 Image: explorer.exe
Attached Process N/A Image: N/A
Wait Start TickCount 9695 Ticks: 8872 (0:00:02:18.404)
Context Switch Count 14 LargeStack
UserTime 00:00:00.000
KernelTime 00:00:00.000
Win32 Start Address SHLWAPI!WrapperThreadProc (0x000007fefeee3eac)
Stack Init fffffa600516ddb0 Current fffffa600516d720
Base fffffa600516e000 Limit fffffa6005167000 Call 0
Priority 10 BasePriority 8 PriorityDecrement 0 IoPriority 2 PagePriority 5
Child-SP RetAddr Call Site
fffffa60`0516d760 fffff800`0187a6fa nt!KiSwapContext+0x7f
fffffa60`0516d8a0 fffff800`0186f35b nt!KiSwapThread+0x13a
fffffa60`0516d910 fffff960`0014c503 nt!KeWaitForSingleObject+0x2cb
fffffa60`0516d9a0 fffff960`0014c59a win32k!xxxRealSleepThread+0x25f
fffffa60`0516da40 fffff960`0014bfea win32k!xxxSleepThread+0x56
fffffa60`0516da70 fffff960`0014c0e9 win32k!xxxRealInternalGetMessage+0x72e
fffffa60`0516db50 fffff960`0014d589 win32k!xxxInternalGetMessage+0x35
fffffa60`0516db90 fffff800`01877ef3 win32k!NtUserGetMessage+0x79
fffffa60`0516dc20 00000000`7724d58a nt!KiSystemServiceCopyEnd+0x13 (TrapFrame @ fffffa60`0516dc20)
00000000`042df7b8 00000000`7724d5be USER32!ZwUserGetMessage+0xa
00000000`042df7c0 00000000`ff556cf1 USER32!GetMessageW+0x34
00000000`042df7f0 000007fe`feee3f75 Explorer!CSoundWnd::s_ThreadProc+0x3b
00000000`042df850 00000000`7731be3d SHLWAPI!WrapperThreadProc+0x116
00000000`042df940 00000000`77456a51 kernel32!BaseThreadInitThunk+0xd
00000000`042df970 00000000`00000000 ntdll!RtlUserThreadStart+0x1d
Some threads belong to different groups simultaneously, for example WOW64 and GUI:
THREAD fffffa800512cbb0 Cid 0af0.0af4 Teb: 000000007efdb000 Win32Thread: fffff900c0763b30
WAIT: (WrUserRequest) UserMode Non-Alertable
fffffa8005138bf0 SynchronizationEvent
Not impersonating
DeviceMap fffff88008479c90
Owning Process fffffa8005145820 Image: reader_sl.exe
Attached Process N/A Image: N/A
Wait Start TickCount 18560 Ticks: 7 (0:00:00:00.109)
Context Switch Count 664 LargeStack
UserTime 00:00:00.000
KernelTime 00:00:00.000
Win32 Start Address reader_sl (0x0000000000403e34)
Stack Init fffffa60039b7db0 Current fffffa60039b7720
Base fffffa60039b8000 Limit fffffa60039b0000 Call 0
Priority 10 BasePriority 8 PriorityDecrement 0 IoPriority 2 PagePriority 5
Child-SP RetAddr Call Site
fffffa60`039b7760 fffff800`0187a6fa nt!KiSwapContext+0x7f
fffffa60`039b78a0 fffff800`0186f35b nt!KiSwapThread+0x13a
fffffa60`039b7910 fffff960`0014c503 nt!KeWaitForSingleObject+0x2cb
fffffa60`039b79a0 fffff960`0014c59a win32k!xxxRealSleepThread+0x25f
fffffa60`039b7a40 fffff960`0014bfea win32k!xxxSleepThread+0x56
fffffa60`039b7a70 fffff960`0014c0e9 win32k!xxxRealInternalGetMessage+0x72e
fffffa60`039b7b50 fffff960`0014d589 win32k!xxxInternalGetMessage+0x35
fffffa60`039b7b90 fffff800`01877ef3 win32k!NtUserGetMessage+0x79
fffffa60`039b7c20 00000000`7545a0ba nt!KiSystemServiceCopyEnd+0x13 (TrapFrame @ fffffa60`039b7c20)
00000000`0007e528 00000000`75443178 wow64win!ZwUserGetMessage+0xa
00000000`0007e530 00000000`7555a996 wow64win!whNtUserGetMessage+0x30
00000000`0007e590 00000000`75543688 wow64!Wow64SystemServiceEx+0xca
00000000`0007ee40 00000000`7555ab46 wow64cpu!ServiceNoTurbo+0x28
00000000`0007eed0 00000000`7555a14c wow64!RunCpuSimulation+0xa
00000000`0007ef00 00000000`7746bf9d wow64!Wow64LdrpInitialize+0x4b4
0000000`0007f460 00000000`7746bb9c ntdll!LdrpInitializeProcess+0x1568
00000000`0007f720 00000000`774568de ntdll! ?? ::FNODOBFM::`string'+0x20959
00000000`0007f7d0 00000000`00000000 ntdll!LdrInitializeThunk+0xe
We can double check that the thread has the real message loop by showing its x86 stack trace:
0: kd> .process /r /p fffffa8005145820 Implicit process is now fffffa80`05145820 Loading User Symbols 0: kd> .load wow64exts 0: kd> .thread /w fffffa800512cbb0 Implicit thread is now fffffa80`0512cbb0 The context is partially valid. Only x86 user-mode context is available. x86 context set 0: kd:x86> .reload Loading Kernel Symbols Loading User Symbols Loading unloaded module list Loading Wow64 Symbols 0: kd:x86> k *** Stack trace for last set context - .thread/.cxr resets it ChildEBP RetAddr 0017fe8c 77185c7c USER32!NtUserGetMessage+0x15 0017feb0 004017e0 USER32!GetMessageA+0xa2 WARNING: Stack unwind information not available. Following frames may be wrong. 0017fef8 00403cb3 reader_sl+0x17e0 0017ff88 7602eccb reader_sl+0x3cb3 0017ff94 7766d24d kernel32!BaseThreadInitThunk+0xe 0017ffd4 7766d45f ntdll_775f0000!__RtlUserThreadStart+0x23 0017ffec 00000000 ntdll_775f0000!_RtlUserThreadStart+0x1b
We continue our taxonomic efforts in the next issue.
[4] In this part we confine our inverstigation to x64 Windows Server 2008 R2.