2008-10-07 29 views

回答

1

當對象在同一個房間內加載進程(即從一個DLL)時,可能會有一些技巧可以在內存中找到DLL。例如,如果您查看虛擬方法表(vtable)中的代碼指針進入活動對象,它們通常會指向DLL。然後,您可以使用一些系統調用來確定代碼是哪個加載的DLL。

但是有很多潛在的缺陷。如果您必須將這些對象加載到單獨的單元中,那麼代碼指針將指向一個存根,而不是實際的代碼。另外,許多COM庫實際上都在運行時提供的包裝類中實現公共接口,因此很可能會在許多常見用例中給出錯誤信息。 (也就是說,你最終會得到運行時DLL的信息,通常是MFC或ATL)。

當一個對象被加載出過程(即從一個EXE)時,我不知道任何可行的方法來追查哪個EXE對應於活動對象。 (很明顯,這些數據必須存在於你的進程或COM運行時的某個地方,但它被埋在存根之下的某個地方,並且可能取決於你正在運行的Windows的版本)。

所以,除非您正在查看一組非常有限的對象(與您在同一間公寓內加載的所有進程中),否則最好的辦法是使用註冊表中的註冊信息查找您需要的內容。這很麻煩,因爲這是可能從操作系統的版本到版本之間發生變化的事情之一,但幸運的是COM已經存在了很長時間,以至於這些年來這一切都沒有改變。

給你從Component Categories Manager得到了一個對象的CLSID,你會查找對應的二進制文件,如下所示:

  1. 打開註冊表項HKEY_CLASSES_ROOT\CLSID\{xxxxxxxxx-yyyyy-zzzz-aaaa-bbbbbbbbbbbbbb}其中括號內字符串的的CLSID你想找到的對象。
  2. 如果這是一個進程內對象,將會有一個名爲InProcServer32的子項,其「default」REG_SZ包含您需要的DLL的完整路徑。
  3. 如果這是一個超出proc的對象,將會有一個名爲LocalServer32的子項,其「default」REG_SZ包含您需要的EXE的完整路徑。在某些情況下,您可能不得不修剪掉這個字符串的命令行開關以獲得EXE路徑。
  4. 使用以前步驟中的DLL或EXE,可以在Win32中調用GetFileVersionInfo()(如果有.NET,則使用System.Diagnostics.FileVersionInfo.GetVersionInfo)以從可執行文件中檢索版本信息結構,該版本信息結構中將包含版本和說明。
0

假設它只用於記錄目的,獲取此信息的一種方法是簡單地等待所有初始化完成,然後枚舉加載的模塊,並將每個日誌文件的詳細信息轉儲到日誌文件。

顯然,這隻適用於inproc對象,如果應用程序非常動態,它將不起作用,但它也會捕獲非COM DLL。

相關問題