win7 64bit下遠程線程注入技術(進程劫持入門技術)

http://blog.csdn.net/arvon2012/article/details/7766439

本文是配合上文學習和使用的。上文中,最後,我們生成了可以hook api的dll,那麼怎麼把它發射到其他進程中,讓其他進程調用運行我們的dll呢?

遠程線程注入技術可以解決這個問題。

 

原理:

遠程線程注入是這樣的,首先在當前運行的進程中找到目標進程,然後將我們的dll的內容寫入目標進程的私有空間中,最後通過關鍵的API:CreateRemoteThread創建線程。該線程只執行一個任務:loadlibrary加載我們的dll。

下面通過實例解釋,例子中注入的進程是“explorer.exe”(個人認爲玩弄這個進程異常的舒爽~~~~吼吼吼吼~~~~~~)

 

 

具體實現:
1.找到目標
原理簡單,我們首先獲得目前時刻正在運行的進程的列表,然後通過遍歷搜索,找到列表中我們想要的進程,然後記錄下進程的ID號。
hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
這個函數用來獲得當前進程的快照。(啪!說人話!)哦,就是獲得當前進程的列表啊。

然後通過下面的代碼按順序遍歷這個列表,通過字符串對比,找到我們的目標:explorer.exe。上代碼!


 

//獲取目標進程的ID
 if(Process32First(hProcessSnap,&pe32))   //獲取第一個進程 
 { 
  do{ 
   char te[MAX_PATH]; 
   strcpy(te,pe32.szExeFile); 
   if(strcmp(te, INJECT_PROCESS_NAME) == 0)
   { 
    dwRemoteProcessId=pe32.th32ProcessID; 
    printf("%d\n",dwRemoteProcessId);
    break; 
   }     
  }     
  while(Process32Next(hProcessSnap,&pe32));//獲取下一個進程 
 } 
 else 
 { 
  return   -1; 
 } 


找到目標進程後,用dwRemoteProcessId記錄下進程ID。還是一樣,大家不用深究看不懂的變量(畢竟變量搞懂也沒大意思),先看清原理,完整的代碼會在最後給出下載地址。
上面這個代碼段中關鍵函數分別是Process32First,Process32Next兩個可以沿着列表搜索的函數還有一個字符串對比函數strcmp覈對當前搜索的進程對象的名稱是不是explorer.exe。

 

 

2.打開進程,把我們的dll寫進去!
(1)打開
在上一步獲得目標進程的id後我們就可以打開進程,然後對進程進行操作。打開進程如下:
hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, dwProcessId);
參數中的第一個是表明我們在打開進程的時候想要獲得的權限,第三個是目標進程的ID。成功打開後,我們用hProcess存放打開的句柄。句柄嘛,大家都懂的,windows裏都是用句柄訪問和操作對象的嘛~~

(2)寫入
既然要往目標進程的私有空間寫入數據,我們就要先在目標進程中申請和我們的dll一樣大,或者更大的空間。申請如下:
pszLibRemoteFile   =  VirtualAllocEx(hProcess,NULL,cb,MEM_COMMIT,PAGE_READWRITE);
參數中的cb是我們想要申請的尺寸,最後一個參數是讀寫權限。
我們怎麼獲得cb呢?look:

int   cch   =   1   +   lstrlenW(lpwLibFile); //這裏的lpwLibFile其實就是我們的dll
int   cb   =   cch   *   sizeof(WCHAR); 



上面第一步得到的是我們dll的文件尺寸,單位是“個”,代表我們的文件有cch個字符。
第二步得到真正的字節大小,我們把字符數乘以每一個寬字符所佔的字節空間即可。這裏爲什麼是寬字符?是windows文件都是寬字符形式嗎?還是。。。不也不懂,大家一起查查,知道了別忘告訴我下,先謝過各位親~~~

空間申請好了,空間的首地址用pszLibRemoteFile存着,然後就可以寫數據了:
WriteProcessMemory(hProcess,   pszLibRemoteFile,(PVOID)lpwLibFile,   cb,   &dwWritten);
這個沒啥好解釋的,就是一個寫內存的API。

至此在目標進程中已經有了我們dll邪惡的身影,最後當然是逼着目標進程加載我們的dll(不加載就是垃圾數據佔空間來的,難道佔空間也是一種攻擊方式???額。。。)

 

 

 

3.加載
windows允許我們做什麼,我們就以什麼爲突破口。
windows提供給我們一個API叫做CreateRemoteThread。。。。說實話,微軟爲什麼要給程序員這中完全不安全的API,我不能猜到內幕。只能壞笑着說“微軟~~~你真壞”
不過這裏要說下,win7沒那麼好欺負,直接調用CreateRemoteThread好像不行,我沒有認真研究具體是哪裏被拒絕了,不過網上找到資料,這個函數最終會調用NtCreateThreadEx。
呵呵,各位菜鳥朋友們,當大家看到nt開頭的函數應該很興奮吧,對windows來說,對幾乎所有的API調用最後都會調用對應nt開頭的API,這些是底層的函數,既然win7不讓我們創建線程,那我們自己強行調用這個nt函數。
這裏真的有點像hook api裏的操作:
找到NtCreateThreadEx所在dll,然後從這個dll中獲得NtCreateThreadEx的位置,然後定義一個返回值和參數表和NtCreateThreadEx一樣的函數的指針存放NtCreateThreadEx的地址,直接調用指針指向的位置裏存放的代碼(廢話一堆。。其實就是用地址調用了NtCreateThreadEx)。
程序如下:

pFunc = GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtCreateThreadEx");  
  //下面就是用地址執行了NtCreateThreadEx
  ((PFNTCREATETHREADEX)pFunc)(
   &hThread, 
   0x1FFFFF,  
   NULL,  
   hProcess,  
   pThreadProc,  
   pRemoteBuf,  
   FALSE,  
   NULL,  
   NULL,  
   NULL,  
   NULL);  



OK,目前線程能創建了,那麼別忘了我們付給這個線程的艱鉅使命:出賣它所屬的進程,調用我們的dll庫(這是擬人的修辭手法啊有木有!)
回頭看下這個創建線程的函數,裏面有個參數叫做pThreadProc,呵呵,能猜到吧,這裏放的就是線程起來後負責運行的程序。我們果斷把這個值附成LoadLibrary,然後在哪裏傳入LoadLibrary的參數呢?pRemoteBuf!新的線程會從這裏讀取它要執行的函數的參數。我們前面在寫入dll數據的時候不是記錄了一個地址嗎?那個地址變量不也是Buff嗎?把那個變量放到這個參數的位置就OK了。
我的程序裏這樣創建線程:
 MyCreateRemoteThread(hProcess, pfnThreadRnt,pszLibRemoteFile);
第二個參數在前面有個處理:
pfnThreadRnt   =   (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(L"Kernel32"), "LoadLibraryW");
懂了吧?嘿嘿。。
第三個參數是存了我們dll的buff頭指針。
當這個函數順利執行完的時候,我們dll的工作也順利完成了。

 

提醒下廣大和我一樣的菜鳥朋友,如果要把你的dll注入64位系統的explorer.exe,別忘了把dll編程成x64的,然後這個注入程序也編譯生成x64的可執行文件哦,否則會發現注入了木有任何反應哦~親~得意

 

本文的源碼在http://download.csdn.net/detail/arvon2012/4441040

技術相關更多文章猛擊:哇啦天堂論壇技術區

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章