文章

滴水-day22-PE空白区添加代码

手动在代码空白区添加代码

  1. 注意文件与内存对齐。

  2. 添加代码的地址是ImageBuffer中的偏移,而不是文件中的。

call(E8)跳转的地址不是真正的地址,而是由真正的地址经过运算得到的硬编码

call(E8) X (X是四字节)

X = E8 - (E8当前地址+5)

这些地址说的都是内存中的。

对于文件对齐与内存对齐不一样的程序在计算E8后面的位置和E9后面的位置的时候计算方式不再是直接加上ImageBase了。

由于对齐不同,需要计算文件地址在内存中的地址,也就是文件偏移到内存偏移

计算公式:

内存偏移 = (文件偏移(File Offset) - 该地址所在节的物理偏移(Raw Offset) + 该地址所在节的虚拟偏移(Virtual Offset)) + 基地址(ImageBase)

例如我的A程序

.text 00011000 00005509 00000400 00005600 60000020

我想要在5918处添加CALL MessageBox(76150F40)

那么CALL的地址计算方式就是:

((5918+5) - 0x400 + 0x11000) + 0x400000 = 41651D

76150F40 - 41651D = 75D3AA23

75D3AA23就是CALL的地址

JMP的计算方式与这个一样,都是计算文件偏移到内存偏移

PS:在计算call的地址时候尽量关闭程序的随机基地址,否者call的地址与实际地址不同

JMP不受影响

练习

PETool 1.0.0.5.exe文件注入代码

MessageBoxA地址:76150F40

E8 X

X = 76150F40 - (233E8 + 5 == 233ED - 1000 + 1000)+ 00400000 = 4233ED = 75D2DB53

004233ED

E8 53 DB D2 75

E9 X

X = 000193BE + 00400000 - (233ED + 5 - 1000 + 1000) + 00400000 = 4233F2 = FFFF5FCC

E9 CC 5F FF FF

修改OEP

233E0

小记

在修改OEP的时候,尽量使用相对虚拟地址而不是虚拟地址。

相对虚拟地址:虚拟地址 - 该地址所在节的物理偏移 + 该地址所在节的虚拟偏移

而在修改E8 E9后的地址的时候尽量使用虚拟地址,因为这些是需要直接运行的代码,也就是在内存中的状态而虚拟地址就是在内存中的状态

虚拟地址:相对虚拟地址+基地址

为何OEP不能使用虚拟地址呢?

因为在程序在运行后会自动拉伸代码,自动计算入口点,入口点就是OEP+基地址。这些程序会自动完成,如果在文件中OEP使用了虚拟地址那么程序在拉伸后就是虚拟地址+基地址。这样肯定是不行的,因为虚拟地址已经是可运行状态了。

相对虚拟地址也可以理解为是FileBuffe,经过ImageBuffer运行后转为可执行地址。

  • Shellcode使用虚拟地址(VA)****:因为在程序运行时,代码段在内存中的位置是虚拟地址。

  • OEP使用相对虚拟地址(RVA):因为OEP在程序加载时是相对于模块基地址的偏移,操作系统会自动将其转换为虚拟地址。

License:  CC BY 4.0