RVA是相对虚拟地址(Relative Virtual Address)的缩写,顾名思义,它是一个“相对”地址,也可以说是“偏移量”,PE文件的各种数据结构中涉及到地址的字段大部分都是以RVA表示的。

准 确地说,RVA就是当PE文件被装载到内存中后,某个数据的位置相对于文件头的偏移量。举个例子,如果Windows装载器将一个PE文件装入 00400000h处的内存中,而某个节中的某个数据被装入0040xxxxh处,那么这个数据的RVA就是(0040xxxxh- 00400000h)=xxxxh,反过来说,将RVA的值加上文件被装载的基地址,就可以找到数据在内存中的实际地址。

PE文件中出现RVA的 概念是因为PE的内存映像和磁盘文件映像是不同的,同一数据相对于文件头的偏移量在内存中和在磁盘文件中可能是不同的,为了提高效率,PE文件头中使用的 都是内存映像中的偏移量,也就是RVA。从图17.3中也可以得到另一个结论,那就是RVA仅仅是对于处于节中的数据而言的,对于文件头和节表来说无所谓 RVA和文件偏移,因为它们在被映射到内存中后不管是大小还是偏移都不会有任何改变。

2、汇编中虚拟地址(VRA)与文件偏移地址(FileOffset)的相互转换:

+———+———+———+———+———+———+

|  段名称   虚拟地址  虚拟大小  物理地址  物理大小   标志   |

+———+———+———+———+———+———+

|  Name     VOffset    VSize    ROffset    RSize      Flags |

+———+———+———+———+———+———+

|  .text   00001000   00000092  00000400  00000200  60000020|

|  .rdata  00002000   000000F6  00000600  00000200  40000040|

|  .data   00003000   0000018E  00000800  00000200  C0000040|

|  .rsrc   00004000   000003A0  00000A00  00000400  C0000040|

+———+———+———+———+———+———+

文件虚拟偏移地址和文件物理偏移地址的计算公式如下:

>>>>>>>VaToFileOffset( 虚拟地址转文件偏移地址)

如VA = 00401000 (虚拟地址)

ImageBase = 00400000 (基地址)

VRk = VOffset – ROffset = 00001000 – 00000400 = C00 (得出文件虚拟地址和文件物理址之间的VRk值)

FileOffset = VA – ImageBase – VRk = 00401000 – 00400000 – C00 = 400(文件物理地址的偏移地址)

如VA = 00401325,则:

FileOffset = VA – ImageBase – VRk = 00401325 – 00400000 – C00 = 725

>>>>>>FileOffsetToVa( 文件偏移地址转虚拟地址)

如FileOffset = 435(文件偏移地址)

VA = FileOffset + ImageBase + VRk = 435 + 00400000 + C00 = 00401035(虚拟地址)

源文档 <http://blog.csdn.net/xuexi1028/article/details/6948591>

纸上得来终觉浅,绝知此事要躬行