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;
}