-
dll注入
鎖定
- 中文名
- dll注入
- 外文名
- DLL Rejection
- 意 義
- 將一個DLL放進進程的地址空間裏
- 方 法
- 打開目標進程
例:
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注入結束了。
- 參考資料
-
- 1. DLL動態鏈接庫編寫詳解 .李巖的博客[引用日期2013-03-20]
- 2. 經典DLL注入實例 .Rabbit's Blog[引用日期2012-07-14]