如何获取流程中关键部分的列表

时间:2012-05-18 20:51:45

标签: windbg

在WinDbg中,您可以调用!locks来获取当前进程中所有关键部分的列表。我想知道是否有办法调用调试引擎API来检索相同的列表。我想在一个用C ++构建的自定义构建调试器中完成它,它是在Debug Engine API上构建的。有什么想法吗?

非常感谢。

1 个答案:

答案 0 :(得分:4)

这是相对简单的,您需要使用名为RTL_CRITICAL_SECTION_DEBUG的结构。我在打印输出中添加了注释:

0:011> dt ntdll!_RTL_CRITICAL_SECTION_DEBUG
   +0x000 Type             : Uint2B
   +0x002 CreatorBackTraceIndex : Uint2B
   +0x004 CriticalSection  : Ptr32 _RTL_CRITICAL_SECTION  // This is pointer to actual critical section
   +0x008 ProcessLocksList : _LIST_ENTRY  // All critical sections are chained in this doubly linked list
   +0x010 EntryCount       : Uint4B
   +0x014 ContentionCount  : Uint4B
   +0x018 Flags            : Uint4B
   +0x01c CreatorBackTraceIndexHigh : Uint2B
   +0x01e SpareUSHORT      : Uint2B

如您所见,所有关键部分属于同一个全局列表,其中一个关键部分的ProcessLocksList指向下一个关键部分(以及之前的)的ProcessLocksList。一旦知道了所有ProcessLocksList的地址,就可以通过从中减去sizeof(void *)来提取指向RTL_CRITICAL_SECTION结构的指针。

最后,第一个ProcessLocksList条目的地址由ntdll!RtlCriticalSectionList给出。

以下命令演示了我上面所说的内容。它将打印出该过程中的所有关键部分:

  !list "-t ntdll!_LIST_ENTRY.Flink -e -x \"ln poi(@$extret-0x4); dt ntdll!_RTL_CRITICAL_SECTION poi(@$extret-0x4)\" ntdll!RtlCriticalSectionList"

如果需要,请对x64进行调整。

根据要求添加: 这是x64的一个版本:

  !list "-t ntdll!_LIST_ENTRY.Flink -e -x \"ln poi(@$extret-0x8); dt ntdll!_RTL_CRITICAL_SECTION poi(@$extret-0x8)\" ntdll!RtlCriticalSectionList"