使用 CreateRemoteThread 注入 DLL 來抓取封包. |
|
Skyer
高階會員 發表:43 回覆:111 積分:120 註冊:2002-04-04 發送簡訊給我 |
好久沒 po 文章了.. 最近研究某外掛,脫完殼後,寫了個小工具幫助分析。
此小工具使用 CreateRemoteThread 注入目標程式後,HOOK recv & send 達到抓封包的目的。 使用技術:
1. CreateRemoteThread
2. 分析 PE Format (去找出 recv & send 位置)
3. VirtualQuery & VirtualProtect (改變唯讀記憶體成可寫入)
4. HOOK API (這裡是 recv & send 兩個) 已知 bug:
退出時,偶爾目標程式會跟著結束 QQ 快照兩張
1. 程式介面
2. 注入後介面
--
Regards,
Skyer
------
-- Regards, Skyer |
Skyer
高階會員 發表:43 回覆:111 積分:120 註冊:2002-04-04 發送簡訊給我 |
嗯,來說明一下.. HOOK API 裡面的 ASM 部分.. 1. Hook send
因為在這裡是替換掉原 send 的入口位址成我們自己的(就是mySend)。
先來看一下 send 的宣告
function send(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;因為是採 stdcall 的參數傳遞動作,所以參數是由右至左,依序壓入堆疊。 所以在堆疊中是這樣的 (位址只是參考) 0000 return address (原呼叫 send 後要返回的位址) 0004 TSocket 0008 Buf 000C len 0010 flags 所以要取出 buf & len 的話,就是找 [esp 8] & [esp C], esp (StackPointer), 但在例子裡有點不一樣.. 來說明一下吧 /-------------Hook.pas - mySend---------------------------- procedure mySend; asm pushad pushfd mov eax, Form1 mov edx, [esp $2C] mov ecx, [esp $30] call TForm1.OnSend popfd popad jmp [SendFunc] end;\---------------------------------------------------------- pushad pushfd在這裡,因為我們是以非正常方式入侵. 所以第一動作就是保存現場,把所有暫存器 & 旗標壓入堆疊.. 也因為如此,原 send 的參數,就會位移 $20 (pushad), 4 (pushfd) 所以這裡,要取得 buf & len 就要位移 $24 即 [esp $2C] & [esp $30] mov eax, Form1 mov edx, [esp $2C] mov ecx, [esp $30] call TForm1.OnSend這一段其實就等於 Form1.OnSend(buf, len) Delphi 的參數傳遞預設使用 register 方式.. 由左至右傳 eax 是第一個 param, edx 第二個, ecx 第三個, 第四個後就壓入堆疊 在 class 中,第一個參數就是傳實體本身,跟 MFC 用 ecx 是一樣的.. 在來就是恢復現場 & 跳到原 send 去.. 2. Hook recv 這個就複雜了.. 因為不像 send, 在呼叫時,就可以攔來下了.. recv 得等原 recv 執行完後,才能取得封包..所以在這裡就是要想辦法先執行原 recv 後,在偷封包,最後還得跳回原 return address.. 看 code 來詳細解釋吧.. procedure myRecv; asm pop eax mov retAddr, eax mov eax, [esp 4] mov buf, eax call @@rethere @@rethere: pop eax add eax, 11 push eax jmp [RecvFunc] push eax pushad pushfd mov ecx, eax mov eax, Form1 mov edx, buf call TForm1.OnRecv popfd popad pop eax jmp [retAddr] end; pop eax mov retAddr, eax因為我們要先執行 recv, 所以得先把原 return address 替換掉才行。所以將原 return address pop 出來,備分到一個全域變數 retAddr 裡. mov eax, [esp 4] mov buf, eax再來,記下來 recv 的 buf 位址,等執行完原 recv 後,buf 就是封包了,在這裡不記 len, 因為實際的大小是依 recv 的回傳值決定 call @@rethere @@rethere: pop eax add eax, 11 push eax jmp [RecvFunc]前三行在病毒 or 殼中常用到.. 因為我們的 dll 是注入別的行程,所以我們無法確定 dll 會被載入到那個位址. 由前三行,eax 就會得到 "pop eax" 所在記憶體位址.. 把這值 11 (add eax, 11 & push eax & jmp [RecvFunc] 三個指令大小) 就可以替換掉原 return address,改成回到 jmp [RecvFunc] 下一行.. 11 我怎麼知道的呢? 在這裡我是先隨便放個值, compile 後,用 debug tool 載入來算的 XD 後面的就跟 send 一樣,就不說明了.. 以上是我替換 API 的方式, 是使用了 BASM (Delphi 內嵌的 ASM) 要怎麼用 pascal 來作呢.. 這我就不會了 XD -- Regards, Skyer
------
-- Regards, Skyer |
8866
中階會員 發表:27 回覆:147 積分:69 註冊:2002-10-14 發送簡訊給我 |
|
Skyer
高階會員 發表:43 回覆:111 積分:120 註冊:2002-04-04 發送簡訊給我 |
|
8866
中階會員 發表:27 回覆:147 積分:69 註冊:2002-10-14 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |