PE文件格式详细解析(一)

PE文件格式详细解析

本篇文章将会详解Windows操作平台下PE文件格式,同时以具体的示例辅佐大家更好理解PE文件格式。本文章主要使用到以下两个工具:WinHex:用于将PE文件以16进制和ASCII码显示;PE tools解析和修改PE文件的工具。

1.PE文件格式

PE(Portable Executable,可移植的可执行文件),是Windows操作系统下可执行文件的总称。

PE文件往往指32位系统下的可执行文件,亦称PE32。64位的可执行文件称为PE+或PE32+,为PE文件的扩展格式。

PE文件主要分为以下几种:

种类主扩展名
可执行系列.exe .scr
库系列.dll .ocx .cpl .drv
驱动程序系列.sys .vxd
对象文件系列.obj

2.PE文件位置标识

由于PE文件在加载到内存时需要进行内存对齐,因此一个PE文件在磁盘中和在内存中所占大小不一致,需要以下两种位置标识方式标识具体数据在磁盘和内存中的位置信息。

  • RAW offset

    标识数据的物理地址,即一个数据在文件中相对于文件头的偏移量。

    如下图,使用WinHex打开某一具体可执行文件最左边的位置标识。

在这里插入图片描述

  • VA和RVA

    VA(Virtual Address,虚拟地址),指PE文件装载在内存中某一数据在虚拟内存中的绝对地址。32位Windows操作系统默认分配4G的虚拟内存,因此其VA值的范围为0x0000000~0xFFFFFFFF。

    RVA(Relative Virtual Address,相对虚拟地址),指从某个基准位置开始的相对地址。

    由于DLL(Dynamic Linked Library,动态链接库)在加载到进程的虚拟地址空间时,该位置可能已加载了其他的DLL,因此需要加载到没有使用的某一基地址上,然后使用RVA进行地址映射,将DLL装载到内存中。因此PE文件中的地址信息大多以RVA的形式存放。

    VA和RVA满足以下关系:
    V A = R V A + I m a g e B a s e VA=RVA+ImageBase VA=RVA+ImageBase

  • RVA to RAW
    当PE文件加载到内存中时,PE文件需要将每个节区准确的进行内存地址与文件偏移的映射(这里涉及到PE文件节区结构的相关知识,将在下一节中讲解)。

    该映射方法如下:

    1. 查找该数据的RVA所属节区

    2. 查找该节区头结构中的VirtualAddress(标识该节区起始的RVA)和PointerToRawData(文件中节起始的偏移量)

    3. 使用以下公式计算该数据的物理地址RAW
      R A W − P o i n t e r T o R a w D a t a = R V A − V i r t u a l A d d r e s s RAW - PointerToRawData = RVA - VirtualAddress RAWPointerToRawData=RVAVirtualAddress
      该公式其实表示的是一个数据在内存与磁盘中相对节区起始的偏移量一致。

    例如:查看一个PE文件的EP(Entry Point,入口地址)的物理地址。

    使用PEtools查看可执行文件的相关信息,直接给出了EP的物理地址为0x09A8

在这里插入图片描述

该地址使用上述的方法计算:

在这里插入图片描述

通过查看可选头结构找到EP的RVA地址为0x15A8,然后查看.text节的相关信息

在这里插入图片描述

.text节区的VirtualAddress为0x1000,PointerToRawData为0x0400,使用公式计算

RAW-0x0400=0x15A8-0x1000,得出RAW为0x09A8即为上述所给的物理地址。

3.PE文件的结构

(PE文件的结构在WinNT.h头文件中标识)

PE文件的整体结构如图所示:

在这里插入图片描述

3.1 DOS头

DOS头由两部分组成,分别为DOS HeaderDOS Stub。DOS头的作用是兼容MS-DOS操作系统,使得DOS识别出这是有效的执行体,然后运行紧随之后的DOS Stub。

  • DOS Header

    DOS Header由IMAGE_DOS_HEADER结构体构成,该结构体大小为0x40字节,该结构的具体内容如下

    typedef unsignedlong DWORD;	//大小为4B
    typedef unsignedchar BYTE;	//大小为1B
    typedef unsignedshort WORD;	//大小为2B
    
    typedef struct _IMAGE_DOS_HEADER {
        WORD e_magic;       // 魔术数字
        WORD e_cblp;        // 文件最后页的字节数
        WORD e_cp;          // 文件页数
        WORD e_crlc;        // 重定义元素个数
        WORD e_cparhdr;     // 头部尺寸,以段落为单位
        WORD e_minalloc;    // 所需的最小附加段
        WORD e_maxalloc;    // 所需的最大附加段
        WORD e_ss;          // 初始的SS值(相对偏移量)
        WORD e_sp;          // 初始的SP值
        WORD e_csum;        // 校验和
        WORD e_ip;          // 初始的IP值
        WORD e_cs;          // 初始的CS值(相对偏移量)
        WORD e_lfarlc;      // 重分配表文件地址
        WORD e_ovno;        // 覆盖号
        WORD e_res[4];      // 保留字
        WORD e_oemid;       // OEM标识符(相对e_oeminfo)
        WORD e_oeminfo;     // OEM信息
        WORD e_res2[10];    // 保留字
        LONG e_lfanew;      // 新exe头部的文件地址
    } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
    

    该结构中只有两个重要的成员变量,分别是e_magic(offset:0x0000)和e_lfanew(offset:0x003c)。

    补充一个知识点Intel CPU采用小端模式,例如0x12345678在二进制文本中实际显示为78 56 34 12。

    e_magic其值是一个常数为0x5A4D,其ASCII码为MZ,标识着该文件为可执行文件。

    在这里插入图片描述

    e_lfanew的值表示NT头在文件中的偏移地址raw

    在这里插入图片描述

    可以看到图中可执行文件的DOS头中e_lfanew的值为0x00e0,可以看到该地址确实为NT头部。

    在这里插入图片描述

  • DOS Stub

    DOS Stub实际上是个有效的EXE,由代码和数据混合而成,大小不固定,在不支持PE文件格式的操作系统中,它将简单显示一个错误提示。在Windows OS下不会运行其中的代码,但在DOS环境中可以运行。多数情况下DOS Stub由汇编器/编译器自动生成。

    在这里插入图片描述

    可以看到该可执行文件的DOS stub的ASCII码中包含This program cannot be run in DOS mode这句提示

  • 8
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值