4.4 EAT Hook 挂钩技术
EAT(Export Address Table)用于修改动态链接库(DLL)中导出函数的调用。与IAT Hook
不同,EAT Hook是在DLL自身中进行钩子操作,而不是修改应用程序的导入表。它的原理是通过修改DLL的导出函数地址,将原本要导出的函数指向另一个自定义的函数。这样,在应用程序调用DLL的导出函数时,实际上会执行自定义的函数。
EAT Hook的步骤通常包括以下几个步骤:
- 获取目标DLL的基址:通过模块加载和遍历PE文件的导出表,找到目标DLL的基址。
- 定位导出函数:根据导出函数的名称或序号,在导出表中找到目标函数的位置。
- 保存原始函数地址:将目标函数的地址保存下来,以便后续恢复。
- 修改导出函数地址:将目标函数在导出表中对应的地址修改为自定义函数的地址。
- 实现自定义函数:编写自定义的函数,该函数会在被钩子函数被调用时执行。
- 调用原始函数:在自定义函数中,可以选择是否调用原始的被钩子函数。
与IAT不同是EAT存放的不是函数地址,而是导出函数地址的偏移,使用时需要加上指定Dll的模块基地址,当Hook挂钩之后,所有试图通过导出表获取函数地址的行为都会受到影响,EATHook并不会直接生效,它只能影响Hook
之后对该函数地址的获取。
实现导出表劫持的详细流程如下所示:
- 首先获取到DOS头,并加上偏移得到NT头,再通过Nt头得到数据目录表基地址。
- 数据目录表
DataDirectory
中的第0个成员指向导出表的首地址,直接拿到导出表的虚拟地址。 - 循环查找导出表的导出函数是否与我们的函数名称一致,一致则取出导出函数地址。
- 设置导出函数位置读写属性,将新的导出函数地址写入到该位置
根据上述流程,读者可以很容易的写出导出表劫持代码,如下所示则是完整的代码片段,当运行EATHook
时,进程内如果再次获取MessageBox
函数的内存地址时则会返回MyMessageBox
自定函数地址,此时功能将被替换。
#include <windows.h>
#include <cstdio>
#include <tchar.h>
// 导出表劫持
BOOL EATHook(LPCTSTR szDllName, LPCTSTR szFunName, LPVOID NewFun)
{
DWORD addr = 0, index = 0, dwProtect = 0;
// 装入模块
HMODULE DllBase = LoadLibrary(szDllName);
if (NULL == DllBase)
{
return(FALSE);
}
// 得到Dos头NT头数据目录表
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)DllBase;
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
PIMAGE_OPTIONAL_HEADER pOptHeader = (PIMAGE_OPTIONAL_HEADER)(&pNtHeader->OptionalHeader);
// 得到导出表的虚拟地址
PIMAGE_EXPORT_DIRECTORY pExpDes = (PIMAGE_EXPORT_DIRECTORY)
((PBYTE)DllBase + pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
// 获取导出表的函数地址,函数名称,函数序号
PULONG pAddressOfFunctions = (PULONG)((PBYTE)DllBase + pExpDes->AddressOfFunctions);
PULONG pAddressOfNames = (PULONG)((PBYTE)DllBase + pExpDes->AddressOfNames);
PUSHORT pAddressOfNameOrdinals = (PUSHORT)((PBYTE)DllBase + pExpDes->AddressOfNameOrdinals);
// 循环查找
for (int i = 0; i < pExpDes->NumberOfNames; ++i)
{
index = pAddressOfNameOrdinals[i];
// 得到导出函数名
LPCTSTR pFuncName = (LPTSTR)((PBYTE)DllBase + pAddressOfNames[i]);
// 对比函数名
if (!_tcscmp((LPCTSTR)pFuncName, szFunName))
{
// 返回地址
addr = pAddressOfFunctions[index];
break;
}
}
// 设置读写属性
VirtualProtect(&pAddressOfFunctions[index], 0x1000, PAGE_READWRITE, &dwProtect);
// 设置导出函数
pAddressOfFunctions[index] = (DWORD)NewFun - (DWORD)DllBase;
// 写出替换
WriteProcessMemory(GetCurrentProcess(), &pAddressOfFunctions[index],
(LPCVOID)((DWORD)NewFun - (DWORD)DllBase), sizeof(NewFun), &dwProtect);
return(TRUE);
}
// 自定义导出函数
int __stdcall MyMessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
{
printf("hello lyshark \n");
return(0);
}
typedef int (WINAPI* LPFNMESSAGEBOX)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);
int main(int argc, char *argv[])
{
// 对MessageBoxA进行Eat Hook
EATHook("USER32.dll", "MessageBoxA", MyMessageBox);
// 模拟下次调用后就是执行我们的Hook代码
LoadLibrary("USER32.dll");
HMODULE hDll = GetModuleHandle("USER32.dll");
LPFNMESSAGEBOX lpMessageBox = (LPFNMESSAGEBOX)GetProcAddress(hDll, "MessageBoxA");
lpMessageBox(NULL, "Hello, EAT Hook", "Info", MB_OK);
system("pause");
return(0);
}
上述代码被运行后,针对外部调用MessageBoxA
函数都会转向到MyMessageBox
函数上,至此传入的参数将会失效,如下图所示;
4.4 EAT Hook 挂钩技术的更多相关文章
- Android so注入( inject)和Hook(挂钩)的实现思路讨论
本文博客:http://blog.csdn.net/qq1084283172/article/details/54095995 前面的博客中分析一些Android的so注入和Hook目标函数的代码,它 ...
- 禁用copy on write实现全局EAT HOOK
以前写过一个,但是一不小心删除了,哎,就当再次复习复习吧. 首先抛出一个有意思的问题: 已知所有Windows可执行文件exe都会链接子系统ntdll.dll,那么真实内存中有几份ntdll.dll? ...
- pg3 bypass源码阅读 —— 学习x64内核hook跳板技术
如之前描述的 pg3复杂了许多 先来看看都要hook哪些点 1.hook dpc和定时器分发器,防止seh路线触发pg KiTimerListExpire,KiRetireDpcList 看一下hoo ...
- EAT/IAT Hook
标 题: EAT/IAT Hook 作 者: Y4ng 时 间: 2013-08-21 链 接: http://www.cnblogs.com/Y4ng/p/EAT_IAT_HOOK.html #in ...
- PE格式: 分析IatHook并实现
Ring 3层的 IAT HOOK 和 EAT HOOK 其原理是通过替换IAT表中函数的原始地址从而实现Hook的,与普通的 InlineHook 不太一样 IAT Hook 需要充分理解PE文件的 ...
- Windows Hook技术
0x01 简介 有人称它为“钩子”,有人称它为“挂钩”技术.谈到钩子,很容易让人联想到在钓东西,比如鱼钩就用于钓鱼.编程技术的钩子也是在等待捕获系统中的某个消息或者动作.钩子的应用范围非常广泛,比如输 ...
- Windows Dll Injection、Process Injection、API Hook、DLL后门/恶意程序入侵技术
catalogue 1. 引言2. 使用注册表注入DLL3. 使用Windows挂钩来注入DLL4. 使用远程线程来注入DLL5. 使用木马DLL来注入DLL6. 把DLL作为调试器来注入7. 使用c ...
- hook 9大类
HOOK技术主要分为两大类,一是内核层HOOK,一是用户层HOOK. 用户层HOOK也就是在ring3环境下hook kenerl32.dll.User3.dll.Gui32.dll.Advapi.d ...
- HOOK API (一)——HOOK基础+一个鼠标钩子实例
HOOK API (一)——HOOK基础+一个鼠标钩子实例 0x00 起因 最近在做毕业设计,有一个功能是需要实现对剪切板的监控和进程的防终止保护.原本想从内核层实现,但没有头绪.最后决定从调用层入手 ...
- windows、linux劫持技术
windows系统以下能够利用detours劫持 realse 模式劫持,调试的程序不能够 函数劫持能够实现的效果. 函数的劫持原理 我们怎样实现-detours detours是微软亚洲研究院出品 ...
随机推荐
- 【Django-Vue】手机号是否存在接口 多方式登录接口 腾讯云短信介绍和申请 api与sdk
目录 昨日回顾 今日内容 0 登录注册功能设计 1 短信登录接口 视图类 2 多方式密码登录接口 视图类 序列化类 路由 3 腾讯云短信介绍和申请 3.1api与sdk 补充 练习 昨日回顾 # 你的 ...
- Codeforces Round #544 (Div. 3)简单题解
复健,时间有限题解比较简陋 A. Middle of the Contest 将小时转成分钟,得到起止时间在一天中的分钟数,取平均值即可,复杂度O(1).平均值转换会时间的时候注意前导0. void ...
- SCA技术进阶系列(一):SBOM应用实践初探
现代软件都是组装的而非纯自研.随着开源组件在数字化应用中的使用比例越来越高,混源开发已成为当前业内主流开发方式.开源组件的引入虽然加快了软件开发效率,但同时将开源安全问题引入了整个软件供应链.软件组成 ...
- 森林消防智慧预警:火灾监测 Web GIS 可视化平台
前言 森林火灾是一种突发性强.破坏性大.处置救助较为困难的自然灾害.2021 年前三季度全国共发生森林火灾 527 起,受害森林面积约 2628 公顷,15 人死亡:发生草原火灾 12 起,受害草原面 ...
- 文心一言 VS 讯飞星火 VS chatgpt (181)-- 算法导论13.4 4题
四.用go语言,在 RB-DELETE-FIXUP 代码的哪些行中,可能会检查或修改哨兵 T.nil ? 文心一言: RB-DELETE-FIXUP 是红黑树中的一个操作,用于在删除一个节点后进行必要 ...
- 详解 Serverless 架构的 6 大应用场景
导读 Serverless 架构将成为未来云计算领域重要的技术架构,将会被更多的业务所采纳.进一步深究,Serverless 架构在什么场景下有优秀的表现,在什么场景下可能表现得并不是很理想呢?或者说 ...
- 斐波拉契序列的 Go 实现
本篇文章主要介绍斐波拉契序列的 Go 语言实现. 斐波拉契序列: 前面相邻两项之后构成后一项. 1. 循环迭代 package main import "fmt" const ma ...
- 京东App秒杀抢购流程接口分析(基于pypp技术)
App数据抓包必需工具 必需工具:小米手机,Charles,HttpCanary 从2022年2月后,京东只限于从app发起抢购,所以,网上的很多工具已经无效了.只能分析app端的底层协议和流程. g ...
- [java] JSP post 提交乱码 解决方案
//在post提交的页面顶部插入下列代码 <% request.setCharacterEncoding("UTF-8"); %>
- java - Array 数组反序输出
通过Array类的静态 sort() 方法可实现对数组排序,sort() 方法提供了许多种重载形式,可对任意类型数组进行升序排序. 然而,Array类中没有类似 js 的 reverse 反序输出 ...