簡體   English   中英

來自內存緩沖區的 CreateProcess

[英]CreateProcess from memory buffer

我可以使用 CreateProcess 來啟動一個 EXE。 我想在內存緩沖區中擁有 EXE 的內容並對其執行 CreateProcess(或等效項),而不必將其寫入文件。 有沒有辦法做到這一點?

背景故事:我們制作游戲。 我們將一個普通的 EXE 發送給我們的分銷商,然后他們使用他們最喜歡的 DRM 對其進行包裝並將其出售給他們的用戶。 曾有用戶發現崩潰的情況。 大多數崩潰需要 5 分鍾才能修復,但補丁必須通過分銷商,並且可能需要幾天甚至幾周的時間。 我不能只將修補的 EXE 發送給播放器,因為它沒有發行商的 DRM。 我正在考慮將真正的游戲 EXE 分發到加密的數據文件中,這樣被包裝的(外部 EXE)只是解密並啟動真正的 EXE。 這樣我就可以在不禁用 DRM 的情況下安全地分發修復程序。

這實際上很容易。 我在 3 年前讀過的一篇論文中描述了類似的技術。

Windows 允許您使用CREATE_SUSPENDED標志調用CreateProcess函數,該標志告訴 API 在調用 ResumeThread函數之前保持進程掛起。

這讓我們有時間使用GetThreadContext函數來獲取掛起線程的上下文,然后 EBX 寄存器將保存指向PBE(Process Enviroment Block)結構的指針,我們需要確定基地址。

從 PBE 結構的布局中我們可以看到 ImageBaseAddress 存儲在第 8 個字節,因此 [EBX+8] 將為我們提供被掛起進程的實際基地址。

現在我們需要內存中的 EXE,如果內存和內存中的 EXE 的對齊方式不同,請進行適當的對齊。

如果掛起的進程和內存中的exe的基地址匹配,加上如果內存中的exe的imageSize小於或等於掛起的進程'我們可以簡單地使用WriteProcessMemory將內存中的exe寫入內存空間暫停的過程。

但如果不滿足上述條件,我們需要更多的魔法。 首先,我們需要使用ZwUnmapViewOfSection取消映射原始圖像,然后在掛起進程的內存空間內使用VirtualAllocEx分配足夠的內存。 現在我們需要使用WriteProcessMemory函數將內存中的 exe 寫入掛起進程的內存空間。

接下來,將內存中 exe 的 BaseAddress 修補到掛起進程的 PEB->ImageBaseAddress 中。

線程上下文的EAX寄存器保存EntryPoint地址,我們需要用內存中exe的EntryPoint地址重寫。 現在我們需要使用SetThreadContext函數保存更改后的線程上下文。

瞧! 我們准備在掛起的進程上調用ResumeThread函數來執行它!

您可以將游戲編譯為 DLL,並將 DLL 放入加密的數據文件中。 可以從內存中加載 DLL 而無需將其寫入磁盤。 請參閱本教程(最后附有示例代碼): Loading a DLL From Memory

你想做的事情需要 NtCreateProcess,但它沒有記錄,因此很脆弱。 這本書顯然涵蓋了它的使用。

也許你可以建立一個補丁系統? 例如,在啟動時,程序會檢查同一目錄中的補丁 DLL,如果存在則加載它。

為什么需要創建新流程? 我原以為您可以在進行解包/解密的進程的上下文中運行。

你想要的東西可以用一個叫做“Packer”的東西來實現。 實際上從內存中啟動 exe 可能是可能的,但它比打包程序要困難得多;)

最著名的打包程序之一是 UPX(google it)。 有一些工具可以解密它,但它至少應該給你一個開始工作的起點。 我也相當肯定 UPX 是開源的。

看看BoxedAppSDK

它支持從內存緩沖區啟動 exe。

希望能幫助到你。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM