当前位置: 首页 > article >正文

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不到

http://www.lryc.cn/news/2404392.html

相关文章:

  • 大模型高效提示词Prompt编写指南
  • 零基础玩转物联网-串口转以太网模块如何快速实现与TCP服务器通信
  • 十一、【ESP32开发全栈指南: TCP通信服务端】
  • ESP32开发之LED闪烁和呼吸的实现
  • 【产品业务设计】支付业务设计规范细节记录,含订单记录、支付业务记录、支付流水记录、退款业务记录
  • 2025软件供应链安全最佳实践︱证券DevSecOps下供应链与开源治理实践
  • Linux安装jdk、tomcat
  • WebRTC通话原理与入门难度实战指南
  • N元语言模型 —— 一文讲懂!!!
  • .NET 9中的异常处理性能提升分析:为什么过去慢,未来快
  • Mac 安装git心路历程(心累版)
  • 计算机网络第2章(下):物理层传输介质与核心设备全面解析
  • Qt Creator 11.0创建ROS2 Humble工程
  • C# 类和继承(扩展方法)
  • 机器学习复习3--模型的选择
  • MySQL复杂SQL(多表联查/子查询)详细讲解
  • STM32使用土壤湿度传感器
  • 在C++中,头文件(.h或.hpp)的标准写法
  • Axios学习笔记
  • Langchain学习笔记(十一):Chain构建与组合技巧
  • 【判断既约分数】2022-4-3
  • Windows平台RTSP/RTMP播放器C#接入详解
  • 深圳SMT贴片工艺优化关键步骤
  • 从 JDK 8 到 JDK 17:Swagger 升级迁移指南
  • 配置git命令缩写
  • Redis 缓存问题及其解决方案
  • 使用 Coze 工作流一键生成抖音书单视频:全流程拆解与技术实现
  • 【发布实录】云原生+AI,助力企业全球化业务创新
  • vue中的派发事件与广播事件,及广播事件应用于哪些场景和一个表单验证例子
  • DeepSeek 赋能智能养老:情感陪伴机器人的温暖革新