複製鏈接
請複製以下鏈接發送給好友

dll注入

鎖定
所謂DLL [1]  注入就是將一個DLL放進某個進程地址空間裏,讓它成為那個進程的一部分。要實現DLL注入,首先需要打開目標進程。
中文名
dll注入
外文名
DLL Rejection
意    義
將一個DLL放進進程的地址空間裏
方    法
打開目標進程
例:
hRemoteProcess = OpenProcess(PROCESS_CREATE_THREAD | //允許遠程創建線程
PROCESS_VM_OPERATION | //允許遠程VM操 [2] 
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注入結束了。
參考資料