Easy list traversing (dt vs. !list)
CARE: Crash Analysis Report Environment
DATA (Dump Analysis + Trace Analysis) Facebook group
Please join the community of memory (dump) and trace analysis engineers. This group promotes scientific methods and memory dump-based worldview.
Twitter @ DumpAnalysis You can now follow portal and blog news at DumpAnalysis on Twitter
LinkedIn Group Dr. Watson Enthusiasts All about Dr. Watson errors and more. Get news, excerpts and progress reports about the forthcoming book The Science of Dr. Watson: An Illustrated History of Debugging (ISBN 978-1906717070)
2010 (0x7DA) - The Year of Dump Analysis 2011 (0x7DB) - 2020 (0x7E4) The Debugging Decade
I recently discovered in WinDbg help that dt command can be used for traversing linked lists. Most structures I work with have LIST_ENTRY as their first member and it is much easier to use dt command than !list (less typing). For example:
0:000> dt _MYBIGSTRUCTURE
+0x000 Links : _LIST_ENTRY
...
+0x080 SomeName : [33] Uint2B
0:000> dd component!MyBigStructureListHead l1
01022cd0 0007fe58
0:000> .enable_unicode 1
The following command outputs the whole list of structures:
0:000> dt _MYBIGSTRUCTURE -l Links.Flink 0007fe58
And the following command outputs the list of SomeName members:
0:000> dt _MYBIGSTRUCTURE -l Links.Flink -y SomeName 0007fe58
Links.Flink at 0×7fe58
+0×000 Links : [ 0×8e090 - 0×1022cd0 ]
+0×080 SomeName : [33] “Foo”
Links.Flink at 0×8e090
+0×000 Links : [ 0×913f8 - 0×7fe58 ]
+0×080 SomeName : [33] “Bar”
If you don’t remember exact member name you can specify the partial name and any member that matches will be shown:
0:000> dt _MYBIGSTRUCTURE -l Links.Flink -y S 0007fe58
However it your structure doesn’t have LIST_ENTRY as its first member then you need to subtract its offset, for example:
kd> dd nt!PsActiveProcessHead l1
808af068 85fa48b0
kd> dt _EPROCESS
+0x000 Pcb : _KPROCESS
+0x078 ProcessLock : _EX_PUSH_LOCK
+0x080 CreateTime : _LARGE_INTEGER
+0x088 ExitTime : _LARGE_INTEGER
+0x090 RundownProtect : _EX_RUNDOWN_REF
+0x094 UniqueProcessId : Ptr32 Void
+0×098 ActiveProcessLinks : _LIST_ENTRY
kd> dt _EPROCESS -l ActiveProcessLinks.Flink -y ImageFileName 85fa48b0-0×98
ActiveProcessLinks.Flink at 0×85fa4818
+0×098 ActiveProcessLinks : [ 0×85d1ce20 - 0×808af068 ]
+0×164 ImageFileName : [16] “System”
ActiveProcessLinks.Flink at 0×85d1cd88
+0×098 ActiveProcessLinks : [ 0×85dba6b8 - 0×85fa48b0 ]
+0×164 ImageFileName : [16] “smss.exe”
ActiveProcessLinks.Flink at 0×85dba620
+0×098 ActiveProcessLinks : [ 0×858d20b8 - 0×85d1ce20 ]
+0×164 ImageFileName : [16] “csrss.exe”
ActiveProcessLinks.Flink at 0×858d2020
+0×098 ActiveProcessLinks : [ 0×858c20b8 - 0×85dba6b8 ]
+0×164 ImageFileName : [16] “winlogon.exe”
ActiveProcessLinks.Flink at 0×858c2020
+0×098 ActiveProcessLinks : [ 0×8589f0b8 - 0×858d20b8 ]
+0×164 ImageFileName : [16] “services.exe”
Here is another example, not involving LIST_ENTRY but rather a classic single list forward pointer:
0:000> !teb
TEB at 7FFDE000
ExceptionList: 6fc54
Stack Base: 70000
Stack Limit: 6d000
SubSystemTib: 0
FiberData: 1e00
ArbitraryUser: 0
Self: 7ffde000
EnvironmentPtr: 0
ClientId: 22c.228
Real ClientId: 22c.228
RpcHandle: 0
Tls Storage: 742b8
PEB Address: 7ffdf000
LastErrorValue: 997
LastStatusValue: 103
Count Owned Locks:0
HardErrorsMode: 0
0:000> dt -r _TEB
+0x000 NtTib : _NT_TIB
+0x000 ExceptionList : Ptr32 _EXCEPTION_REGISTRATION_RECORD
+0×000 Next : Ptr32 _EXCEPTION_REGISTRATION_RECORD
+0×004 Handler : Ptr32
+0×004 StackBase : Ptr32 Void
+0×008 StackLimit : Ptr32 Void
+0×00c SubSystemTib : Ptr32 Void
+0×010 FiberData : Ptr32 Void
+0×010 Version : Uint4B
+0×014 ArbitraryUserPointer : Ptr32 Void
+0×018 Self : Ptr32 _NT_TIB
0:000> dt _EXCEPTION_REGISTRATION_RECORD -l Next 7FFDE000
Next at 0x7ffde000
+0x000 Next : 0x0006fc54 _EXCEPTION_REGISTRATION_RECORD
+0x004 Handler : 0x00070000 +70000
Next at 0x6fc54
+0x000 Next : 0x0006fcfc _EXCEPTION_REGISTRATION_RECORD
+0x004 Handler : 0x7c5c1f44 KERNEL32!_except_handler3+0
Next at 0x6fcfc
+0x000 Next : 0x0006ff5c _EXCEPTION_REGISTRATION_RECORD
+0x004 Handler : 0x7c2e5649 ADVAPI32!_except_handler3+0
Next at 0x6ff5c
+0x000 Next : 0x0006ffb0 _EXCEPTION_REGISTRATION_RECORD
+0x004 Handler : 0x7c2e5649 ADVAPI32!_except_handler3+0
Next at 0x6ffb0
+0x000 Next : 0x0006ffe0 _EXCEPTION_REGISTRATION_RECORD
+0x004 Handler : 0x01015878 component!_except_handler3+0
Next at 0x6ffe0
+0x000 Next : 0xffffffff _EXCEPTION_REGISTRATION_RECORD
+0x004 Handler : 0x7c5c1f44 KERNEL32!_except_handler3+0
- Dmitry Vostokov -
_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:
June 4th, 2008 at 7:18 pm
Excellent information! This has saved me much time remembering how to navigate the syntax of dt, to traverse linked lists. Keep these coming
June 5th, 2008 at 7:21 am
There is also dl (Display Linked List) command. Give it a try too
December 11th, 2008 at 7:05 am
[…] “이 문서는 http://www.dumpanalysis.org/blog blog 의 번역이며 원래의 자료가 통보 없이 변경될 수 있습니다. 이 자료는 법률적 보증이 없으며 의견을 주시기 위해 원래의 blog 를 방문하실 수 있습니다. (http://www.dumpanalysis.org/blog/index.php/2007/02/11/easy-list-traversing-dt-vs-list/)” […]