PE文件与虚拟内存之间的映射

这篇主要来讲讲PE文件和虚拟内存之间的映射关系,PE是win32平台下可执行文件遵守的数据格式,常见的可执行文件(如 .exe 、.dll)都是典型的PE文件。

一、PE文件数据节介绍

PE文件格式把可执行文件分为若干个数据节(section),下面列举几个主要的section.
.text 由编译器产生,存放着二进制的机器代码,也是我们反汇编和调试的对象。
.data 初始化的数据块,如宏定义、全局变量、静态变量等。
.idata 可执行文件所使用的的动态链接库等外来函数与文件的信息。
.rsrc 存放程序的资源,如图标、菜单等。
除此之外 还可以在代码中使用 #pragma data_seg()来指定代码存放的数据节。

二、虚拟内存

调试器看到的内存地址都是虚拟内存,每个进程都单独拥有4GB的虚拟内存空间。

三、术语

1、文件偏移地址(File Offset)
数据在PE文件中的地址叫文件偏移地址,这是文件在磁盘上存放时相对于文件开头的偏移。

2、装载基址(Image Base)
PE装入内存时的基地址,这个不是固定的。默认情况下,EXE文件在内存中的基地址是0x00400000,DLL文件是0x10000000,这些位置可以通过修改编译器选项更改。

3、虚拟内存地址 (Virtual Address, VA)
PE文件中的指令被装入内存后的地址。

4、相对虚拟地址(Relative Virtual Address,RVA)
是内存地址相对于装载基址的偏移量。

虚拟内存地址、装载基址、相对虚拟内存地址三者之间的关系如下:
VA = Image Base + RVA

四、文件地址与内存地址的关联

1、数据存放格式的区别
(1)、PE文件中的数据按照磁盘数据标准存放,以0x200字节为基本单位进行组织,当一个数据节(section)不足0x200字节时,不足的地方将被0x00存放;当一个数据节超过0x200字节时,下一个0x200块将分配给这节使用。因此PE数据节的大小永远是0x200的整数倍。

(2)、当代码装入内存后,将按照内存数据标准存放,并以0x1000字节为基本单位进行组织,类似的,不足将被补全,若超出将分配下一个0x1000为其所用。因此内存中的节总是0x1000的整数倍。

2、节偏移
节(section)| 相对虚拟偏移量 RVA | 文件偏移量
.text | 0x00001000 |0x400
.rdata | 0x00007000 |0x6200
.data | 0x00009000 |0x7400
.rsrc | 0x0002D000 |0x7800

每个节的偏移量为:
.text 节偏移 = 0x00001000 - 0x400 = 0xC00
.rdata 节偏移 = 0x00007000 - 0x6200 = 0xE00
.data 节偏移 = 0x00009000 - 0x7400 = 0x1c00
.rsrc 节偏移 = 0x0002D000 - 0x7800 = 0x25800

那么文件偏移量地址与虚拟内存地址之间的换算关系公式如下
文件偏移地址 = 虚拟内存地址(VA) - 装载基址(Image Base) - 节偏移
= RVA - 节偏移

举例来说明,如果在调试时遇到虚拟内存中0x00404141处的的一条指令,那么换算出这条指令在文件中的偏移量,则是:
文件偏移量= 0x00404141 - 0x00400000 -(0x1000 - 0x400) = 0x3541
在文件0x3541处存放着内存中0x00404141的指令。

表达的不够清楚,大家没有看明白的,欢迎留言讨论。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值