2015-05-04 73 views
1

現象就是這樣。爲什麼進程在不同階段加載模塊(dll)?

我正在嘗試實施dll注入。我的應用程序以'掛起'狀態創建進程(使用CreateProcess和CREATE_SUSPENDED),等待一個重要的dll被加載(當然是kernel32.dll),然後執行注入。注入後使用ResumeThread恢復暫停的進程。

我正在使用暫停的進程創建,希望在dll加載之前的任何其他執行之前注入dll。但是在執行這個時,我發現了一些有趣的東西

我已經使用notepad.exe簡單地測試了這個注入,它工作得很好。但是當我將可執行文件複製爲notepad2.exe時,我的注入等待無限時間。 Kernel32.dll永不加載,直到進程的主線程恢復。

似乎有某種預先加載模塊的「已認證」可執行文件(或者我的計算機中安裝的某些已經使用dll注入的安全解決方案可能會導致這種不同的執行)。

是否有人知道是否有任何類型的模塊以不同的方式加載? (坦率地說,我還是不明白windows進程的生命週期......)

+1

根據我的經驗,最初只映射了ntdll.dll,並且在線程恢復時排隊等待APC運行。這將調用'ntdll!LdrpInitializeProcess',它初始化執行環境(例如語言支持,堆,線程本地存儲,KnownDlls目錄)加載kernel32.dll並獲取BaseThreadInitThunk的地址,執行靜態DLL導入,斷開連接的調試器並運行init例程。然後執行跳轉到'ntdll!RtlUserThreadStart',它調用'kernel32!BaseThreadInitThunk',它調用EXE的入口點,例如'WinMainCRTStartup'。 – eryksun

+0

我看到DLL加載在進程啓動過程中的表現與表面上隨機的方式不同,即使是相同的可執行文件。我懷疑Windows試圖根據未記錄的啓發式優化進程啓動 - 例如,每當特定的可執行文件啓動時它可能會「記筆記」,並使用該信息嘗試下次更快地啓動它。不幸的是,底線可能是沒有可靠的方法來預測kernel32.dll(或任何其他系統DLL)是否會在恢復過程之前或之後加載。 (但是我猜你可以對APC進行排隊?) –

+0

@HarryJohnston,在內存管理器級別有一些服務,例如prefetch/superfetch,用於優化系統加載的DLL和EXE頁面以加速應用程序加載。但是我認爲最初的APC排隊以'ntdll!LdrInitializeThunk'開始的工作多年來一直保持一致。我總是在下面的調試會話中看到初始化步驟和DLL加載順序:'cdb -xe cpr -c「bp ntdll!LdrInitializeThunk; g」notepad「。也就是說,它可能是'NtCreateUserProcess'有時預先映射ntdll.dll以外的DLL。 – eryksun

回答

0

我想我找到了答案。答案是,雖然進程處於SUSPENDED狀態,因此主線程停止,當該進程中的某個線程嘗試訪問某個模塊時,將加載所需的模塊(這意味着,該應用程序似乎是'懶惰加載'需要模塊)

在評論中,我說我的PC上安裝的某些安全解決方案所保護的進程使用Detour來注入DLL,因此在進程處於SUSPENDED狀態時某些進程加載模塊。 但這不是Detour的具體情況,而是每個流程的一般問題。

我很愚蠢,我使用的注入技術是列出目標進程中加載​​的所有模塊,找到kernel32.dll,計算LoadLibraryW的偏移量,並使用遠程線程調用該函數。在這種技術中,注入器枚舉所有模塊之前 LoadLibrary函數曾經被調用過,因此LazyLoading永遠不會發生,因此我永遠無法看到kernel32.dll加載進程。

當我使用從當前進程使用GetProcAddress的簡單技術時,獲取LoadLibrary函數的地址,並遠程調用進程,kernel32.dll被成功加載並且注入成功。

如果有多個應用程序通過'使用Detour'安全解決方案進行保護,即使我暫停了進程,注入嘗試也會發生,這就是爲什麼kernel32.dll加載到notepad.exe上(它在列表中的安全解決方案),但未加載到notepad2.exe上(因爲圖像名稱不同,它不在列表中)。

我只是愚蠢的,試圖使用更復雜的方法進行DLL注入,這就是導致所有這些問題的原因。

並且非常感謝評論。

相關問題