通过修改PE加载DLL

一、准备工作

1、查看IDT中是否有足够空间

IDT地址(RVA)为84CC

在PEVIew中查看IDT,存在于rdata节区。已实现dll的导入项有kernel32.dll user32.dll gdi32.dll shell32.dll

将工具栏试图改为file offset,可以看到偏移为76CC,一直到772C

而下一个节区的开头是7730,所以整个IDT长度为76CC–772F

在HxD中查找查看

可以看到此区域数据,长度为64字节,有5个IDT结构体,其中一个为NULL结构体。从图可以看出IDT尾部存在其他数据,没有足够空间来添加myhack3.dll结构体

2、移动IDT

目标区域选择三种方式

  • 查找文件空白区域
  • 增加文件最后一个节区大小
  • 文件末尾添加新节区

首先查找空白大节区,在rdata节区中,从8C60–8DFF都是空白区域,也叫作Null-Padding区域。可以将原IDT区域移植到此处

并不是节区中所有区域都会无条件加载到进程虚拟内存,只有节区头中明确记录的区域才会加载。查看rdata节区头

节区头中存储着对应节区的位置、大小、属性等信息。整理如下

从中可以看出,rdata在内存和磁盘中的大小是不同的

Rdata节区在磁盘文件中的大小为2E00,在内存大小为2C56,剩余未被使用的区域大小为2E00 – 2C56 = 1AA > 64,所以在此空白区域创建新IDT是ok的。

选择其中足够区域

PS:Null-Padding区域需要通过分析节区头来确定这部分是否加载到内存中以及加载大小。

现在选定区域为8C80

pFile地址为7E80

二、修改exe文件

3、修改导入表RVA值

找到RVA值位置0160处,将84CC改为8C80,将长度64改为78(增加一个IID结构大小)

保存后,此时导入表位置变为8C80,长度变为78

4、解除绑定导入表

Bound Import Table(绑定导入表)是一种提高dll加载速度的技术

若想正常导入dll模块,绑定导入表需要添加信息或者可以不存在,此时各项值为0。

此时各项值已经为0,不需要继续修改

5、创建新IDT

将原来区域76CC-772F数据覆盖到新开辟的IDT区域,地址就在7E80(pFile)处

粘贴过来的是64字节大小的源数据,还需要加上IID头

根据IID头的定义

根据定义,在准确位置写入相关数据

6、设置Name、INT、IAT

之前设置的IID结构体有指向其他数据结构(INT、Name、IAT)的RVA值,还需要准确设置这些数据结构才能保证exe程序运行。也就是说,前边设置的只是目录,接下来需要写的才是正文。

其中RVA/RAW(RVA/pFile)的对应值如下

在相应的地址处填写值

修改的对应关系为

直接用教材中的图片更清晰些

各项意义:

1、INT是RVA数组,每个元素是一个RVA地址。RVA of INT值为8D00指向此地址INT,此地址值为8D30指向的是IAT值,也就是dummy。

而dummy是在myhack3.cpp中定义的一个外部接口函数名。

2、Name值 包含要导入的dll名称,如指向8D10地址的值为dll字符

3、IAT也是RVA数组,可以拥有与INT相同的值。函数运行时,PE装载器会将虚拟内存中的IAT替换为实际函数地址。

7、修改IAT节区属性值

加载PE文件到内存时,PE装载器会修改IAT,写入函数实际地址,所以相关节区一定要具有写属性(WRITE),这样装载器才能具有写入操作。查看rdata节区头

向原属性值0X4000 0040添加写属性IMAGE_SCN_MEM_WRITE(0x8000 0000),操作bit OR

即 0x4000 0040 OR 0x8000 0000 = 0xC000 0040

修改完后查看Characteristics属性值,可以看到已经添加上WRITE属性值

保存完成所有修改

三、验证

执行修改后的exe文件,可以运行

PEView查看文件IDT部分,可以看到添加的myhack3.dll部分

在Process Explorer中可以看到运行的1.exe程序中加载了myhack3.dll文件

本来有下载google index.html功能,由于众所周知的原因没有演示结果 :D

您可能还喜欢...