3

在 WinDbg 中,你可以调用 !locks 来获取当前进程中所有临界区的列表。我想知道是否有办法调用调试引擎 API 来检索相同的列表。我想在 C++ 中构建的定制调试器中执行此操作,该调试器基于调试引擎 API 构建。有什么想法吗?

非常感谢。

4

1 回答 1

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下一个临界区(以及前一个临界区)。一旦知道所有ProcessLocksLists 的地址,就可以通过从中减去 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"
于 2012-05-18T22:01:20.347 回答