PE学习——PE文件整体结构解析,写得很精致,可以对照案例实践

PE学习——PE文件整体结构解析,写得很精致,可以对照案例实践

RVA与FOA的转换

想象一下,如果你想通过逆向的方式改变一个全局变量的初始值,该怎么做?首先我们可以写一个程序,输出一个全局变量的地址和值:

int a = 0x12345678;

int main() {

printf("Address: 0x%x \n", &a);

printf("Value: 0x%x \n", a);

getchar();

return 0;

}

我们运行程序可以看见相应的值,那么我们可以是否可以在文件中直接搜索对应的值然后修改呢?这种方法没有毛病,但是文件中也许会存在很多个0x12345678,你无法准确的知道哪一个才是全局变量;那么,又是否可以通过已经给出的这个地址0x42ba30直接去寻找呢?当然也是不行的,因为在之前章节的学习中我们了解到,PE文件有2种状态(动静态),在这2种状态下,文件的对齐方式会发生变化,所以当前的地址是PE文件运行时(动态)的地址,你需要转换成在磁盘上(静态)的地址。

这两种状态的地址相互转换,我们可以称之为RVA与FOA的转换,RVA就是相对虚拟地址,FOA就是文件偏移地址;从RVA转换到FOA,就是从文件运行时(动态)的地址转换成在磁盘上(静态)的地址,按如下公式可以进行转换:

RVA地址由内存地址减去ImageBase地址(PE文件在内存中的开始位置是由扩展PE头中的ImageBase决定);

判断RVA地址是否位于PE头中:

如果是,那么RVA等于FOA;

如果不是,判断RVA位于哪个节:==》见后面逆向工程核心原理书中所述

当满足RVA地址大于等于节.VirtualAddress和RVA地址小于等于节.VirtualAddress加上当前节内存对齐后的大小时,就表示RVA地址在该节中。

RVA地址减去节.VirtualAddress等于差值,FOA地址就是根据节.PointerToRawData加上差值。

在一些较老的编译器中,编译出来的文件会区分文件对齐、内存对齐,但是在现在的编译器编译出来的程序,文件对齐与内存对齐时完全一样的,所以我们不用费这么大的周折,我们只需要算出RVA的值就可以得出FOA的值。

例如,在当前程序中就是这样,根据0x42BA30-0x400000(ImageBase)得出0x2BA30,其是RVA,也是FOA,直接使用Winhex打开找到:

可以直接修改它然后保存运行,这时候你就会发现全局变量的值已经发生了改变:

==》在我的机器上实践下:

32位,release编译,vs2017出来的结果:

二者并不一样!

换成64位,二者也不相同。

补充:

关于RVA和FOA(RAW)二者的转换,在逆向工程核心原理里提到过:

我们以书中第一个问题为例,核心计算方式就是section里的偏移是一致的!Image在内存中虽然变大,但是都是填充的NULL!

相关推荐

365体育平台真假怎么分 白百何出轨想起爆料往事 是她睡导演被打折腿吗
365平台赌博 【心得】死光連招心得 @影之刃 哈啦板
mobile288-365 学生党必看!暑假工有哪些好选择?2025年最受欢迎的6类工作