VA&RVA
VA指的是进程虚拟内存的绝对地址,RVA(Relative Virtual Address,相对虚拟地址)指从某个基准位置(ImageBase)开始的相对地址。VA与RVA满足下面的换算关系。
RVA + ImageBase = VA
PE(Portable Executable)头部信息大多以RVA形式存在。原因在于,PE文件(主要是DLL(DLL,Dynamic Linked Library))加载到进程虚拟内存的特定位置时,该位置可能已经加载了其它PE文件(DLL)。此时必须通过重定位(Relocation)将其加载到其它空白的位置,若PE头信息使用的是VA,则无法正常访问。因此,使用RVA来定位信息,即使发生了重定位,只要相对于基准位置的相对地址没有变化,就能正常访问到指定信息,不会出现任何问题。
提示:
32 位 Widows OS 中,各进程分配有 4GB 的虚拟内存,因此,进程中 VA 值的范围是 0000 0000 ~ FFFF FFFF。
RVA to RAW
PE文件加载到内存时,每个节区都要能准确完成内存地址与文件偏移间的映射。这种映射一般称为 RVA to RAW,方法如下:
- 查找RVA所在节区。
- 使用简单的公式计算文件偏移(RVA)。
根据IMAGE_SECTION_HEADER结构体,换算公式如下:
RAW - PointerToRawData = RVA - VirtualAddress
进而得:
RAW = RVA - VirtualAddress + PointerToRawData
PE头中表示地址时不使用VA,而是RVA。
Q:节区头成员 VirtualAddress 是内存中节区头的起始地址(RVA),VirtualAddress 不就是 VA 吗?为什么要叫 RVA 呢?
A:“使用 RVA 值来表示节区头的成员 VirtualAddress”,这样理解就可以。节区头结构体(IMAGE_SECTION_HEADER)的 VirtualAddress 成员与虚拟内存地址(VA,VirtualAddress)用的术语相同才引起这一混乱。“节区头成员 VirtualAddress 指的是虚拟内存中相应节区的起始地址,它以 RVA 的形式保存在结构体中”,如此理解即可。
Preference
逆向工程核心原理 (P_{92}) (P_{104})
就着这个帖子理解 RVA、VA、RAW、偏移量
RVA可以理解为内存偏移;RAW可以理解为文件偏移(硬盘偏移)。