在远程进程中注入DLL钩挂IAT的方法
2014-08-23张钟
张 钟
(重庆理工大学,重庆 400054)
0 引言
在Windows系统的编程应用中,有时需要对某些API函数进行拦截,在拦截函数里执行自己的代码功能后,再返回原函数执行或者改变原函数操作行为等。拦截简称为钩子,可分为内核级和用户级钩子,内核级钩子有SYSENTER钩子、SSDT钩子、内联钩子、IRP钩子、LADDR 钩子、IDT 钩子、IOAPIC 钩子[1]等,实现起来较难,须具有0环权限;用户级钩子3环权限就可实现。用户级拦截API函数常用的方法有2种:一种是内联钩子,一种是导入地址表(Import Address Table,IAT)钩子。内联钩子的特点是将被拦截函数的首部的5个字节先保存起来,然后修改为JMP+钩子函数的偏移地址,待钩子函数代码执行完后,再将保存起来的5个字节写回原函数的首部,然后再执行原函数。这种方法的缺点是:(1)对硬件CPU有依赖性,不同的CPU其JMP指令是不同的;(2)在抢占式、多线程环境下根本不能工作。因为一个线程覆盖另一个函数起始位置的代码是需要时间的,在这个过程中,另一个线程可能调用同一函数,其结果将是灾难性的[2]。而导入地址表钩子不存在上述2个问题,方法简单,容易实现,而且程序也相当健壮。此外,在软件的加密、解密和反病毒应用中也往往涉及PE文件的IAT。当Windows装载器把PE文件装入内存时,会根据PE文件头中的导入表所记录的DLL名称,将DLL装入内存,以供PE文件使用DLL中的函数代码来实现程序的各种功能。当程序调用API函数时会首先在导入表中的IAT中查找该函数入口地址,找到后调用该函数。PE文件的导入表可分为2种结构形式:(1)导入表磁盘映像,可供查看导入表所记录的DLL名称和导入函数名称或序号;(2)导入表的内存映像,适用于钩挂导入地址表IAT。……
