PE 文件基础知识

本文章内容大部分来自于对《0day安全:软件漏洞分析技术(第二版)》的整理

PE 文件概述

PE 文件是 Windows 可执行文件的格式,PE 文件按照一定的规定,将代码,数据(程序定义的变量和常量),程序资源(图片等)按照一定的格式存储在一个文件中,方便系统运行程序的时候将代码加载到内存中。如果没有这种规定的格式,程序在内存中的加载将会相当混乱,计算机系统将很难对程序进行管理。

PE 文件格式

PE 将程序中的不同的部分分成若干个数据节,代码和数据等分别存储在不同的节中。一个标准的的PE文件的格式如下:

  • .text 由编译器产生的二进制程序代码
  • .data 初始化的数据块,如:宏定义、全局变量、静态变量
  • .idata 可执行程序所使用的动态链接库等外来的函数与文件的信息
  • .rsrc 存放程序的资源,如图标、菜单等

Windows 虚拟内存机制

Windows 的内存可以分成两个层面:物理内存和虚拟内存。物理内存较为复杂,需要进入 Windows 内核级别 ring0 才能看到。

Intel的x86处理器是通过Ring级别来进行访问控制的,级别共分4层,RING0, RING1, RING2, RING3。Windows 只使用其中的两个级别RING0 和 RING3。RING0 层拥有最高的权限,RING3 层拥有最低的权限。

所以在用户模式下,我们用调试器看到的内存地址都是虚拟内存。

Windows 让所有的进程都“相信”自己拥有独立的 4GB 内存(32位计算机),但是实际的物理内存可能只有 512 MB,所以为了让所有内存中的程序都有调用 4GB 内存的能力,Windows 的程序员设计了虚拟内存管理器

虽然每个内存中的程序(也就是进程)能调度 4GB的内存,但是由于本身一个程序并不会时时刻刻使用全部的 4GB 内存,所以只要将内存合理调配,物理内存是可以存下全部的进程的。就像一个银行可能本身拥有的钞票会小于所有用户的账户上的钞票,但是银行仍然能够正常运转。

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

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 \]

由于操作系统在进行程序装载时“基本”上保持 PE 中的各种数据结构,所以文件偏移地址和 RVA 有很大的一致性,但是仍然有细微的区别。

  • PE 文件中的数据按照磁盘数据标准存放,以 0x200 字节为基本单位进行组织。当一个数据节(section)不足 0x200 字节时,不足的地方将被 0x00 填充;当一个数据节超过 0x200 字节时,下一个0x200 块将分配给这个节使用。因此 PE 数据节的大小永远是 0x200 的整数倍
  • 当代码装入内存后,将按照内存数据标准存放,并以 0x1000 字节为基本单位进行组织。类似的,不足将被补全,若超出将分配下一个 0x1000 为其所用,因此,内存中的节永远是 0x1000 的整数倍

由于这个区别,所以在进程载入内存后,每个 PE 节的起始位置会发生变化。但是每节内数据仍然按照原来的方式排列。

posted @ 2021-02-05 13:03  Node_Sans  阅读(716)  评论(0编辑  收藏  举报