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 -

           

Announcements

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:

Baby Turing

Leave a Reply