欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > win32相关(IAT HOOK)

win32相关(IAT HOOK)

2025/6/8 18:37:39 来源:https://blog.csdn.net/weixin_43754657/article/details/148491749  浏览:    关键词:win32相关(IAT HOOK)

IAT HOOK


什么是IAT Hook?

IAT Hook(Import Address Table Hook,导入地址表钩子)是一种Windows平台下的API钩取技术,通过修改目标程序的导入地址表(IAT)来拦截和重定向API调用

在我们之前学习pe文件结构的导入表时,有讲到过IMAGE_IMPORT_DESCRIPTOR这个结构体,其中有个FirstThunk参数,这个参数是指在程序运行中,存放着要执行的函数地址

在这里插入图片描述
我们在调用MessageBox这类的函数时,在程序运行时,会把函数的地址放到IAT表当中,我们就是通过修改这个执行的地址来达到我们Hook的目的

我们来代码实践一下

注入的dll模块

#include<iostream>
#include<windows.h>#ifdef _WIN64
#define IMAGE_ORDINAL_FLAG 0x8000000000000000
#else
#define IMAGE_ORDINAL_FLAG 0x80000000
#endifPDWORD_PTR g_pIatEntry = NULL;      // 指向IAT条目
DWORD_PTR g_origMessageBoxW = 0;    // 原始函数地址
DWORD g_dwOldProtect = 0;// 编写我们要替换的函数(hook的函数)
int WINAPI HookMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType) {return MessageBoxA(hWnd, "MessageBox已被Hook!", "HOOK", uType);
}// 安装钩子
BOOL InstallHook() {if (!g_pIatEntry) return FALSE;// 保存原始地址g_origMessageBoxW = *g_pIatEntry;// 修改内存属性,改为可以读可以写,可以执行VirtualProtect(g_pIatEntry, sizeof(PDWORD_PTR), PAGE_EXECUTE_READWRITE, &g_dwOldProtect);// 这里填写我们想要替换的函数的地址*g_pIatEntry = (DWORD_PTR)HookMessageBoxW;// 还原之前的内存属性VirtualProtect(g_pIatEntry, sizeof(PDWORD_PTR), g_dwOldProtect, NULL);return TRUE;
}
// 卸载钩子
BOOL UnInstallHook() {if (!g_pIatEntry || !g_origMessageBoxW) return FALSE;// 修改内存属性,改为可以读可以写,可以执行VirtualProtect(g_pIatEntry, sizeof(PDWORD_PTR), PAGE_EXECUTE_READWRITE, &g_dwOldProtect);*g_pIatEntry = (DWORD_PTR)g_origMessageBoxW;// 还原之前的内存属性VirtualProtect(g_pIatEntry, sizeof(PDWORD_PTR), g_dwOldProtect, NULL);return TRUE;
}PDWORD_PTR GetIatAddr(PCSTR dllName, PCSTR dllFunName) {// 获取当前进程的模块句柄HMODULE hModule = GetModuleHandle(0);DWORD_PTR dwHModule = (DWORD_PTR)hModule;// 获取DOS头PIMAGE_DOS_HEADER pDOsHeader = (PIMAGE_DOS_HEADER)dwHModule;// 获取NT头PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(dwHModule + pDOsHeader->e_lfanew);// 获取可选PE头PIMAGE_OPTIONAL_HEADER pOptHeader = (PIMAGE_OPTIONAL_HEADER)&pNtHeader->OptionalHeader;// 获取数据目录表PIMAGE_DATA_DIRECTORY pDataDir = (PIMAGE_DATA_DIRECTORY)&pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];// 在硬盘中需要转换,在内存中不需要转换 获取导入表地址PIMAGE_IMPORT_DESCRIPTOR pImageImportTable = (PIMAGE_IMPORT_DESCRIPTOR)(dwHModule + pDataDir->VirtualAddress);// 遍历导入表获取符合条件的函数while (pImageImportTable->Name) {PCHAR iatDllName = (PCHAR)pImageImportTable->Name + dwHModule;// 找到了我们需要的Hook的dllif (_stricmp(dllName, iatDllName) == 0) {// 获取导入名称表 获取函数名称PIMAGE_THUNK_DATA pThunkINT = (PIMAGE_THUNK_DATA)(dwHModule + pImageImportTable->OriginalFirstThunk);// 获取导入地址表 获取函数地址PIMAGE_THUNK_DATA pThunkIAT = (PIMAGE_THUNK_DATA)(dwHModule + pImageImportTable->FirstThunk);while (pThunkINT->u1.Function) {// 判断是不是按名称来导入的if ((pThunkINT->u1.Ordinal & IMAGE_ORDINAL_FLAG) == 0) {PIMAGE_IMPORT_BY_NAME pImageImportByname = (PIMAGE_IMPORT_BY_NAME)(pThunkINT->u1.Function + dwHModule);// 忽略大小写比较方法名称if (strcmp(dllFunName, pImageImportByname->Name) == 0) {// 找到到函数了返回函数地址return (PDWORD_PTR)pThunkIAT;}}pThunkINT++;pThunkIAT++;}}pImageImportTable++;}
}BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwCallReason, LPVOID lpReserved) {if (dwCallReason == DLL_PROCESS_ATTACH) {// 获取ida表函数地址g_pIatEntry = GetIatAddr("user32.dll", "MessageBoxW");InstallHook();}else if (dwCallReason == DLL_PROCESS_DETACH){// 进程退出时卸载钩子UnInstallHook();}return TRUE;
}

我这边提前写好了一个小程序,就是点按钮弹出一个MessageBox消息出来

在这里插入图片描述

我们来Hook掉弹窗中的内容

用到我们之前写dll注入的程序,执行一下

在这里插入图片描述
可以看到,我们已经返了我们修改后的弹窗

注:在MFC或者其他的库中,弹窗的函数可能实际上并不是MessageBoxW,像MFC是对MessageBox又做了一层封装,导致我们Hook不到

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词