例:
hRemoteProcess = OpenProcess( PROCESS_CREATE_THREAD | //允許遠程創建執行緒
PROCESS_VM_OPERATION | //允許遠程VM操 作
PROCESS_VM_WRITE, //允許遠程VM寫
FALSE, dwRemoteProcessId )
由於我們後面需要寫入遠程進程的記憶體地址空間並建立遠程執行緒,所以需要申請足夠的許可權(PROCESS_CREATE_THREAD、VM_OPERATION、VM_WRITE)。
如果進程打不開,以後的操作就別想了。進程打開後,就可以建立遠執行緒了,不過別急,先想想這個遠執行緒的執行緒函式是什麼?我們的目的是注入一個DLL。而且我們知道用LoadLibrary可以載入一個DLL到本進程的地址空間。於是,自然會想到如果可以在目標進程中調用LoadLibrary,不就可以把DLL載入到目標進程的地址空間了嗎?對!就是這樣。遠執行緒就在這兒用了一次,建立的遠執行緒的執行緒函式就是LoadLibrary,而參數就是要注入的DLL的檔案名稱。(這裡需要自己想一想,注意到了嗎,執行緒函式ThreadProc和LoadLibrary函式非常相似,返回值,參數個數都一樣) 還有一個問題,LoadLibrary這個函式的地址在哪兒?也許你會說,這個簡單,GetProcAddress就可以得出。於是代碼就出來了。
char *pszLibFileRemote="my.dll";
PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("Kernel32"), "LoadLibraryA");
CreateRemoteThread( hRemoteProcess, NULL, 0, pfnStartAddr, pszLibFileRemote, 0, NULL);
但是不對!不要忘了,這是遠執行緒,不是在你的進程里,而pszLibFileRemote指向的是你的進程里的數據,到了目標進程,這個指針都不知道指向哪兒去了,同樣pfnStartAddr這個地址上的代碼到了目標進程里也不知道是什麼了,不知道是不是你想要的LoadLibraryA了。但是,問題總是可以解決的,Windows有些很強大的API函式,他們可以在目標進程里分配記憶體,可以將你的進程中的數據拷貝到目標進程中。因此pszLibFileRemote的問題可以解決了。
char *pszLibFileName="my.dll";//注意,這個一定要是全路徑檔案名稱,除非它在系統目錄里;原因大家自己想想。
//計算DLL路徑名需要的記憶體空間
int cb = (1 + lstrlenA(pszLibFileName)) * sizeof(char);
//使用VirtualAllocEx函式在遠程進程的記憶體地址空間分配DLL檔案名稱緩衝區
pszLibFileRemote = (char *) VirtualAllocEx( hRemoteProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
//使用WriteProcessMemory函式將DLL的路徑名複製到遠程進程的記憶體空間
iReturnCode = WriteProcessMemory(hRemoteProcess, pszLibFileRemote, (PVOID) pszLibFileName, cb, NULL);
OK,現在目標進程也認識pszLibFileRemote了,但是pfnStartAddr好像不好辦,我怎么可能知道LoadLibraryA在目標進程中的地址呢?其實Windows為我們解決了這個問題,LoadLibraryA這個函式是在Kernel32.dll這個核心DLL里的,而這個DLL很特殊,不管對於哪個進程,Windows總是把它載入到相同的地址上去。因此你的進程中LoadLibraryA的地址和目標進程中LoadLibraryA的地址是相同的(其實,這個DLL里的所有函式都是如此)。至此,DLL注入結束了。