查看PE文件的导入目录表(IDT)
1.查看PE文件的IDT,每一个DLL对应一个IID(20个字节,十六进制下为14),如果原IDT有足够空间,则可以直接在原IDT后面添加DLL,如果没有足够空间,那么需要将IDT迁移至程序空白区域。一个IDT包含多个IID,最后是一个20字节的空白区域,所以说足够空间的意思就是当你加入你自己的DLL之后,还要保证IDT后面有20字节的空白区域。
2.查看IDT的文件大小和映射大小,进行比较(文件大小-映射大小),如果有足够空间,则可以在IDT后面放入你需要加载的DLL,如果没有足够空间,则需要在最后一个节区扩展相应空间。
3.(假设现在IDT没有足够空间,那么我们要将原来的IDT迁移到新的空白位置),迁移新位置的时候一般是找相应节区,看该节区是否有空间放入IDT,再判断该节区是否有空间放入IDT时,要查看该节区头信息,确保该空白空间确实可用,具体是看该节区头的文件大小和映射大小的差是否足够大,够大就可以在该节区放入IDT。
在新空白区域放入IDT
1.修改原IDT的RVA和Size
在HXD中修改PE文件的IDT的RVA和Size,例如你要加入一个DLL,将Size的十六进制数据加上14(10进制的20个字节,一个IID),然后修改RVA为新的空白区域。
2.删除绑定导入表
将BOUND IMPORT TABLE的RVA和SIZE设置为0x0。
3.将原IDT复制到新的空白区域
复制到新区域后,在IDT的最后一个DLL和最后空白20字节之间添加你的DLL的信息,包括一个4字节INT的RVA,2个空的4字节,一个4字节的DLL名称的RVA,一个4字节的IAT的RVA,(总共20个字节,一个IID),这3个数据都是相对内存地址RVA。接着再在你刚才安排的INT的RVA处填写一个RVA,这个RVA才是真正的INT的内容;然后在你刚才写入的DLL名称的RVA处写入DLL的名称的机器码(可以用OLLYDBG,xDBG将字符串转换为机器码);最后在你刚才写入的IAT的RVA处写入IAT的内容的RVA,IAT内容的RVA可以跟INT内容的RVA相同。注:再写INT的内容时格式是:导入函数的Ordinal+导入函数的名称字符串(也就是0x00 00+名称字符串)。
修改IAT的属性值
加载PE文件到内存时,PE装载器会修改IAT,写入函数的实际地址,所以相关节区一定要有WRITE可写属性。查看PE文件的IAT所在节区的属性,如果不可写,那么我们手动更改属性值,将可读属性值0x40000040与可写属性值0x80000000执行按位或运算(bit OR),将属性值最终变为C0000040即可。