逆向實用乾貨分享,Hook技術第一講,之Hook Windows API

來源:互聯網
上載者:User

標籤:堅持   http   跳轉   模組   mod   利用   五個   tar   五步   

             逆向實用乾貨分享,Hook技術第一講,之Hook Windows API

IBinary
出處:http://www.cnblogs.com/iBinary/
著作權,歡迎保留原文連結進行轉載:)

一丶什麼是Hook,以及Hook能幹啥

首先這一個小標題主要介紹神馬是Hook,如果知道的,則不用看了.

這裡我偷襲啊懶,貼出Hook的意思  https://baike.baidu.com/item/%E9%92%A9%E5%AD%90%E7%A8%8B%E5%BA%8F

Hook,英文單詞中成為鉤子,鐵鉤的意思,在我們編程中就是掛鈎的意思

我們要HookApi,則是要把這個API進行掛鈎,讓其執行我們的代碼,然後執行完我們的代碼之後,在執行API的代碼,當然執行不執行使我們說了算.

二丶Hook API的原理,以及思路

現在我們要知道我們要怎麼Hook API

假設我們程式現在要調用一個MessageBox函數,那麼我們把這個API Hook了,變為我們的API去執行,執行完我們的代碼之後再去執行它的的函數.

具體看下我們的草圖:

其實相當於就是我們在這個API之前,跳轉到我們的函數執行了,然後跳轉之後,我們執行完畢之後,可以選擇是否在跳回去,但是這裡注意,跳回去則跳轉到msg的return處位置即可.

eax可以給一個值,讓它返回.

利用這個技術,我們可以監控API,比如應用程式會調用loadLibrary,那我們把它Hook了,把Dll路徑改成我們的,那載入的就是我們的dll了,當然 Hook的API很多,因為只要是Windows的API都能HOOK

因為JMP的時候佔五個位元組,而WindowsAPI也是頭部弄了五個位元組,猜想可能是Windows自己留作Hook的.

三丶Hook的步驟(Hook自己)

首先說下步驟

/*思路:    我們要擷取MessageBoxA的函數地址,在擷取之前我們要進行下面幾個步驟1.調用GetModuleHandlle,擷取Dll模組(user32.dll的)的基地址2.通過基地址,調用GetProcAddress獲得Msg的函數地址3.修改Msg函數地址的保護屬性,調用virtualProtect4.重定位跳轉地址 Dest - MsgCode = offset -5     jmp 跳轉到這個位移即可5.跳回來的時候則是 dest + offset + 5 = Msgcode +5的位置*/

看上面,很暈,一步一步代碼實現.

注意: 這裡只是簡單實現,並且說下思路,代碼複製過去你不能運行,因為比如下方,我寫 offset g_szUser32...等等的,

其實都是在.const中定義的,最下面會貼出完整代碼,那麼是可以啟動並執行.

第一步,獲得Msg的地址,首先調用GetModuleHandle
;1.獲得Msg的地址,先調用GetmoudulHandle    invoke GetModuleHandle,offset g_szUser32        ;獲得模組地址
   mov @hUserHand,eax                     ;傳回值給局部變數儲存
;其中g_szUser32在常量區是 user32.dll的字串
第二步:通過模組地址,獲得Msg函數的地址
invoke GetProcAddress,@hUserHand,offset g_szMsgNamemov @MsgProcAddrs,eax
;代碼同上
第三步:修改Msg函數地址的記憶體保護屬性,方便一會我們把JMP的二進位寫進去好修改
invoke VirtualProtect,@MsgProcAddrs,1000h,PAGE_EXECUTE_READWRITE,addr @hOldProtect
修改大小是1000(4096)個位元組
許可權是 可讀可寫可執行
是否儲存舊的許可權屬性: 是 ,這裡必須儲存,雖然你不用,否則API會失敗
還有就是,因為要儲存以前的,所以我們必須把地址給他,要加上Addr才可以
第四步: OD查看Msg位置,尋找5個位元組位置

這個時候我們可以在我們的代碼中寫個int 3,開啟的時候OD會斷下,我們在GetprocAddress的位置下斷點,

看下擷取到的Msg的地址是多少

我們在反組譯碼視窗中跟隨到Msg的位置.

可以看到的位置,剛好五個位元組, mov edi,edi是沒用的指令,但是windows還是保留了

也就是說可能就是以為了自己去監控API留下的.那麼這個時候我們可以在這個位置,寫入

JMP的指令  JMP  我們的API位置

我們如果跳轉到我們API的位置後,執行的代碼前邊這三條還是這個,因為一會我們還要在跳轉到當前的MSG + 5

的位置處繼續執行,(當然,隨你便,你也可以跳轉到Msg的Return位置)

第五步: 寫入Jmp,JMP到我們的函數的位置

首先我們知道 JMP的二進位是 E9 

所以我們要 E9  xxxxxx   xxx使我們函數的地址

但是JMP 的時候,這個地方是個位移

那麼我們要JMP到我們函數的位移位置,就要進行地址重定位了.

怎麼重定位,很簡單,小學數學

計算Msg的下一條執行的位置

code + offset = dest  當前的Msg的下條位置計算 帶入則是  7595FDAE + 5 = 7595FDB3 也正好是我們跳回來的位置

計算跳轉到我們函數地址

dest - code = offset  目標地址我們知道,就是我們的函數地址,開始跳轉的地址也知道了,所以帶入帶

我們的函數地址 - Code(當前的Msg地址) = offset 位移,那麼 JMP 這個位移即可.

定義我們的函數

函數寫成下面的那樣

最下面的label中的內容則是 JMP 00000000 其中這個地址是我們要重定位寫進去的

第六步:實現代碼,寫入JMP

從這裡開始我直接寫實現代碼了

   mov eax,@MsgProcAddrs       ;code    mov ebx,NewMsgBox           ;dest    sub ebx,eax                 ;dest - code = offset    sub ebx,5                   ;得出的位移需要-5,別忘了jmp佔五個位元組,這樣才可以跳轉到你的地址執行    mov [eax],byte ptr 0e9h     ;寫入Jmp    mov [eax +1],ebx            ;寫入跳轉的地址

首先獲得msg的位置,也就是Code

然後獲得 自己函數的位置,也就是Dest

現在我們要求出中間的位移是多少 dest - code = offset

然後因為JMP跳轉要佔五個位元組,所以接著-5個位元組大小

現在我們要把Msg函數的位置,改為JMP,我們要JMP我們的地址,我們看下OD分析

1.首先找到Msg函數位置,看下資料視窗中跟隨

2.單步走,然後執行到第一個把二進位改為E9H的地址

現在我們接著反組譯碼視窗中去看看Msg的地址,看下是否改為了JMP了

現在是改為了JMP,但是位移是不對了,不過我們的位移已經計算出了了,所以寫到E9後面即可

3.修改位移OD查看.

,反組譯碼視窗中看下Msg

,現在顯示不知是否正確,那麼我們現在去反組譯碼視窗中看下00401000是不是我們的NewMsg位置

可以看出,代碼正是我們寫的.

 

也正好是JMP 000000000的位置,那麼我們就可以在我們的代碼中寫了,劫持真正的MsgBox函數的執行

我們知道, 因為是jmp過來的,所以ebp - c 還是Msg的第二個參數,我們把裡面的內容改了

注意,這個在劫持代碼裡面寫.

四丶我們還有修改跳回來的位置,這個是同理了

看下代碼:

 invoke VirtualProtect,label1,1000h,PAGE_EXECUTE_READWRITE,addr @hOldProtect    mov eax,offset label1           ;code 我們要修改的地址是標號的地址,所以他是code    mov ebx,@MsgProcAddrs           ;dest 我們要跳轉到Msg的地址,所以他是Dest    sub ebx,eax                     ;dest - code = offset  帶入公式咋得到ebx是位移    mov [eax +1],ebx                ;eax標號的位置+1後面,也就是JMP 00 00 00 00 把00 00 00 00 寫成位移,咋跳回來Msg的位置繼續執行    invoke MessageBoxA,NULL,offset g_szMsgTitle,NULL,MB_OK 

第一,我們要修改的跳轉位置是標號1的位置,所以他是code

第二,我們要跳轉到哪裡,所以他是dest

第三,根據公式, dest - code = offset 求得了位移

第四,我們把dset +1的位置,也就是JMP 00 00 00 00  修改位了位移,咋又跳回來了.

看下OD分析

看下OD,我們也可以看出,我們單步走,單步走到 mov dword ptr[eax +0x1]的位置,看下是否把標號1的位移修改了

在記憶體中我們已經看到了,我們的位移修改了.

那麼我們反組譯碼視窗看下,當前我們的API ,也就是JMP 00 00 00 00 的位置是否修改了

可以看出,確實修改了,那麼我們看下JMP 後面的地址是哪裡把

正好使我們調用MsgBox的位置 +5的下面,也就是說,上面JMP到我們的API執行了,下面咋通過JMP有跳回來了,此時因為我們已經儲存了 棧底環境,所以運行是沒有出錯的

看下不調試,正常運行

通過HOOK技術,我們把本來應該輸出 Hello 看雪,變成了我們自己想要的字串.

因為代碼是RadAsm工程的,所以這裡打包發到百度雲端硬碟

 

連結:http://pan.baidu.com/s/1kVBWalp 密碼:luz8

IBinary
出處:http://www.cnblogs.com/iBinary/
著作權,歡迎保留原文連結進行轉載:)

如果覺著好,請推薦,加關注,如果覺著哪裡寫的不好,請批評改正.謝謝大家.如果看不懂,請評論一下給點動力,其實寫部落格最主要的還是自己整理,每天都堅持.把最好的獻給大家.

逆向實用乾貨分享,Hook技術第一講,之Hook Windows API

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.