2010-12-11 62 views
3

好的,我正在編寫一個旨在枚舉給定進程中的線程的應用程序,就像Process Explorer一樣。我很清楚,這可能會打破不同的Windows版本,因爲它依賴於「非官方」的API,如NtQuerySystemInformation,我完全沒有問題。如何在Process Explorer中獲取進程開始地址的「名稱」?

我已經有了獲得給定線程的基地址的代碼。現在我想把它變成類似於進程管理器所做的事情,即「ntdll.dll!EtwDeliverDataBlock + 0x453」。我實際上並不需要函數名稱或偏移量,只是模塊名稱。

我該怎麼做?

回答

4

如果您只需要模塊名稱,最簡單的方法是使用EnumProcessModules獲取所有已加載模塊的列表,然後在每個模塊上使用GetModuleInformationGetModuleInformation返回的其中一項是加載該模塊的基址。從技術上來說,HMODULE本身的整數值與基地址相同,但對我來說這似乎有點脆弱......

然後,只需找到模塊的基地址就在線程當前的電流之下(或開始)地址。

哦,並且得到模塊的實際名稱,有GetModuleBaseName

+0

嗯..這可能工作。有沒有辦法做到這一點,我不必實際打開目標進程的句柄? (例如,不能那樣做到系統進程) – 2010-12-13 20:36:56

+0

@比利:我不確定。我相信Process Explorer實際上使用內核模式驅動程序來實現它的某些功能,所以也許這是其中的一種。 – 2010-12-13 22:07:06

+0

通過調用類SystemModuleInformation的NtQuerySystemInformation來解決它 - 我會盡我所能與您聯繫。 – 2010-12-15 02:18:23

1

您可以使用GetModuleHandleExGET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS標誌來獲取給定地址的模塊句柄。然後您可以使用GetModuleBaseName來獲取模塊的名稱。

編輯:你可能也想使用GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT標誌,所以你不要增加模塊的引用計數。

+2

GetModuleHandleEx不適用於遠程進程。正因爲如此,你建議使用'UNCHANGED_REFCOUNT'標誌也是無關緊要的...... – wj32 2010-12-11 09:12:12

0

您可以使用該代碼來獲取模塊句柄(它比GetModuleHandleEx更快),然後致電GetModuleBaseName

HMODULE GetCallingModule(LPCVOID pCaller) const 
{ 
    HMODULE hModule = NULL; 
    MEMORY_BASIC_INFORMATION mbi; 
    if (VirtualQuery(pCaller, &mbi, sizeof(MEMORY_BASIC_INFORMATION)) == sizeof(MEMORY_BASIC_INFORMATION)) 
    { 
     // the allocation base is the beginning of a PE file 
     hModule = (HMODULE) mbi.AllocationBase; 
    } 
    return hModule; 
} 
+1

這不適用於跨進程。 – 2011-03-07 17:59:16

+0

@KindDragon:它需要'VirtualQueryEx'跨進程工作,甚至需要相應的進程句柄。然而,通過在你自己的進程中查找一個靜態變量的MEMORY_BASIC_INFORMATION :: AllocationBase來獲得'HINSTANCE hInstance'是個巧妙的技巧。但是,如果你避免使用樣板CRT代碼或者這樣做,那隻會是需要的。 – 0xC0000022L 2016-03-27 02:38:38

相關問題