步驟零;注入的DLL應該有一個入口點,我們稱它爲Init()
,它將LPCWSTR
作爲其單個參數並返回int
;即與LoadLibrary()
相同的簽名,因此作爲線程起始函數地址同樣有效......
第一步;使用加載庫和遠程線程進行注入。在注入的DLL DLLMain()
中做什麼都不聰明。存儲作爲注入線程退出代碼返回的HMODULE
,這是注入DLL的HMODULE
和返回值LoadLibrary()
。
注意,這已不再是在x64的可靠方法,如果/DYNAMICBASE
和ASLR(地址空間佈局隨機化)爲HMODULE
在x64上啓用比從GetThreadExitCode()
返回DWORD
值和地址空間變化意味着大它不再像HMODULE
的值足夠小以適應DWORD
。請參閱下面的註釋和鏈接問題(此處),以解決使用共享內存進行通信的問題HMODULE
第二步;使用LoadLibrary將注入的DLL加載到正在進行注入的進程中。然後在您的地址空間中找到您的Init()
入口點的偏移量,並在您的地址空間中減去您注入的DLL的HMODULE
。您現在具有Init()
函數的相對偏移量。取目標進程中注入DLL的HMODULE
(即您在第一步中保存的值),並向其添加相對地址Init()
。您現在在目標進程中的地址爲Init()
。
第三步;在目標進程中使用您用來呼叫LoadLibrary()
的相同「遠程線程」方法調用Init()
。您可以將一個字符串傳遞給Init()調用,這可以是任何您喜歡的。
我傾向於做的是傳遞一個唯一的字符串鍵,作爲命名管道名稱的一部分。注入的DLL和注入過程現在都知道命名管道的名稱,並且可以在它們之間進行通信。 Init()
函數不是DLLMain()
,並且不受影響DLLMain()
的限制(因爲它不在LoadLibrary
等內部調用),因此您可以在其中執行常規任務。一旦注入的DLL和注入過程通過命名管道連接,您可以根據需要來回傳遞命令和數據結果。由於您將Init()
函數傳遞給一個字符串,因此您可以確保命名管道對於注入過程的此特定實例以及此特定的注入DLL是唯一的,這意味着您可以同時運行多個注入過程實例,並且每個過程都可以注入到多個目標進程中,並且所有這些通信通道都是唯一可控的。
我看不到如何將字符串傳遞給CreateRemoteThread(...,dllExportAddrInRemoteProcess,stringBuffer,...)可以工作(沒有WriteProcessMemory)。但是,這兩個進程都知道注入線程的進程標識和線程標識,因此您可以將這些標識用作與IPC一起使用的名稱的一部分 – Anders 2009-07-22 11:55:39