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 挂钩技术的更多相关文章

  1. Android so注入( inject)和Hook(挂钩)的实现思路讨论

    本文博客:http://blog.csdn.net/qq1084283172/article/details/54095995 前面的博客中分析一些Android的so注入和Hook目标函数的代码,它 ...

  2. 禁用copy on write实现全局EAT HOOK

    以前写过一个,但是一不小心删除了,哎,就当再次复习复习吧. 首先抛出一个有意思的问题: 已知所有Windows可执行文件exe都会链接子系统ntdll.dll,那么真实内存中有几份ntdll.dll? ...

  3. pg3 bypass源码阅读 —— 学习x64内核hook跳板技术

    如之前描述的 pg3复杂了许多 先来看看都要hook哪些点 1.hook dpc和定时器分发器,防止seh路线触发pg KiTimerListExpire,KiRetireDpcList 看一下hoo ...

  4. EAT/IAT Hook

    标 题: EAT/IAT Hook 作 者: Y4ng 时 间: 2013-08-21 链 接: http://www.cnblogs.com/Y4ng/p/EAT_IAT_HOOK.html #in ...

  5. PE格式: 分析IatHook并实现

    Ring 3层的 IAT HOOK 和 EAT HOOK 其原理是通过替换IAT表中函数的原始地址从而实现Hook的,与普通的 InlineHook 不太一样 IAT Hook 需要充分理解PE文件的 ...

  6. Windows Hook技术

    0x01 简介 有人称它为“钩子”,有人称它为“挂钩”技术.谈到钩子,很容易让人联想到在钓东西,比如鱼钩就用于钓鱼.编程技术的钩子也是在等待捕获系统中的某个消息或者动作.钩子的应用范围非常广泛,比如输 ...

  7. Windows Dll Injection、Process Injection、API Hook、DLL后门/恶意程序入侵技术

    catalogue 1. 引言2. 使用注册表注入DLL3. 使用Windows挂钩来注入DLL4. 使用远程线程来注入DLL5. 使用木马DLL来注入DLL6. 把DLL作为调试器来注入7. 使用c ...

  8. hook 9大类

    HOOK技术主要分为两大类,一是内核层HOOK,一是用户层HOOK. 用户层HOOK也就是在ring3环境下hook kenerl32.dll.User3.dll.Gui32.dll.Advapi.d ...

  9. HOOK API (一)——HOOK基础+一个鼠标钩子实例

    HOOK API (一)——HOOK基础+一个鼠标钩子实例 0x00 起因 最近在做毕业设计,有一个功能是需要实现对剪切板的监控和进程的防终止保护.原本想从内核层实现,但没有头绪.最后决定从调用层入手 ...

  10. windows、linux劫持技术

    windows系统以下能够利用detours劫持 realse  模式劫持,调试的程序不能够 函数劫持能够实现的效果. 函数的劫持原理 我们怎样实现-detours detours是微软亚洲研究院出品 ...

随机推荐

  1. Ubuntu20.04上安装MySQL8.0(绝对保证能够正常使用)

    今天在学习 Spark 连接 MySQL时发现还没安装,便参考了厦门大学实验室的Blog进行操作.但安装完成之后发现没有显示设置密码的选择,但又改不掉root密码(头开始痛起来). 故记录一下安装My ...

  2. P1525 关押罪犯 (并查集 / 二分图)| 二分图伪码

    原题链接:https://www.luogu.com.cn/problem/P1525 题目概括: 给你m对关系,每对关系分别涉及到x,y两人,矛盾值为w 请你判断分配x和y到两个集合中,能否避免冲突 ...

  3. 图解 Promise 实现原理(二)—— Promise 链式调用

    本文首发于 vivo互联网技术 微信公众号 链接: https://mp.weixin.qq.com/s/Xz2bGaLxVL4xw1M2hb2nJQ作者:Morrain 很多同学在学习 Promis ...

  4. 技术文档 | 在Jenkins及GitlabCI中集成OpenSCA,轻松实现CI/CD开源风险治理

    ​插播: OpenSCA-cli 现支持通过 homebrew 以及 winget 安装: Mac/Linux brew install opensca-cli Windows winget inst ...

  5. Synchronized的使用及原理总结

    本文为博主原创,未经允许不得转载 Synchronized的使用总结:   1.作用 原理 synchronized 的锁膨胀升级过程 对象的内存布局 锁的消除及逃逸分析 synchronized的方 ...

  6. 京东App秒杀抢购流程接口分析(基于pypp技术)

    App数据抓包必需工具 必需工具:小米手机,Charles,HttpCanary 从2022年2月后,京东只限于从app发起抢购,所以,网上的很多工具已经无效了.只能分析app端的底层协议和流程. g ...

  7. 15-触摸按键控制LED灯

    1.触摸按键 触摸按键可分为四大类:电阻式,电容式,红外感应式和表面声波式 电阻式触摸按键使用人体破压电阻,改变电阻,实现开关效果,耐用性差,很少使用 红外感应式是通过红外扫描的方式,一般使用在比较恶 ...

  8. 【Git】常用 Git 命令清单

    [来源]https://blog.csdn.net/hj7jay/article/details/53431717

  9. css - 隐藏body滚动条

    body::-webkit-scrollbar{ display: none; }

  10. 【转帖】10个Linux 系统性能监控命令行工具

    引言: 系统一旦跑起来,我们就希望它能够稳定运行,不要宕机,不出现速度变慢.因此,对于Linux 系统管理员来说每天监控和调试 Linux 系统的性能问题是一项繁重却又重要的工作.监控和保持系统启动并 ...