1. 程式人生 > 實用技巧 >在R3環自己實現快速呼叫WriteProcessMemory函式

在R3環自己實現快速呼叫WriteProcessMemory函式

這裡僅簡單講下原理和分析過程中的注意點,你先用已有的思路結合我的註釋大概理解一下這段實現程式碼:

 1 #include "stdio.h"
 2 #include "windows.h"
 3 
 4 void MyWriteProcessMemory(HANDLE hProcess,LPVOID lpBaseAddress,LPVOID lpBuffer,DWORD nSize,LPDWORD lpNumberOfBytesWritten)
 5 {
 6     _asm
 7     {
 8         lea eax,[ebp+0x18]
 9         push eax         //lpNumberOfBytesWritten

10 push [ebp+0x14]     //nSize 11 push [ebp+0x10]    //lpBuffer 12 push [ebp+0xc]    //lpBaseAddress 13 push [ebp+8]      //hProcess 14 sub esp,4        //平衡堆疊,因為在call NtWriteProcessMemory後,棧中會壓入一個4位元組資料(我們不用管這4位元組資料幹嘛的) 15 mov eax,0x115      //把服務號儲存在eax中 16 mov edx,0x7FFE0300    //獲取SystemCall中的地址
17 call dword ptr [edx] //呼叫SystemCall  
18 add esp,0x18      //本來這個call後面是跟retn 0x14的,我們是自己寫的程式,不能反悔到它那裡去,我們只需要平衡到這段程式碼執行之前的esp就行了 19 } 20 } 21 22 int main(int argc, char* argv[]) 23 { 24 char inBuffer[10] = "abcdefg";  //要寫入的資料 25 char strA[10] = {0};  //要寫入資料的緩衝區   26 SIZE_T size = 0
;    //接收實際的資料長度 27 MyWriteProcessMemory((HANDLE)-1,strA,inBuffer,9,&size);  //其實和WriteProcessMemory的引數一樣,我們採用這種方式來呼叫自己的函式,開頭的-1表示操作的程序是自己 28 printf("%s\n",strA);    //列印strA,如果寫入成功,會打印出上面的 abcdefg 29 getchar(); 30 return 0; 31 }

看完了估計你還是一頭霧水,不過不用擔心,因為這裡面的程式碼是通過 OllyDbg 逐個斷點分析堆疊後寫出來的,你自己分析一遍後就恍然大悟了。

我參考的文章是這篇:https://www.cnblogs.com/onetrainee/p/11704626.html,雖然他講的是 ReadProcessMemory 的實現,但 WriteProcessMemory 的分析思路和它完全是一模一樣的,建議先看下那篇文章再來讀下面的分析方法。總體來講,分析過程如下:

1.先正常的呼叫WriteProcessMemory函式,然後在OllyDbg中跟蹤它,看他執行到 NtWriteProcessMemory 時的堆疊是什麼樣的,觀察我們傳進去的每一個引數在棧中此時的位置

2.進入 NtWriteProcessMemory ,看下此時我們的棧又發生了什麼變化

3.根據引數在棧中的變化,以及分析執行完後棧要怎麼平衡回去才能讓我們的函式正常返回

當然,有什麼不懂的歡迎通過郵箱和我交流,筆者一定儘快回覆。