Inline Hook

IATHook的缺点:不在IAT表的函数没办法实现hook

Inline Hook(内联HOOK)

让正常程序执行的流程跳转到我们写好的代码中,执行完后再回到原始地址

硬编码

在计算机程序或文本编辑中,硬编码是指将可变变量用一个固定值来代替的方法。是用来给计算机看的

JMP的硬编码是E9

JMP 目标地址= E9 xxxxx

目标地址-JMP指令所在的地址 =xxxxxx+5

xxxxx 相当于目标指令距离JMP指令的下一个指令的偏移

Inline HOOK过程

1 找到要HOOK的函数地址

2 保存要HOOK函数的前五个字节

3 计算目标函数距离jmp指令的下一条指令的偏移offset

4 改变函数的前五个字节 改成 0xE9 offset

Inline HOOK总结

找到要替换的函数的地址,然后给该位置添加新的硬编码来跳转,相当于把原来的函数替换成了自己写的函数

Inline HOOK代码实现

#include"InlineTest.h"
/*
1 找到要HOOK的函数地址

2 保存要HOOK函数的前五个字节

3 计算目标函数距离jmp指令的下一条指令的偏移offset

4 改变函数的前五个字节 改成 0xE9 offset
*/

//1初始化函数 进行HOOK的初始工作,找到要HOOK的函数,然后保存前五个字节,计算出偏移量,保存改变后的前五个字节
//2安装钩子
//3卸载钩子
//4要替换的自定义函数
DWORD g_unhookfun = 0;//要修改的函数地址
char g_oldcode[5] = { 0 };//用来存放jmp指令的五个硬编码字节
char g_newcode[5] = { 0xE9,0,0,0,0 };//存放新代码的jmp硬编码

int WINAPI NewMessageBoxW(
_In_opt_ HWND hWnd,
_In_opt_ LPCWSTR lpText,
_In_opt_ LPCWSTR lpCaption,
_In_ UINT uType)
{
//1
UnStallHook();
int ret = MessageBoxW(NULL, L"inline HOOK成功", L"Inline HookTEST", MB_OK);
InitHook();
return ret;
////me
//int ret = MessageBoxA(NULL, "inline HOOK成功", "Inline HookTEST", MB_OK);
//return ret;
}
//初始化HOOK,找到HOOK函数,保存函数的前五个字节
//计算出偏移值,保存改变后的前五个字节
BOOL InitHook()
{
//找到要HOOK的函数地址
HMODULE hModule = LoadLibraryA("User32.dll");
if (hModule==NULL)
{
cout << "加载dll文件出错" << endl;
return false;
}
g_unhookfun = (DWORD)GetProcAddress(hModule, "MessageBoxW");
//把要修改的函数的前五个字节保存下来
/*memcpy(g_oldcode, (char*)g_unhookfun, 5);*/
DWORD oldProtect;
VirtualProtect((DWORD*)g_unhookfun, 5, PAGE_EXECUTE_READWRITE, &oldProtect);
for (int i = 0; i < 5; i++)
{
g_oldcode[i] = *((char*)g_unhookfun+i);
}
VirtualProtect((DWORD*)g_unhookfun, 5, oldProtect, &oldProtect);
//计算新函数的偏移
DWORD offset = (DWORD)NewMessageBoxW -((char)g_unhookfun + 5);
//保存新的函数的五个字节
//memcpy(&g_newcode[1], (char*)&offset, 4);
memcpy(&g_newcode[1],&offset, 4);
return TRUE;
}
//安装钩子
BOOL InstallHook()
{
//修改内存属性
DWORD oldProtect = 0;
VirtualProtect((DWORD*)g_unhookfun, 5, PAGE_EXECUTE_READWRITE, &oldProtect);
//修改函数前五个字节的内容
memcpy((DWORD*)g_unhookfun,g_newcode,5);

//改回去内存属性
VirtualProtect((DWORD*)g_unhookfun, 5, oldProtect, &oldProtect);
return TRUE;
}
//卸载钩子
BOOL UnStallHook()
{
//修改内存属性
DWORD oldProtect = 0;
VirtualProtect((DWORD*)g_unhookfun, 5, PAGE_EXECUTE_READWRITE, &oldProtect);
//修改函数前五个字节的内容
memcpy((DWORD*)g_unhookfun, g_oldcode, 5);

//改回去内存属性
VirtualProtect((DWORD*)g_unhookfun, 5, oldProtect, &oldProtect);
return TRUE;
}

BOOL WINAPI DllMain(HINSTANCE hInstance,DWORD CallReason,LPVOID lpReserved)
{
if (CallReason == DLL_PROCESS_ATTACH)
{
InitHook();
InstallHook();
}
else if (CallReason == DLL_PROCESS_DETACH)
{
UnStallHook();
}
return TRUE;
}