WinNT/Win2000/WinXP中的远线程技术之一
WinNT/Win2000/WinXP中的遠線程技術之一--DLL注入
??? 什么是遠線程?我們知道用CreateThread可以在當前進程里建立一個線程,遠線程與此類似,只不過是在其他進程中建立一個線程,用API函數CreateRemoteThread。這個遠線程建立后就與建立它的進程無關了,而是進入了另外一個進程。舉例說,進程A可以在進程B中建立一個遠線程,這個遠線程就是進程B中的線程了,而此時如果進程A結束了,也不會影響到那個遠線程的運行,除非進程B也結束了,那個遠線程才會結束。怎么樣,是不是很神奇啊?現在我們來看看怎么建立遠線程。
??? 最簡單的遠線程技術是DLL注入。好,先從這個講起。所謂DLL注入就是將一個DLL放進某個進程的地址空間里,讓它成為那個進程的一部分。要實現DLL注入,首先需要打開目標進程。
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注入結束了。
?
總結
以上是生活随笔為你收集整理的WinNT/Win2000/WinXP中的远线程技术之一的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DAGNN:有向无环图神经网络
- 下一篇: Siamese Network (应用篇