遠程線程注入代碼

其他話暫且不說,直接新建個基於對話框的MFC項目出來。它長這樣的:

沒啥特殊的,上面的所有按鈕都不在此次使用。無非就是在系統中新建了個進程。接下來要上我們的主要代碼了。

一般情況下,操作系統會為我們每個進程分配一定的內存空間,兩個獨立的進程是不能相互訪問對方的內存空間的。那我們又想在對方進程中添加一些有意思的代碼去訪問它自己的數據,難道我們就沒啥辦法了么?看了龍哥的《如此HOOK》這篇文章,受到了啟發,採用遠程線程注入的方法,可以通過調用系統API在對方進程中申請一塊內存,代碼如下:

這段代碼第一行就是申請成功返回的內存地址(對方進程的地址),hProcess是我們通過系統調用打開的對方進程的句柄(對方進程就是上面那個MFCApplication1.exe)。注意申請的這一段內存一定要是可讀可寫可執行。為了證明這塊內存空間申請成功,下面上windbg這個調試器對MFCApplication1.exe進行調試,先attach上這個進程吧:

這個地址就是申請下來的內存首地址,先看下它內容吧。

因為還沒有將代碼寫上去,所以反彙編出來一堆奇怪的東西,好吧,現在把我們要注入的代碼寫上去。

再反彙編這段內存:

這個就是我們寫進去的,其實我們要寫的代碼在我們自己這個進程里其實是一個函數

這個函數很簡單,就調用MessageBoxA彈出一個對話框,函數參數再一個結構體內,由於結構體在我們程序里,但遠程進程里可沒有這個結構體,所以還需要在遠程進程開闢一段內存用來存儲代碼執行所需要的參數。

至此,代碼和數據都已經寫入了遠程線程了,讓我們來看看會發生什麼,

果然彈出了對話框,然後點擊確定,看看我們注入的這段代碼是不是運行的有始有終,點擊確定,不好,調試器中斷下來了,應該是捕獲異常了,

看到那個問號沒有,分明就不是代碼卅,異常很正常,但我們注入的都是代碼,彈出對話框之後應該結束的。咋會運行到一段奇怪的非代碼的代碼上去呢?

重啟項目,附上調試器。

看到沒有,代碼被注入到遠程進程的0x14f0000地址處,反彙編這段地址看看:

那我們就在這裡下個斷點,等它執行到此處。

單步執行,點擊彈出框的確定按鈕後,執行到此處:

我們發現後面還有個call,怎麼回事,不是只調用了一個MessageBoxA么。在VS裡面反彙編我們那個要注入的函數看看

看到沒有,在函數返回前確實還調用了一個__RTC_CheckEsp。E8就是call的機器碼,後面FF FF E7 9E就是相對地址了。絕對地址就是此處地址加相對地址再加5,注意這裡用的是補碼。

計算器運算得到的結果,由於是補碼,去掉前面那個1,跟小括弧裡面那個絕對地址是不是一樣呢,那麼這個絕對地址應該是我們這個進程的地址空間的。遠程進程的這個地址處是啥玩意,我們根本不知道,所以調用這一塊內存的代碼就基本會引發異常了,windbg看看遠程進程這一塊到底是個啥吧

一堆問號,根本不是代碼,所以異常了,那麼我們本來就沒有打算調用這個安全檢查函數,其實是編譯器自己加進去的,為了判斷sp有沒有被寫壞,我們其實可以指定編譯器不加這個安全檢查函數的,VS可以這樣設置

選擇默認就行,就不會加這個__RTC_Check_Esp了,重啟項目看看我們注入的那一段代碼被再次反彙編成啥了:

看看,是不是只有一個call指令了,其實那個[ebp-8]處的內容就是MessageBoxA函數的地址

到這裡基本上明白了遠程線程注入代碼的流程了吧! 還是要感謝@吉林-小伙,龍哥的那篇文章。
推薦閱讀:

TAG:軟體調試 | 代碼注入 |