VA = Image Base + RVA;
| .rsrc 00004000 000003A0 00000A00 00000400 C0000040|
2、汇编中虚拟地址(VRA)与文件偏移地址(FileOffset)的相互转换:
(2).装载基址(Image Base):PE装入内存时的基地址。默认EXE文件在内存中的基地址为0x00400000,DLL为0x10000000。当然位置可由编译选项更改。
典型PE文件通常包含:.text(编译器产生,存放二进制代码, 反汇编和调试的对象)、.data(初始化数据块)、.idata(使用的外来函数如动态链接库与文件信息)、.rsrc(存放程序资源),还包括其他如.reloc、.edata、.tls、.rdata等。
PE文件中出现RVA的 概念是因为PE的内存映像和磁盘文件映像是不同的,同一数据相对于文件头的偏移量在内存中和在磁盘文件中可能是不同的,为了提高效率,PE文件头中使用的 都是内存映像中的偏移量,也就是RVA。从图17.3中也可以得到另一个结论,那就是RVA仅仅是对于处于节中的数据而言的,对于文件头和节表来说无所谓 RVA和文件偏移,因为它们在被映射到内存中后不管是大小还是偏移都不会有任何改变。
则有:
文件虚拟偏移地址和文件物理偏移地址的计算公式如下:
>>>>>>>VaToFileOffset( 虚拟地址转文件偏移地址)
FileOffset = VA - Image Base -节偏移
| Name VOffset VSize ROffset RSize Flags |
Windows内存:1.物理内存层面;2.虚拟内存层面。
| .text 00001000 00000092 00000400 00000200 60000020|
如VA = 00401325,则:
可执行文件:包含二进制代码,字符串,菜单,图标,位图字体等。
准 确地说,RVA就是当PE文件被装载到内存中后,某个数据的位置相对于文件头的偏移量。举个例子,如果Windows装载器将一个PE文件装入 00400000h处的内存中,而某个节中的某个数据被装入0040xxxxh处,那么这个数据的RVA就是(0040xxxxh- 00400000h)=xxxxh,反过来说,将RVA的值加上文件被装载的基地址,就可以找到数据在内存中的实际地址。
虚拟内存:
+---------+---------+---------+---------+---------+---------+
可理解为: 实际 = 基点 + 位移.
VRk = VOffset - ROffset = 00001000 - 00000400 = C00 (得出文件虚拟地址和文件物理址之间的VRk值)
装载PE文件时,文件偏移地址(磁盘上)与RVA(内存上)有很大一致性(操作系统会尽量保持PE中各数据结构),那同样会有细微差异,由文件数据和内存数据的存放单位不同造成。
+---------+---------+---------+---------+---------+---------+
文件偏移量 = 0x00404141 - 0x00400000(默认的Image Base)-(0x1000 - 0x400)(代码存于.text文件中) = 0x3541
FileOffset = VA - ImageBase - VRk = 00401325 - 00400000 - C00 = 725
内存管理器可以使进程在实际只有512MB物理内存的情况下使进程“认为”自己拥有4GB内存(其中包括代码, 栈空间,资源区,动态链接库等)。
RVA是相对虚拟地址(Relative Virtual Address)的缩写,顾名思义,它是一个“相对”地址,也可以说是“偏移量”,PE文件的各种数据结构中涉及到地址的字段大部分都是以RVA表示的。
而在内存中,则以0x1000字节(4byte)为基本单位进行组织,其他与前者类似。
在进行File Offset和VA换算时,会由存储单位引起节基址差称为节偏移。比如:
| .rdata 00002000 000000F6 00000600 00000200 40000040|
= VA - Image Base - (相对虚拟偏移量 - 文件偏移量)
ImageBase = 00400000 (基地址)
(1).文件偏移地址(File Offset):数据在PE文件中的地址,在磁盘上存放时相对于文件开头的偏移。
+---------+---------+---------+---------+---------+---------+
本文由澳门新葡亰1495app发布于网络技术,转载请注明出处:(转)澳门新葡亰1495app:RVA-相对虚拟地址解释