空白区添加代码:
PE空白区表示PE文件按照对齐方式之后多出来的部分,可以是节与节之间的空白区也可以是节表与节之间的空白区,在图中是绿色部分。
步骤:
- 我们需要先知道这段代码对应的硬编码,例如如果想插入MessageBoxA函数,我们利用反汇编工具对该函数下断点,查看他对应的硬编码。
- 确定代码空白区,并确定他是否能容下这段代码
- 使用call指令E8 00 00 00 00,E8后面的4字节表示一个偏移值,表示当前指令地址与需要调用指令地址之间的偏移,我们可以使用需要调用指令地址减去当前指令地址再加上指令的长度5就得出这个偏移值。
- 然后使用JMP指令:E9 00 00 00 00跳回函数程序入口,E9后面的4个字节是程序入口地址减去当前地址再加上指令长度5得到。
- 将函数入口地址改为添加的代码的地址
完成之后,运行时的顺序是:函数入口(添加的代码的起始地址)——>call指令调用 MessageBoxA函数——>JMP指令跳到修改之前函数开始地址。
注意,添加代码是添加在内存对齐后的地址,而不是文件对齐地址。使用十六进制编辑器打开PE文件后的状态是文件对齐状态,所以需要转换成内存对齐的地址。
添加节:
步骤:
- 判断是否有空间添加节表。一个节表占40个字节,而在节表结束后需要有一段40字节的空节,加起来共80字节,所以需要确保原节表后面的空白区有80个字节的。
- 我们要添加的节是要可执行的,为了节省时间,我们可以先直接复制前面的节表,直接复制过来就不需要修改节属性了
- 此时节的数量增加了一个,所以需要改NumberOfSections,使其加1
- 将真实大小(VirtualSize)修改成文件对齐之后的大小0x1000(SizeOfRawData)
- 修改添加的节表成员的属性:名字、文件对齐之后的大小(0x1000)、内存中的偏移(第9个节的偏移地址0x17c00+其数据大小0x0c00)
- 修改文件中的偏移(第9个节的偏移地址0x17c00+大小0xc00)
- 修改一下SizeOfImage的大小(0x1F000加上0x1000)