API钩取技术研究(一)—— IAT Hook

IAT Hook

通过修改IAT的方式实现对Notepad的WriteFile()函数钩取,使得保存的文件中所有小写字母变成大写字母。

实验环境

VMware Workstation Pro 16.2.4 + Windows 7(32位)+ Microsoft Visual Studio 2010 Express,环境配置参考《VM安装windows7 32》

实验原理

  1. 钩取(Hooking)是一种更改程序流向,以获取程序运行时的信息或使程序具备新功能的技术它允许程序在运行时注入自己的代码,以便在特定的事件或条件下执行自己的逻辑
    • 一方面,Hook技术可以用于许多不同的应用程序场景,例如调试、性能分析、安全保护等。在计算机系统中,Hook技术通常用于调试和性能分析。例如,调试器可以使用Hook技术来捕获程序的运行时信息,例如函数调用、变量值等,以便开发人员可以更好地了解程序的行为。性能分析器可以使用Hook技术来监视程序的运行时行为,例如函数调用次数、CPU使用率等,以便开发人员可以优化程序的性能。Hook技术还可以用于安全保护。例如,防病毒软件可以使用Hook技术来检测和防止恶意软件的运行。Hook技术可以检测程序的行为是否异常,并采取相应的安全措施,例如终止程序的执行或采取防护措施。
    • 另一方面,它允许攻击者在运行时拦截和修改系统中的函数或API调用,从而影响系统的行为和安全性。Hook技术通常用于攻击和防御,例如在恶意软件中,攻击者可能会使用Hook技术来劫持系统中的API调用,从而绕过防御机制,或者在系统中植入恶意代码,从而影响系统的安全性和稳定性。Hook技术可以用于各种类型的系统,包括操作系统、应用程序、网络和通信设备等。
  2. Windows OS中,用户程序要使用系统资源(内存、文件、网络、视频、音频等)时无法直接访问这些资源都是由Windows OS直接管理的,出于多种考虑(稳定性、安全、效率等),Windows OS禁止用户程序直接访问系统资源(内存、文件、网络、视频、音频等) 。需要使用这些资源时,用户程序必须向系统内核( Kernel )申请,申请的方法就是使用微软提供的Win32 API(或是其他OS开发公司提供的API )。没有API函数,则不能创建出任何有意义的应用程序(因为它不能访问进程、线程、内存、文件、网络、注册表、图片、音频以及其他系统资源)。使用API函数时OS将会逐级向下调用系统函数,处理相关请求后,然后再返回到请求访问资源的线程。
  3. PE文件双桥结构、导入函数表INT、导入地址表IAT
    如图所示,在PE文件加载前,INT和IAT都指向IMAGE_IMPORT_BY_NAME。在磁盘中时,INT和IAT都一样,在内存中指向的是IMAGE_IMPORT_BY_NAME数组的RVA,存放着函数真实地址
    在这里插入图片描述
    但是在PE加载的时候,双桥结构会断裂,IAT 会被PE加载器重写,PE加载器先搜索INT,PE加载器迭代搜索INT数组中的每个指针,找出 INT所指向的IMAGE_IMPORT_BY_NAME结构中的函数在内存中的真正的地址,并把它替代原来IAT中的值。此时IAT中存放的就是函数的真实地址。
    PE中导入表,也就是IMAGE_IMPORT_DESCRIPTOR结构在一个数组中,意味着一个PE文件中可能有多个导入表,每个导入表中只有一个OriginalFirstThunk和FirstThunk,但是他们指向的IMAGE_THUNK_DATA是一个数组,数组的元素个数代表函数的个数,如果是IMAGE_THUNK_DATA中的AddressOfData字段生效,它指向的是一个IMAGE_IMPORT_BY_NAME数组,这个数组中的元素个数跟IMAGE_THUNK_DATA中的可能不一样,因为有的函数没有名字。
  4. 在进行IAT Hook之前需要根据IID结构体和ITD结构体找到想要Hook的原函数的地址(具体到代码实现就是两个for循环)。IMAGE_IMPORT_DESCRIPTOR(IID)结构体记录着PE文件要导入哪些库文件,每个导入的DLL都对应一个IID结构体,通过IID可以找到原函数在哪个DLL中被导入,该结构体定义如下:
    请添加图片描述
    INT和IAT指向一个相同类型的 IMAGE_THUNK_DATA(ITD)结构体数组,该数组以一个全0结构体结尾,该结构体与导入函数相对应,有多少个ITD结构体就有多少个函数被导入,通过修改IDT结构体中联合体u1成员变量Function的值为我们自己定义的钩取函数(如上图 PE装载后),即可实现IAT Hook,IDT结构体定义如下:
    请添加图片描述

实验过程

采用创建远程线程的方式注入dll

因为要操作目标进程Notepad.exe的内容,所以注入一个dll会比较方便,注入的dll会有目标进程的全部权限,而且也能很好的把Hook函数放到目标进程中去,代码注入也可以使用,但是实现过程比较困难,所以为简单起见我采用创建远程线程的方式注入dll,参考《DLL注入-创建远程线程》

编写hookiat.dll实现IAT Hook

在hookiat.dll中实现对Notepad.exe的IAT Hook操作。

DllMain()主函数的代码如下:

在这里插入图片描述

自定义钩取函数MyWriteFile()

自己定义钩取函数MyWriteFile()。若要将Notepad.exe中的小写字母修改为大写字母,在MyWriteFile()中修改第二个参数lpBuffer即可,然后将修改后的lpBuffer传入原来Notepad.exe的WriteFile()函数中,进行调用。
在这里插入图片描述

核心:hook_iat()函数实现IAT修改

这里需要弄清楚INT,IAT,IID结构体和ITD结构体这些概念以及它们之间的关系,并且了解PE结构基地址、虚拟地址(VA)、相对虚拟地址(RVA)的定义及换算公式,详见实验原理4和关于PE文件结构的参考博文。

① 寻找IID结构体表:

找Notepad.exe的IMAGE_IMPORT_DESCRIPTOR(IID)结构体表,它记录着PE文件要导入哪些库文件,每个导入的DLL都对应一个IID结构体。寻找IID结构体表,首先要获取Notepad.exe进程IMAGE_NT_HEADERS(NT头)的相对虚拟地址(RVA)。如图,通过PEview查看Notepad.exe文件结构,在IMAGE_DOS_HEADER中可以看到其基地址加上偏移0x3C(60字节)即为一个4字节的PE文件签名的偏移地址(NT头第一个部分)。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
IID表在PE文件结构中的RVA为0x160。IMAGE_NT_HEADERS的虚拟地址0x3c的基础加上0x80,就找到IID表的相对虚拟地址。
在这里插入图片描述
在这里插入图片描述

② 寻找ITD结构体实现IAT表修改
  1. 在IID结构体表中进行遍历寻找kernel32.dll对应的IID结构体(第一层循环)。
  2. 找到kernel32.dll对应的IID结构体后,可以通过访问结构体中的成员FirstThunk址,它指向kernel32.dll IAT的第一个IMAGE_THUNK_DATA(ITD)结构体,这样我们就找到了IDT表,有多少个ITD结构体就有多少个函数被导入。
  3. 在IDT表中进行遍历,找到要钩取的原始WriteFile() API函数对应的ITD结构体(第二层循环)。IDT结构的成员变量Function对应的是原始WriteFile() API函数在内存中的地址,只要修改Function的值为我们自定义的钩取函数新地址即可实现IAT Hook。需要注意的是由于Notepad.exe进程原有IAT内存区域是只可读的,所以修改Function的值之前要通过VirtualProtect()函数将相应的IAT的内存区域更改为可读写模式。
    在这里插入图片描述

实现演示

IAT-Hook演示

参考

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值