RVA计算FOA

独行   ·   发表于 2020-11-01 22:41:40   ·   技术文章

RVA计算FOA

前言

该文章描述了RVA和FOA之间的相互转换。第一部分会有基本的概念补充,第二部分讲解如何计算RVA计算FOA。
作者:天象独行
第一部分


一;概念补充

RVA是指“相对虚拟内存地址”。FOA是指“文件偏移地址”。详细如下图:

首先我来看图中“红色方框”中的内容。它表示PE文件在硬盘中的状态。接下来我们来看看当中的标志“A”。它表示的是文件头到“.rsrc节”的距离。我们将这个距离称为“文件偏移地址”即FOA。我们很容易通过这个偏移地址来计算出“.rsrc节”的地址。

下面我们再来看看图中右边的蓝色方框。它表示的是文件加载到内存当中状态(注释:我们将加载至内存当中的文件称之为“模块”)我们来看图中标识的”A’”。它表示PE文件头至“.rsrc节”的距离,这样的距离我们称之为“相对虚拟内存地址”即RVA。(注释:PE结构内容请参考如下网址文章:http://www.nvnv.xyz/newsinfo/2368194.html)

二;为什么文件加载后出现变化?

文件放入到内存之后为什么会产生这样的变化呢?这里大家可以理解为在文件中PE结构的对齐值为200h(200指的是十六进制)。然后在通常情况下来在内存当中的文件的对齐为1000h。为什么需要对齐呢?一定程度上是为了更加快速的计算定位地址。在这个变化的过程中,是通过在节区后面添加0补充来将200h增加到1000h的对齐。

第二部分


三;如何计算RVA和FOA的转换?

首先我们来看一下下面这张图:

我们需要通过RVA来计算出FOA。

我们先了解一下节表项IMAGE_SECTION_HEADER当中两个元素。第二个元素VirtualAddress以及第四个元素PointerToRawData。其中VirtualAddress记录了当前节区的RVA地址。PointerToRawData记录了当前节区在文件中的偏移地址。

那么,在图中RVA在节2当中,那么RVA20 = IMAGE_SECTION_HEADER.VirtualAddress现在我们来看看图中的OFFSET的值是否能够计算出来呢?
计算方式如下:OFFSET = RVA - IMAGE_SECTION_HEADER.VirtualAddress。

我们知道PE文件到PE内存映像的变化是在节区最后用0来补充对齐的。这样我们就知道图中OFFSET2 = OFFSET 。它们的大小是一样的。现在我们只需要知道FOA20的值是多少就能够计算出来FOA的值是多少了。那么我们怎么知道FOA20的值呢?同样,查看节表项IMAGE_SECTION_HEADER当中第四个元素PointerToRawData。下面我们来计算FOA = OFFSET + IMAGE_SECTION_HEADER.PointerToRawData。

总结

1;计算OFFSET = RVA - IMAGE_SECTION_HEADER.VirtualAddress
2;获取FOA20 = IMAGE_SECTION_HEADER.PointerToRawData
3;计算FOA = OFFSET + IMAGE_SECTION_HEADER.PointerToRawData

用户名金币积分时间理由
veek 50.00 0 2020-11-02 10:10:38 一个受益终生的帖子~~

打赏我,让我更有动力~

0 条回复   |  直到 2020-11-1 | 1006 次浏览
登录后才可发表内容
返回顶部 投诉反馈

© 2016 - 2024 掌控者 All Rights Reserved.