Reading Notebook: 16-July-09
Comments in italics are mine and express my own views, thoughts and opinions
Windows Internals by M. Russinovich, D. Solomon and A. Ionescu:
Two stacks per thread (p. 12) - We can see different stack addresses in any thread from a complete memory dump that starts in user space and was caught up in kernel space:
1: kd> !thread 89025970 1f
THREAD 89025970 Cid 14f8.1518 Teb: 7ffd8000 Win32Thread: 00000000 WAIT: (Unknown) UserMode Non-Alertable
8902abb8 QueueObject
890259e8 NotificationTimer
Not impersonating
DeviceMap e155cbf8
Owning Process 89030d88 Image: dllhost.exe
Attached Process N/A Image: N/A
Wait Start TickCount 1795450 Ticks: 108 (0:00:00:01.687)
Context Switch Count 769
UserTime 00:00:00.046
KernelTime 00:00:00.000
Win32 Start Address ntdll!RtlpWorkerThread (0x7c959f2b)
Start Address kernel32!BaseThreadStartThunk (0x7c8217ec)
Stack Init b6047000 Current b6046c38 Base b6047000 Limit b6044000 Call 0
Priority 8 BasePriority 8 PriorityDecrement 0
ChildEBP RetAddr
b6046c50 80833e95 nt!KiSwapContext+0×26
b6046c7c 8082b72b nt!KiSwapThread+0×2e5
b6046cc4 808ef652 nt!KeRemoveQueue+0×417
b6046d48 8088b19c nt!NtRemoveIoCompletion+0xdc
b6046d48 7c94860c nt!KiFastCallEntry+0xfc
00bfff70 7c9477f9 ntdll!KiFastSystemCallRet
00bfff74 7c959f68 ntdll!NtRemoveIoCompletion+0xc
00bfffb8 7c82482f ntdll!RtlpWorkerThread+0×3d
00bfffec 00000000 kernel32!BaseThreadStart+0×34
We can get kernel raw stack range from this !thread (in magenta above) and get user space raw stack range from !teb command after we switch to our process context and make the thread current:
1: kd> .process /r /p 89030d88
Implicit process is now 89030d88
1: kd> .thread 89025970
Implicit thread is now 89025970
1: kd> !teb
TEB at 7ffd8000
ExceptionList: 00bfffdc
StackBase: 00c00000
StackLimit: 00bf9000
SubSystemTib: 00000000
FiberData: 00001e00
ArbitraryUserPointer: 00000000
Self: 7ffd8000
EnvironmentPointer: 00000000
ClientId: 000014f8 . 00001518
RpcHandle: 00000000
Tls Storage: 00000000
PEB Address: 7ffd4000
LastErrorValue: 1008
LastStatusValue: 0
Count Owned Locks: 0
HardErrorMode: 0
Thread local storage (p. 12) - !tls WinDbg command:
1: kd> !tls
Usage:
tls <slot> [teb]
slot: -1 to dump all allocated slots
{0-0n1088} to dump specific slot
teb: <empty> for current thread
0 for all threads in this process
<teb address> (not threadid) to dump for specific thread.
1: kd> !tls -1
TLS slots on thread: 14f8.1518
0x0000 : 00000000
0x0001 : 00000000
0x0002 : 00000000
0x0003 : 00000000
0x0004 : 00000000
0x0005 : 00000000
0x0006 : 00000000
0x0007 : 00000000
0x0008 : 00000000
0x0009 : 00000000
0x000a : 00000000
0x000b : 00000000
0x000c : 00000000
0x000d : 00000000
0x000e : 00000000
0x000f : 00000000
0x0010 : 00000000
0x0011 : 00000000
0x0012 : 00000000
0x0040 : 00000000
Thread ID (p. 12) - examples of TID member of CID from a user dump and a kernel dump:
0:000> ~*kc
. 0 Id: 1350.1354 Suspend: 1 Teb: 000007ff`fffde000 Unfrozen
Call Site
USER32!GetWindowLongPtrW
USER32!GetMessageW
notepad
notepad
kernel32!BaseThreadInitThunk
ntdll!RtlUserThreadStart
1: kd> !thread fffffa8001cc7bb0
THREAD fffffa8001cc7bb0 Cid 13e4.01dc Teb: 000000007efdb000 Win32Thread: fffff900c210ed50 WAIT: (WrLpcReply) UserMode Non-Alertable
See also PID -TID space graph from one memory dump: Memory Dump Analysis using Excel
Thread context (p. 12) - It is quite large structure. This is x64 context, for example:
0:000> dt _CONTEXT
ntdll!_CONTEXT
+0x000 P1Home : Uint8B
+0x008 P2Home : Uint8B
+0x010 P3Home : Uint8B
+0x018 P4Home : Uint8B
+0x020 P5Home : Uint8B
+0x028 P6Home : Uint8B
+0x030 ContextFlags : Uint4B
+0x034 MxCsr : Uint4B
+0x038 SegCs : Uint2B
+0x03a SegDs : Uint2B
+0x03c SegEs : Uint2B
+0x03e SegFs : Uint2B
+0x040 SegGs : Uint2B
+0x042 SegSs : Uint2B
+0x044 EFlags : Uint4B
+0x048 Dr0 : Uint8B
+0x050 Dr1 : Uint8B
+0x058 Dr2 : Uint8B
+0x060 Dr3 : Uint8B
+0x068 Dr6 : Uint8B
+0x070 Dr7 : Uint8B
+0x078 Rax : Uint8B
+0x080 Rcx : Uint8B
+0x088 Rdx : Uint8B
+0x090 Rbx : Uint8B
+0x098 Rsp : Uint8B
+0x0a0 Rbp : Uint8B
+0x0a8 Rsi : Uint8B
+0x0b0 Rdi : Uint8B
+0x0b8 R8 : Uint8B
+0x0c0 R9 : Uint8B
+0x0c8 R10 : Uint8B
+0x0d0 R11 : Uint8B
+0x0d8 R12 : Uint8B
+0x0e0 R13 : Uint8B
+0x0e8 R14 : Uint8B
+0x0f0 R15 : Uint8B
+0x0f8 Rip : Uint8B
+0x100 FltSave : _XMM_SAVE_AREA32
+0x100 Header : [2] _M128A
+0x120 Legacy : [8] _M128A
+0x1a0 Xmm0 : _M128A
+0x1b0 Xmm1 : _M128A
+0x1c0 Xmm2 : _M128A
+0x1d0 Xmm3 : _M128A
+0x1e0 Xmm4 : _M128A
+0x1f0 Xmm5 : _M128A
+0x200 Xmm6 : _M128A
+0x210 Xmm7 : _M128A
+0x220 Xmm8 : _M128A
+0x230 Xmm9 : _M128A
+0x240 Xmm10 : _M128A
+0x250 Xmm11 : _M128A
+0x260 Xmm12 : _M128A
+0x270 Xmm13 : _M128A
+0x280 Xmm14 : _M128A
+0x290 Xmm15 : _M128A
+0x300 VectorRegister : [26] _M128A
+0x4a0 VectorControl : Uint8B
+0x4a8 DebugControl : Uint8B
+0x4b0 LastBranchToRip : Uint8B
+0x4b8 LastBranchFromRip : Uint8B
+0x4c0 LastExceptionToRip : Uint8B
+0x4c8 LastExceptionFromRip : Uint8B
increaseuserva in BCD (p. 14) - this might get your terminal server installation into problems. See example of Insufficient Memory (PTE) pattern.
AWE (p. 15) - reminds me of old overlay programming on PDP-11 RSX-11M
8192Gb VUS and the same for VKS on x64 (p. 15)
Transition from user mode to kernel mode (p. 17) - example from a complete memory dump (blue - user space and mode, red - kernel space and mode)
THREAD 89fef020 Cid 0ebc.0ec0 Teb: 7ffdd000 Win32Thread: bc15eea8 WAIT: (Unknown) UserMode Non-Alertable
8ab06754 NotificationEvent
Not impersonating
DeviceMap e1006df0
Owning Process 89e58570 Image: svchost.exe
Wait Start TickCount 2613554 Ticks: 114791 (0:00:29:53.609)
Context Switch Count 5430 LargeStack
UserTime 00:00:00.093
KernelTime 00:00:00.062
Win32 Start Address svchost!wmainCRTStartup (0x010020c9)
Start Address kernel32!BaseProcessStartThunk (0x7c82b5ff)
Stack Init b86aa000 Current b86a9bec Base b86aa000 Limit b86a7000 Call 0
Priority 13 BasePriority 8 PriorityDecrement 0
Kernel stack not resident.
ChildEBP RetAddr
b86a9c04 80832f7a nt!KiSwapContext+0×26
b86a9c30 8082925c nt!KiSwapThread+0×284
b86a9c78 808f482c nt!KeWaitForSingleObject+0×346
b86a9ca0 808f198b nt!IopSynchronousServiceTail+0×180
b86a9d38 80888c7c nt!NtReadFile+0×5cf
b86a9d38 7c94ed54 nt!KiFastCallEntry+0xfc
0007fc40 7c941b84 ntdll!KiFastSystemCallRet
0007fc44 7c80189f ntdll!NtReadFile+0xc
0007fcac 77f595ab kernel32!ReadFile+0×16c
0007fcd8 77f5943c ADVAPI32!ScGetPipeInput+0×2a
0007fd4c 77f596c1 ADVAPI32!ScDispatcherLoop+0×51
0007ffb0 0100214d ADVAPI32!StartServiceCtrlDispatcherW+0xe3
0007ffc0 7c8123e5 svchost!_wmainCRTStartup+0×7f
0007fff0 00000000 kernel32!BaseProcessStart+0×23
Special system instruction to switch to kernel mode (p. 17) - to see this instruction we can disassemble the code before the return address of the first user space function from the stack trace:
// W2K3
1: kd> k
*** Stack trace for last set context - .thread/.cxr resets it
ChildEBP RetAddr
b6046c50 80833e95 nt!KiSwapContext+0x26
b6046c7c 8082b72b nt!KiSwapThread+0x2e5
b6046cc4 808ef652 nt!KeRemoveQueue+0x417
b6046d48 8088b19c nt!NtRemoveIoCompletion+0xdc
b6046d48 7c94860c nt!KiFastCallEntry+0xfc
00bfff70 7c9477f9 ntdll!KiFastSystemCallRet
00bfff74 7c959f68 ntdll!NtRemoveIoCompletion+0xc
00bfffb8 7c82482f ntdll!RtlpWorkerThread+0×3d
00bfffec 00000000 kernel32!BaseThreadStart+0×34
1: kd> ub 7c94860c
[…]
ntdll!KiFastSystemCall:
7c948608 8bd4 mov edx,esp
7c94860a 0f34 sysenter
// W2K
1: kd> k
ChildEBP RetAddr
b3994950 8044b8fe nt!MiFreeSessionSpaceMap+0x3d
b3994b94 80537bf5 nt!MiDereferenceSession+0x29a
b3994ba0 80441f05 nt!MiSessionRemoveProcess+0x41
b3994c50 804e8582 nt!MmCleanProcessAddressSpace+0x14f
b3994d00 804e801c nt!PspExitThread+0x4e4
b3994d0c 8043110a nt!PsExitSpecialApc+0x1a
b3994d4c 804683f4 nt!KiDeliverApc+0x19a
b3994d4c 77f88b27 nt!KiServiceExit+0×59
[…]
1: kd> ub 77f88b27
[…]
77f88b1a 8bff mov edi,edi
77f88b1c b8ab000000 mov eax,0ABh
77f88b21 8d542404 lea edx,[esp+4]
77f88b25 cd2e int 2Eh
Mode transition is not a context switch (p. 17) - This is one of questions I’m asked by engineers
Reliability and Performance Monitor (pp. 18 -19) - looks like it combines the old Performance Monitor and the new Reliability Monitor
Idle process (p. 19) - here is example from a dump:
3: kd> k
ChildEBP RetAddr
f773d3b8 00000000 processr!AcpiC1Idle+0x12
3: kd> !process
PROCESS 8089fb40 SessionId: none Cid: 0000 Peb: 00000000 ParentCid: 0000
DirBase: 013d5000 ObjectTable: e10007b0 HandleCount: 8671.
Image: Idle
VadRoot 00000000 Vads 0 Clone 0 Private 0. Modified 16. Locked 0.
DeviceMap 00000000
Token e1002030
ElapsedTime 00:00:00.000
UserTime 00:00:00.000
KernelTime 1 Day 03:41:20.812
QuotaPoolUsage[PagedPool] 0
QuotaPoolUsage[NonPagedPool] 0
Working Set Sizes (now,min,max) (7, 50, 450) (28KB, 200KB, 1800KB)
PeakWorkingSetSize 0
VirtualSize 0 Mb
PeakVirtualSize 0 Mb
PageFaultCount 0
MemoryPriority BACKGROUND
BasePriority 0
CommitCharge 0
THREAD 8089f8c0 Cid 0000.0000 Teb: 00000000 Win32Thread: 00000000 RUNNING on processor 0
THREAD f772a0a0 Cid 0000.0000 Teb: 00000000 Win32Thread: 00000000 RUNNING on processor 1
THREAD f77320a0 Cid 0000.0000 Teb: 00000000 Win32Thread: 00000000 RUNNING on processor 2
THREAD f773a0a0 Cid 0000.0000 Teb: 00000000 Win32Thread: 00000000 RUNNING on processor 3
3: kd> !thread 8089f8c0
THREAD 8089f8c0 Cid 0000.0000 Teb: 00000000 Win32Thread: 00000000 RUNNING on processor 0
Not impersonating
Owning Process 8089fb40 Image: Idle
Attached Process N/A Image: N/A
Wait Start TickCount 0 Ticks: 1795558 (0:07:47:35.593)
Context Switch Count 41020289
UserTime 00:00:00.000
KernelTime 07:03:12.406
Stack Init 8089c8b0 Current 8089c5fc Base 8089c8b0 Limit 808998b0 Call 0
Priority 0 BasePriority 0 PriorityDecrement 0
ChildEBP RetAddr Args to Child
8089c604 00000000 0000000e 00000000 00000000 nt!KiIdleLoop+0xa3
Terminal services (pp. 19 -20) - an for architectural overview (UML diagram) please see this post: Reverse Engineering Citrix ThinWire
Objects, attributes and methods (p. 21) - here we can see some general methods from object headers:
0:000> dt _OBJECT_HEADER
ntdll!_OBJECT_HEADER
+0x000 PointerCount : Int8B
+0x008 HandleCount : Int8B
+0x008 NextToFree : Ptr64 Void
+0×010 Type : Ptr64 _OBJECT_TYPE
+0×018 NameInfoOffset : UChar
+0×019 HandleInfoOffset : UChar
+0×01a QuotaInfoOffset : UChar
+0×01b Flags : UChar
+0×020 ObjectCreateInfo : Ptr64 _OBJECT_CREATE_INFORMATION
+0×020 QuotaBlockCharged : Ptr64 Void
+0×028 SecurityDescriptor : Ptr64 Void
+0×030 Body : _QUAD
0:000> dt _OBJECT_TYPE
ntdll!_OBJECT_TYPE
+0x000 TypeList : _LIST_ENTRY
+0x010 Name : _UNICODE_STRING
+0x020 DefaultObject : Ptr64 Void
+0x028 Index : Uint4B
+0x02c TotalNumberOfObjects : Uint4B
+0x030 TotalNumberOfHandles : Uint4B
+0x034 HighWaterNumberOfObjects : Uint4B
+0x038 HighWaterNumberOfHandles : Uint4B
+0×040 TypeInfo : _OBJECT_TYPE_INITIALIZER
+0×0b0 Mutex : _ERESOURCE
+0×118 TypeLock : _EX_PUSH_LOCK
+0×120 Key : Uint4B
+0×128 ObjectLocks : [32] _EX_PUSH_LOCK
+0×228 CallbackList : _LIST_ENTRY
0:000> dt _OBJECT_TYPE_INITIALIZER
ntdll!_OBJECT_TYPE_INITIALIZER
+0x000 Length : Uint2B
+0x002 ObjectTypeFlags : UChar
+0x002 CaseInsensitive : Pos 0, 1 Bit
+0x002 UnnamedObjectsOnly : Pos 1, 1 Bit
+0x002 UseDefaultObject : Pos 2, 1 Bit
+0x002 SecurityRequired : Pos 3, 1 Bit
+0x002 MaintainHandleCount : Pos 4, 1 Bit
+0x002 MaintainTypeList : Pos 5, 1 Bit
+0x002 SupportsObjectCallbacks : Pos 6, 1 Bit
+0x004 ObjectTypeCode : Uint4B
+0x008 InvalidAttributes : Uint4B
+0x00c GenericMapping : _GENERIC_MAPPING
+0x01c ValidAccessMask : Uint4B
+0x020 RetainAccess : Uint4B
+0x024 PoolType : _POOL_TYPE
+0x028 DefaultPagedPoolCharge : Uint4B
+0x02c DefaultNonPagedPoolCharge : Uint4B
+0×030 DumpProcedure : Ptr64 void
+0×038 OpenProcedure : Ptr64 long
+0×040 CloseProcedure : Ptr64 void
+0×048 DeleteProcedure : Ptr64 void
+0×050 ParseProcedure : Ptr64 long
+0×058 SecurityProcedure : Ptr64 long
+0×060 QueryNameProcedure : Ptr64 long
+0×068 OkayToCloseProcedure : Ptr64 unsigned char
- Dmitry Vostokov @ SoftwareGeneralist.com -
_1125.png)
Coming Soon:
Debugging Notebook: Essential Concepts, WinDbg Commands and Tools
Crash Dump Analysis for System Administrators and Support Engineers
New Magazines:
Debugged! MZ/PE: MagaZine for/from Practicing Engineers
New Books:
Memory Dump Analysis Anthology, Volume 3
First Fault Software Problem Solving: A Guide for Engineers, Managers and Users
x64 Windows Debugging: Practical Foundations
Also available:
Windows Debugging: Practical Foundations
DLL List Landscape: The Art from Computer Memory Space
Dumps, Bugs and Debugging Forensics: The Adventures of Dr. Debugalov
WinDbg: A Reference Poster and Learning Cards
Memory Dump Analysis Anthology, Volume 2
Memory Dump Analysis Anthology, Volume 1
New Children's Book: