RVA到FOA的转换

地址空间:这个地址空间指的是PE文件被加载到内存的空间,是一个虚拟的地址空间,之所以不是物理空间是因为数据在内存中的位置经常在变,这样既可以节约内存开支又可以避开错误的内存位置。这个地址空间的大小为4G,但其中供程序装载的空间只有2G而且还是低2G空间,高2G空间则被用于装载内核DLL文件,所以也被称作内核空间。

 

文件映射:PE文件在磁盘上的状态和在内存中的状态是不一样的,我们把PE文件在磁盘上的状态称作FileBuffer,在内存中的状态称为ImageBuffer。当PE文件通过装载器装入内存是会经过“拉伸”的过程,所以它在FileBuffer状态下和ImageBuffer状态下的大小是不一样的。这个拉伸的具体过程会在讲完PE头结构后进行介绍。大致的图解如下:

VA:英文全称是Virual Address,简称VA,中文意思是虚拟地址。指的是文件被载入虚拟空间后的地址。 

ImageBase:中文意思是基址,指的是程序在虚拟空间中被装载的位置。

RVA:英文全称是Relative Virual Address,简称RVA,中文意思是相对虚拟地址。可以理解为文件被装载到虚拟空间(拉伸)后先对于基址的偏移地址。计算方式:RVA = VA(虚拟地址) - ImageBase(基址)。它的对齐方式一般是以1000h为单位在虚拟空间中对齐的(传说中的4K对齐),具体对齐需要参照IMAGE_OPTIONAL_HEADER32中的SectionAlignment成员。
FOA:英文全称是File Offset Address,简称FOA,中文意思是文件偏移地址。可以理解为文件在磁盘上存放时相对于文件开头的偏移地址。它的对齐方式一般是以200h为单位在硬盘中对齐的(512对齐),具体对齐需要参照IMAGE_OPTIONAL_HEADER32中的FileAlignment成员。
 
RVA到FOA的转换
<1> 得到RVA的值,RVA=内存地址-ImageBase(ImageBase是IMAGE_OPTION_HEADER中的成员);
<2> 比较RVA与SizeofHeaders的大小,判断RVA是否位于PE头中,如果是的话,FOA=RVA,(SizeofHeaders是IMAGE_OPTION_HEADER中的成员);
<3> 判断RVA位于哪个节,
  RVA >= 节.VirtualAddress
  RVA <= 节.VirtualAddress + 当前节内存对齐后的大小
  差值 = RVA - 节.VirtualAddress
<4> FOA = 节.PointerToRawData + 差值
  
posted @ 2020-01-31 15:52  AGB  阅读(955)  评论(0编辑  收藏  举报