3
在WinDbg中,可以調用!locks來獲取當前進程中所有關鍵部分的列表。我想知道是否有一種方法可以調用調試引擎API來檢索相同的列表。我想在一個構建於調試引擎API上的C++構建的定製構建調試器中執行此操作。有什麼想法嗎?如何獲取進程中關鍵部分的列表
非常感謝。
在WinDbg中,可以調用!locks來獲取當前進程中所有關鍵部分的列表。我想知道是否有一種方法可以調用調試引擎API來檢索相同的列表。我想在一個構建於調試引擎API上的C++構建的定製構建調試器中執行此操作。有什麼想法嗎?如何獲取進程中關鍵部分的列表
非常感謝。
這是比較直接的,你需要使用稱爲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"
非常感謝。這非常有幫助。你能否提供64位版本?另外,有沒有什麼辦法可以在dbghelp.dll和/或dbgeng.dll的幫助下直接檢查C++程序中的_RTL_CRITICAL_SECTION_DEBUG? – awatto
@awatto - x64版本現在被添加到答案 - 這是一個從0x4到0x8的簡單變化,以補償指針類型大小。 –
@awatto - 回答第二個問題 - 在winnt.h中聲明瞭RTL_CRITICAL_SECTION和RTL_CRITICAL_SECTION_DEBUG結構,因此使用應用程序中的結構應該沒有問題。例如,如果您有一個指向關鍵部分實例的指針,則可以指向RTL_CRITICAL_SECTION的指針,然後使用字段DebugInfo作爲指向RTL_CRITICAL_SECTION_DEBUG結構的指針。 –