現象就是這樣。爲什麼進程在不同階段加載模塊(dll)?
我正在嘗試實施dll注入。我的應用程序以'掛起'狀態創建進程(使用CreateProcess和CREATE_SUSPENDED),等待一個重要的dll被加載(當然是kernel32.dll),然後執行注入。注入後使用ResumeThread恢復暫停的進程。
我正在使用暫停的進程創建,希望在dll加載之前的任何其他執行之前注入dll。但是在執行這個時,我發現了一些有趣的東西
我已經使用notepad.exe簡單地測試了這個注入,它工作得很好。但是當我將可執行文件複製爲notepad2.exe時,我的注入等待無限時間。 Kernel32.dll永不加載,直到進程的主線程恢復。
似乎有某種預先加載模塊的「已認證」可執行文件(或者我的計算機中安裝的某些已經使用dll注入的安全解決方案可能會導致這種不同的執行)。
是否有人知道是否有任何類型的模塊以不同的方式加載? (坦率地說,我還是不明白windows進程的生命週期......)
根據我的經驗,最初只映射了ntdll.dll,並且在線程恢復時排隊等待APC運行。這將調用'ntdll!LdrpInitializeProcess',它初始化執行環境(例如語言支持,堆,線程本地存儲,KnownDlls目錄)加載kernel32.dll並獲取BaseThreadInitThunk的地址,執行靜態DLL導入,斷開連接的調試器並運行init例程。然後執行跳轉到'ntdll!RtlUserThreadStart',它調用'kernel32!BaseThreadInitThunk',它調用EXE的入口點,例如'WinMainCRTStartup'。 – eryksun
我看到DLL加載在進程啓動過程中的表現與表面上隨機的方式不同,即使是相同的可執行文件。我懷疑Windows試圖根據未記錄的啓發式優化進程啓動 - 例如,每當特定的可執行文件啓動時它可能會「記筆記」,並使用該信息嘗試下次更快地啓動它。不幸的是,底線可能是沒有可靠的方法來預測kernel32.dll(或任何其他系統DLL)是否會在恢復過程之前或之後加載。 (但是我猜你可以對APC進行排隊?) –
@HarryJohnston,在內存管理器級別有一些服務,例如prefetch/superfetch,用於優化系統加載的DLL和EXE頁面以加速應用程序加載。但是我認爲最初的APC排隊以'ntdll!LdrInitializeThunk'開始的工作多年來一直保持一致。我總是在下面的調試會話中看到初始化步驟和DLL加載順序:'cdb -xe cpr -c「bp ntdll!LdrInitializeThunk; g」notepad「。也就是說,它可能是'NtCreateUserProcess'有時預先映射ntdll.dll以外的DLL。 – eryksun