Reading Notebook: 17-August-09
Comments in italics are mine and express my own views, thoughts and opinions
Windows Internals by M. Russinovich, D. Solomon and A. Ionescu:
TpWorkerFactory (thread pools), TmRm, TmTx, TmTm, TmEn executive objects (p. 137)
Object structure (p. 138) - I created a simplified UML diagram when I was investigating object signaling: http://www.dumpanalysis.org/blog/index.php/2008/03/06/signaled-objects/. Here’s another example of how to get an object header from the dispatcher address a thread is waiting for:
THREAD fffffa800579f060 Cid 0ee8.113c Teb: 000000007ef9b000 Win32Thread: 0000000000000000 WAIT: (UserRequest) UserMode Non-Alertable
    fffffa800538bc10 ProcessObject
Not impersonating
DeviceMap                fffff88006972f30
Owning Process           fffffa8005ad1c10      Image:        WINWORD.EXE
Attached Process         N/A           Image:        N/A
Wait Start TickCount     29919495      Ticks: 4883905 (0:21:09:49.406)
Context Switch Count     3           Â
UserTime                 00:00:00.000
KernelTime               00:00:00.000
Win32 Start Address 0×0000000073433619
Stack Init fffffa6004bc8db0 Current fffffa6004bc8940
Base fffffa6004bc9000 Limit fffffa6004bc3000 Call 0
Priority 10 BasePriority 8 PriorityDecrement 2 IoPriority 2 PagePriority 5
Kernel stack not resident.
Child-SP         RetAddr          Call Site
fffffa60`04bc8980 fffff800`0186d28a nt!KiSwapContext+0×7f
fffffa60`04bc8ac0 fffff800`0186e68a nt!KiSwapThread+0×2fa
fffffa60`04bc8b30 fffff800`01ae2368 nt!KeWaitForSingleObject+0×2da
fffffa60`04bc8bc0 fffff800`018670f3 nt!NtWaitForSingleObject+0×98
fffffa60`04bc8c20 00000000`75ec3d09 nt!KiSystemServiceCopyEnd+0×13 (TrapFrame @ fffffa60`04bc8c20)
00000000`049deec8 00000000`00000000 0×75ec3d09
0: kd> dt _DISPATCHER_HEADER fffffa800538bc10
nt!_DISPATCHER_HEADER
  +0×000 Type            : 0×3 ”
  +0×001 Abandoned       : 0 ”
  +0×001 Absolute        : 0 ”
  +0×001 NpxIrql         : 0 ”
  +0×001 Signalling      : 0 ”
  +0×002 Size            : 0×30 ‘0′
  +0×002 Hand            : 0×30 ‘0′
  +0×003 Inserted        : 0 ”
  +0×003 DebugActive     : 0 ”
  +0×003 DpcActive       : 0 ”
  +0×000 Lock            : 3145731
  +0×004 SignalState     : 0
  +0×008 WaitListHead    : _LIST_ENTRY [ 0xfffffa80`04ca25f8 - 0xfffffa80`0566bca8 ]
0: kd> dt _OBJECT_HEADER
nt!_OBJECT_HEADER
  +0x000 PointerCount    : Int8B
  +0x008 HandleCount     : Int8B
  +0x008 NextToFree      : Ptr64 Void
  +0x010 Type            : Ptr64 _OBJECT_TYPE
  +0x018 NameInfoOffset  : UChar
  +0x019 HandleInfoOffset : UChar
  +0x01a QuotaInfoOffset : UChar
  +0x01b Flags           : UChar
  +0x020 ObjectCreateInfo : Ptr64 _OBJECT_CREATE_INFORMATION
  +0x020 QuotaBlockCharged : Ptr64 Void
  +0x028 SecurityDescriptor : Ptr64 Void
  +0×030 Body            : _QUAD
0: kd> dt _OBJECT_HEADER fffffa800538bc10-30
nt!_OBJECT_HEADER
  +0×000 PointerCount    : 55
  +0×008 HandleCount     : 5
  +0×008 NextToFree      : 0×00000000`00000005
  +0×010 Type            : 0xfffffa80`03bcd840 _OBJECT_TYPE
  +0×018 NameInfoOffset  : 0 ”
  +0×019 HandleInfoOffset : 0 ”
  +0×01a QuotaInfoOffset : 0 ”
  +0×01b Flags           : 0×20 ‘ ‘
  +0×020 ObjectCreateInfo : 0xfffffa80`0489c010 _OBJECT_CREATE_INFORMATION
  +0×020 QuotaBlockCharged : 0xfffffa80`0489c010
  +0×028 SecurityDescriptor : 0xfffff880`06d9825b
  +0×030 Body            : _QUAD
Here is another example of how to get the name of an object if it exists (38 is the size of x64 _OBJECT_HEADER, _QUAD is 8 bytes):
0: kd> dt _OBJECT_HEADER fffffa80047da830
nt!_OBJECT_HEADER
  +0×000 PointerCount    : 175
  +0×008 HandleCount     : 116
  +0×008 NextToFree      : 0×00000000`00000074
  +0×010 Type            : 0xfffffa80`03c0b080 _OBJECT_TYPE
  +0×018 NameInfoOffset  : 0×20 ‘ ‘
  +0×019 HandleInfoOffset : 0×30 ‘0′
  +0×01a QuotaInfoOffset : 0 ”
  +0×01b Flags           : 0×20 ‘ ‘
  +0×020 ObjectCreateInfo : 0xfffff800`01990fa0 _OBJECT_CREATE_INFORMATION
  +0×020 QuotaBlockCharged : 0xfffff800`01990fa0
  +0×028 SecurityDescriptor : 0xfffff880`0678a6fc
  +0×030 Body            : _QUAD
0: kd> dt _UNICODE_STRING fffffa80047da830-38+20
nt!_UNICODE_STRING
 “WinSta0″
  +0×000 Length          : 0xe
  +0×002 MaximumLength   : 0xe
  +0×008 Buffer          : 0xfffff880`00969660 “WinSta0″
Pointer count >= Handle count (p. 139)
- Dmitry Vostokov @ SoftwareGeneralist.com -
_1125.png)
Coming Soon:
Management Bits: An Anthology from Reductionist Manager
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: Color Supplement for Volumes 1-3
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:
August 18th, 2009 at 3:53 pm
You can use !object to get the object header address in a more portable way, and/or use C++-style @@sizeof(OBJECT_HEADER) instead of hardcoding the 38 or 18 value for x64/x86.
Also !ustr will give you nicer output for a UNICODE_STRING, assuming the structure isn’t corrupted (which is a bigger problem!)
–
Best regards,
Alex Ionescu
August 20th, 2009 at 12:02 am
Thanks for shortcuts! Will try next time
Dmitry