1. 程式人生 > 其它 >Windows下64位程式的Inline Hook

Windows下64位程式的Inline Hook

有過32位hook的介紹,程式碼不是主要的,所以貼在最後,首先記述下原理。

主體程式碼還是參考與那本關於黑客技術的書,部分內容則參考自以下部落格。

https://blog.csdn.net/zuishikonghuan/article/details/47979603

原理:
mov rax,地址 push rax ret
64位程式中,jmp 貌似也只能跳轉4位元組的偏移,而程式的地址都是8位元組。所以單獨一條jmp指令不足以實現功能。

這也是原理上的不同。
rax是一個64位暫存器,首先把程式地址儲存到rax暫存器中。
隨後把rax暫存器的內容壓入棧中。
最後使用ret返回。
關鍵之處在於ret指令返回的地址就是棧頂裡面的內容。
所以ret後直接跳到了我們指定函式的地址中。

有了32位Inline Hook的經驗,我們對照著程式碼,使用x64dbg除錯(功能類似於OD,但是支援64位程式),會比較容易理解。

本次需要12位元組:
mov rax,地址 => 0x48 0xb8 + 8位元組地址 = 10位元組
push rax => 0x50 1位元組
ret => 0xc3 1位元組

當然了,要實現類似的效果還有很多其實方法,隨著學習的深入,以及對指令的熟悉,
舉一反三也就有跡可循了。
#include <stdio.h>
#include <windows.h>
#include <iostream>
using namespace
std; #define len 12 class MyHook { public: MyHook() { funcAddr = NULL; ZeroMemory(oldBytes,len); ZeroMemory(newBytes,len); } ~MyHook() { UnHook(); funcAddr = NULL; ZeroMemory(oldBytes,len); ZeroMemory(newBytes,len); }
/* *Hook的模組名稱,Hook的API函式名稱,鉤子函式地址 */ WINBOOL Hook(LPSTR ModuleName, LPSTR FuncName, PROC HookFunc) { BOOL bRet = FALSE; funcAddr = (PROC)GetProcAddress(GetModuleHandleA(ModuleName),FuncName); if(funcAddr!=NULL) { SIZE_T num = 0; ReadProcessMemory(GetCurrentProcess(),(void*)funcAddr,oldBytes,len,&num); for (int i = 0; i < len; i++) { printf("%0x ", oldBytes[i]); } cout << " finish" << endl; newBytes[0] = 0x48; newBytes[1] = 0xB8; newBytes[10] = 0x50; newBytes[11] = 0xC3; memcpy(newBytes+2,(void*)&HookFunc,8); for(int i=0;i<12;i++) { printf("%0x ",newBytes[i]); } cout<<endl; WriteProcessMemory(GetCurrentProcess(),(void*)funcAddr,newBytes,len,&num); cout<<"mytest"<<endl; bRet = TRUE; } return bRet; } void UnHook() { if(funcAddr!=0) { SIZE_T num = 0; WriteProcessMemory(GetCurrentProcess(),(void*)funcAddr,oldBytes,len,&num); } } WINBOOL ReHook() { BOOL ret = FALSE; if(funcAddr!=0) { SIZE_T num; WriteProcessMemory(GetCurrentProcess(),(void*)funcAddr,newBytes,len,&num); ret = TRUE; } return ret; } private: PROC funcAddr; BYTE oldBytes[len]; BYTE newBytes[len]; }; MyHook hook; int WINAPI MyMessageBoxA(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT type) { hook.UnHook(); MessageBox(hWnd,"Hook流程",lpCaption,type); MessageBox(hWnd,lpText,lpCaption,type); hook.ReHook(); return 0; } int main() { MessageBox(NULL,"正常流程1","test",MB_OK); hook.Hook((LPSTR)"User32.dll",(LPSTR)"MessageBoxA",(PROC)&MyMessageBoxA); MessageBox(NULL,"被Hook了1","test",MB_OK); MessageBox(NULL,"被Hook了2","test",MB_OK); cout<<"finish"<<endl; hook.UnHook(); MessageBox(NULL,"正常流程2","test",MB_OK); cout<<&MyMessageBoxA<<endl; }