【PE】RVA与FOA的转换 和 空白区域添加代码
RVA与FOA的转换 和 空白区域添加代码
RVA与FOA的转换
RVA(相对虚拟地址):内存地址 - Imagebase
FOA(文件偏移地址):
1、判断RVA是否在头部
(1)如果在头部:FOV = RVA
2、判断RVA位于哪个节:
RVA >=节.VirtualAddress
RVA<=节.VirtualAddress + 当前节内存对齐后的大小
差值 = RVA - 节.VirtualAddress
3、FOA =节 .PointerToRawData + 差值
空白区域添加代码
外链帮助:
【PE文件入门,一篇就够了】https://bbs.kanxue.com/thread-281836.htm#msg_header_h3_11
我们要插入这样一个代码
1 |
|
功能呢就是弹出一个这样的错误窗口。这个程序的核心就是调用了一个messagebox函数弹出了一个窗口。由于我们是要对pe文件进行操作,所以肯定不是将代码写入,而是要将机器码插入。就是利于栈传第四个参数0,然后call。
构造要写入的代码 6A 00 6A 00 6A 00 6A 00 E8(call)xx xx,我们看到的FF是(near jump)要使用一个什么导入表(后面会学),而我们插入的时候E8利用相对偏移量调用函数。E8后面跟四个字节的相对偏移量offset,怎么计算?还好了解过汇编,offset=要跳转的地方的地址-call指令下面一条指令的地址。
将图一标记位置改为call 1c1023 得到图二,后面的0A=1c1023-1c1019.我们的目标指示让他弹出窗口,不能破坏程序运行,所以弹出之后我们还要跳回到初始位置,让程序正常运行,我们使用JMP(E9)指令来实现该操作,E9后面也是跟偏移量,用法与E8相同。找到messagebox的地址75858A70。根据call指令的位置来计算。
E8所在的位置是3A8,这是文件中的位置,我们要考虑的是运行时的位置,所以要把这个地址加上Image Base =01000000,所以最后得到的 offset=75858A70-010003A8-5=7485 86C3.最后跳转到程序的入口处,查看可选头的成员入口值为739D加上Image Base得到0100739D. offset=0100739D-010003AD-5=6FEB
将程序入口点指向我们插入的代码,
也就是修改扩展pe头里的入口值
在108处占4个字节,我们插入的程序起始位置是000003A0.然后,然后就没然后了,程序运行不起,ida和od看到的东西都很奇怪,延误了两天,这里我直接说一下踩的坑,我随意找了一个空白处填充机器码,但后来发现不是所有的位置都能发生跳转,然后就将指令插入在了text段的末尾,然后发现跳转的有些差异,不会跳转在我设置的地方,后知后觉的发现,视频里的老哥演示的的时候拿的是一个文件对齐和内存对齐相同大小的程序,我用的程序是一个不同的,所以就要计算一下 用我们前面学习到的知识。下面理一下步骤
- 首先在文件中确定一段空间,然后运行程序的时候查看 是否为空
- 插入,根据内存中的位置计算
- 改入口,内存中代码的起始位置
第一次尝试的时候成功弹出了窗口,但是关闭之后没有出现记事本,由此我们可以判断执行完我们的代码后,没有成功的返回原入口。此时才想起来补码写错了,插入的位置是87b0,入口点是739d,739d-83b0-5=
然后我就在e9后面填充了E8 EF 00 00,意识到返回出现问题后,想到了有符号数的符号扩展,应该扩展其符号位即1,所以正确的补码形式是FF FF EF E8,填充进去就是E8 EF FF FF.
外链帮助:
【PE文件入门,一篇就够了】https://bbs.kanxue.com/thread-281836.htm#msg_header_h3_11