2013-10-30 108 views
6

首先,我不想注入一個dll。我想使用WriteProcessMemory()注入代碼(如果這甚至可能)。我已經使用ReadProcessMemory(),所以我認爲寫作不是什麼大不了的事。
好吧,讓我們說有在TargetProgram.exe + D78C612
的功能,讓我們說,它可以被稱爲是這樣的:C++:代碼注入調用函數

push eax 
push [esp+08] 
push edx 
push 00 
push TargetProgram.exe+AF76235 
push 04 
call TargetProgram.exe+D78C612 

我究竟將如何做到這一點用WriteProcessMemory的()?
我的意思是我在哪裏可以找到一段可以注入我的代碼而不會覆蓋重要內容的部分。最重要的是,我將如何調用這個函數?
只需在活動例程中跳轉到我的代碼,之後跳回並刪除它?但是,我如何找到這個例程呢?
這麼多問題,我不知道如何開始......我希望你能幫助我。 :)
如果你有時間,我真的很想看到一個函數調用注入的示例代碼。

回答

4

您可以使用VirtualAllocEx在遠程進程中分配內存,然後將您的程序複製到此內存中。

這裏是做注射步驟:

SuspendThread(hThread); // Suspend the remote thread 
remote_address = VirtualAllocEx(hProcess, ...) // allocate memory for your code 
WriteProcessMemory(hProcess, remote_address, local_address, length, NULL) // copy your code to remote process 
WriteProcessMemory(hProcess, remote_fixup, ...) // insert a jump to your code 
ResumeThread(hThread); // Resume the remote thread 
+0

我有一個類似的問題作爲OP,但我沒有得到你的第一WriteProcessMemory調用。作爲local_address,我可以傳遞函數的地址,但我無法在下一個參數中傳遞它的長度。只是因爲我不知道它有多大(因爲編譯器還沒有編譯它)。那麼WriteProcessMemory是否適合從我的過程寫入另一個函數/代碼?編輯:或者是彙編程序中唯一的關鍵寫入函數(我可以計算它)而不是C++? – Kra

+2

@Kra在大多數情況下,您不能將C函數複製到另一個進程,因爲跳轉地址將被破壞。您必須修復relocs或編寫可重定位的代碼。在這兩種情況下,你都必須使用匯編語言。爲了回答你關於函數代碼長度的問題,我認爲你可以嘗試禁用優化並寫兩個函數f1()和f2(),其中f2代碼中的f1。然後你可以從f2的地址中減去f1的地址,[希望]得到f1的長度。但函數大小是你問題最少的地方。 – Max

+0

明白了。謝謝。 – Kra

1

正如馬克斯的答覆中提到,VirtualAllocEx是在遠程進程分配內存頁的一種方式,假設你有在過程中PROCESS_VM_OPERATION訪問權題。您還需要確保新的頁面在寫入期間標記爲PAGE_EXECUTE_READWRITE以保護其級別,然後使用VirtualProtectEx將其更改爲PAGE_EXECUTE_READ

請注意,x86中的分支和某些調用指令是IP相對的。這意味着它們的編碼取決於它們在內存中的位置,因爲它們從指令的末尾使用帶符號的相對位移。因此,如果您計劃從新代碼調用現有函數,請確保在使用相對調用指令時考慮到這一點,或者使用間接/即時形式。

但是,如果您不知道您要在此完成的工作,很難推薦一種用於執行新目標代碼的技術。使用新的代碼,您可以使用CreateRemoteThread注入遠程線程來執行它,而不必中斷任何現有的線程。這將是執行新代碼的最簡單的解決方案,但要求您調用的代碼是線程安全的。挑選一個已經運行的線程,掛起它,修改EIP或者引入一個繞道,並且無副作用地恢復它(在注入的調用中正確保存上下文)是非常棘手的。

個人注意事項:作爲Visual Studio 2012中的代碼覆蓋工具的作者,它使用一堆技巧動態地重寫第三方x86/x86-64代碼來收集覆蓋率數據,這個東西是哦,所以 - 很有趣的破解和思考:)