PE学习(15) 导入表注入DLL

简单写一个DLL项目,生成LIB和DLL文件回顾基础

在进程进入和退出的时候调用自己写的函数

dllmain.cpp

TestDLL.cpp

TestDLL.h

导出函数

编译后会生成一个LIB和DLL文件

 

测试LIB文件加载静态链接库,成功弹出三个计算器

(注意TestDLL.lib放在工作目录中)

 

测试DLL动态链接库,成功弹出三个计算器

 

注入导入表

当EXE被加载时,系统会根据EXE导入表信息来加载需要用到的DLL。导入表注入的原理是修改EXE导入表,将自己的DLL添加到EXE的导入表中,这样EXE运行时可以将自己的DLL加载到EXE的进程空间

第一步:拿到导入表信息(数据目录第二个)

第二部:计算新增节的大小

新增节存储的内容有:原来的所有导入表,新导入表,新INT和IAT表,模块名和一个_IMAGE_IMPORT_BY_NAME结构体,并且包含一个全0的结束标记

计算DLL的数量(导入表数量)

大小应该增加原有的部分再加一个新导入表和一个全0结束标记

计算一个IAT和INT表项,以及对应的结束标记(4个DWORD)

计算DLL名称长度(末尾是0)

_IMAGE_IMPORT_BY_NAME结构体大小为WORD Hint加字符串长度

增加新节,从pNewFileBuffer开始找到新节表地址,在新节的节表中设置属性为可读写含已初始化数据

拿到新节的PointerToRawData地址

将所有导出表复制到新节中

设置新增导入表的属性,时间戳设为0表示不使用绑定导入,其中ForwarderChain值一般需要设置为-1

设置导入表的结束标记,需要一个导入表的长度全部设为0

指定INT表插入点

设置INT表的结束标志

由于INT表只有一个元素,所以加8偏移得到IMPORT_BY_NAME

导出序号没有必要设置

函数名设置为开头写的DLL内导出的函数

而INT表这一项实际保存的值是IMPORT_BY_NAME的RVA

对应偏移后得到IAT表,将INT表直接复制过来即可(都指向IMPORT_BY_NAME

继续留出结束标志

紧接着偏移IAT表加结束标志之后的部分写入字符串

这个字符串是作为新导出表的Name部分的RVA

最后修改数据目录导入表的RVA指向最后节起始地址

 

测试

整体代码

 

随便找一个EXE并将新的FileBuffer写入新EXE

 

注意将DLL重命名为InjectDll.dll然后放在EXE同级目录,双击打开EXE截图