一、Inline Hook 技术原理1.1 Hook 技术分类在 Windows 系统中,Hook 技术主要分为两类:
消息钩子:通过 SetWindowsHookEx拦截 GUI 消息
代码级钩子:直接修改目标函数代码实现拦截
Inline Hook(内联钩子)属于代码级钩子,其核心原理是通过修改目标函数入口处的指令,将其重定向到自定义函数,从而实现拦截和篡改。
1.2 技术实现流程定位目标函数:获取函数内存地址(如 MessageBoxA)
修改内存保护:使用 VirtualProtect解除内存写保护
写入跳转指令:在函数头部插入 JMP指令跳转到自定义函数
构建跳板逻辑:在自定义函数中处理参数并选择性调用原函数
恢复现场:执行完毕后跳转回原函数继续执行
1.3 典型跳转指令架构指令字节说明x86E9 [Offset]近跳转(4字节偏移)x64FF 25 [RIP+0]远跳转(8字节绝对地址)通用68 [Addr] C3PUSH + RET 组合跳转二、Inline Hook 实现详解2.1 基础实现代码(x86 示例)#include
#include
// 定义函数指针类型
typedef int (WINAPI* MessageBoxAPtr)(HWND, LPCSTR, LPCSTR, UINT);
// 原始函数指针和跳转备份
MessageBoxAPtr OriginalMessageBoxA = MessageBoxA;
BYTE originalBytes[5] = {0};
// 自定义处理函数
int WINAPI HookedMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) {
std::cout << "[Hook] 拦截到弹窗调用:\n"
<< "内容: " << (lpText ? lpText : "NULL") << "\n"
<< "标题: " << (lpCaption ? lpCaption : "NULL") << std::endl;
// 修改内容
return OriginalMessageBoxA(hWnd, "内容已被篡改", lpCaption, uType);
}
// 安装 Hook
bool InstallHook() {
// 获取函数地址
HMODULE user32 = GetModuleHandleA("user32.dll");
LPVOID targetFunc = GetProcAddress(user32, "MessageBoxA");
// 备份原指令
if (!ReadProcessMemory(GetCurrentProcess(), targetFunc, originalBytes, 5, NULL)) {
return false;
}
// 构造跳转指令 (E9 + Offset)
BYTE jmp[5] = {0xE9};
DWORD offset = (DWORD)HookedMessageBoxA - (DWORD)targetFunc - 5;
*(DWORD*)(jmp + 1) = offset;
// 修改内存权限
DWORD oldProtect;
if (!VirtualProtect(targetFunc, 5, PAGE_EXECUTE_READWRITE, &oldProtect)) {
return false;
}
// 写入跳转指令
if (!WriteProcessMemory(GetCurrentProcess(), targetFunc, jmp, 5, NULL)) {
VirtualProtect(targetFunc, 5, oldProtect, &oldProtect);
return false;
}
// 恢复权限
VirtualProtect(targetFunc, 5, oldProtect, &oldProtect);
return true;
}
// 卸载 Hook
void UninstallHook() {
HMODULE user32 = GetModuleHandleA("user32.dll");
LPVOID targetFunc = GetProcAddress(user32, "MessageBoxA");
DWORD oldProtect;
VirtualProtect(targetFunc, 5, PAGE_EXECUTE_READWRITE, &oldProtect);
WriteProcessMemory(GetCurrentProcess(), targetFunc, originalBytes, 5, NULL);
VirtualProtect(targetFunc, 5, oldProtect, &oldProtect);
}
int main() {
if (InstallHook()) {
MessageBoxA(NULL, "原始内容", "测试弹窗", MB_OK);
Uninst