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

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.xdnf.cn/news/12566.html

相关文章:

  • 【RTSP从零实践】1、根据RTSP协议实现一个RTSP服务
  • STM32什么是寄存器
  • 24、std::hash
  • conda环境配置(一) —— 常用虚拟环境操作命令
  • 新时代AI发展,更好的做自己
  • 第1讲、包管理和环境管理工具Conda 全面介绍
  • VB.net复制Ntag213卡写入UID
  • [C++] list双向链表使用方法
  • 深入理解 Java 多线程:原理剖析与实战指南
  • 乐观锁与悲观锁的实现和应用
  • 统一点云数据格式:高效转换与属性保留
  • 微服务架构的性能优化:链路追踪与可观测性建设
  • 基于Python学习《Head First设计模式》第六章 命令模式
  • PHP 表单 - 验证邮件和URL
  • Java+Access综合测评系统源码分享:含论文、开题报告、任务书全套资料
  • 物联网智慧医院建设方案(PPT)
  • JMeter-SSE响应数据自动化2.0
  • # STM32F103 SD卡读写程序
  • JDK21深度解密 Day 15:JDK21实战最佳实践总结
  • Go语言堆内存管理
  • 如何在 Java 中优雅地使用 Redisson 实现分布式锁
  • ArcPy扩展模块的使用
  • 深入解析HarmonyOS5 UIAbility组件:从核心架构到实战应用
  • Clickhouse统计指定表中各字段的空值、空字符串或零值比例
  • uniapp- UTS 插件鸿蒙端开发示例 虽然我们这个示例简单 但是这个是难住很多人的一大步
  • 交互标牌——视觉货币(数字)转换器项目及源码
  • 企业微信授权登录(uniapp项目)
  • 零基础在实践中学习网络安全-皮卡丘靶场(第十六期-SSRF模块)
  • 第4章:Cypher查询语言基础
  • GenSpark vs Manus实测对比:文献综述与学术PPT,哪家强?