PE文件格式介绍(一)

0x00 前言

PE文件是portable File Format(可移植文件)的简写,我们比较熟悉的DLL和exe文件都是PE文件。了解PE文件格式有助于加深对操作系统的理解,掌握可执行文件的数据结构机器运行机制,对于逆向破解,加壳等安全方面方面的同学极其重要。接下来我将通过接下来几篇详细介绍PE文件的格式。

0x01 基本概念

PE文件使用的是一个平面地址空间,所有代码和数据都被合并在一起,组成一个很大的组织结构。文件的内容分割为不同的区块(Setion,又称区段,节等),区段中包含代码数据,各个区块按照页边界来对齐,区块没有限制大小,是一个连续的结构。每块都有他自己在内存中的属性,比如:这个块是否可读可写,或者只读等等。

认识PE文件不是作为单一内存映射文件被装入内存是很重要的,windows加载器(PE加载器)便利PE文件并决定文件的哪个部分被映射,这种映射方式是将文件较高的偏移位置映射到较高的内存地址中。当磁盘的数据结构中寻找一些内容,那么几乎能在被装入到内存映射文件中找到相同的信息。但是数据之间的位置可能改变,其某项的偏移地址可能区别于原始的偏移位置,不管怎么样,所表现出来的信息都允许从磁盘文件到内存偏移的转换,如下图:

PS:PE文件头以下的地址无论在内存映射中还是在磁盘映射中都是一样的,当内存分页和磁盘分页一致时无需进行地址转换,只有当磁盘分页和内存分页不一样时才要进行地址转化,这点很重要,拿到PE文件是首先查看分页是否一致。前两天一直没碰到内存和磁盘分页不一样的,所以这个点一直没发现,今天特来补上。

下面要介绍几个重要概念,分别是基地址(ImageBase),相对虚拟地址(Relative Virtual Address),文件偏移地址(File Offset)。

1)基地址

定义:当PE文件通过Windows加载器被装入内存后,内存中的版本被称作模块(Module)。映射文件的起始地址被称作模块句柄(hMoudule),可以通过模块句柄访问其他的数据结构。这个初始内存弟子就是基地址。

内存中的模块代表着进程从这个可执行文件中所需要的代码,数据,资源,输入表,输出表以及其他有用的数据结构所使用的内存都放在一个连续的内存块中,编程人员只要知道装载程序文件映像到内存的基地址即可。在32位系统中可以直接调用GetModuleHandle以取得指向DLL的指针,通过指针访问DLL module的内容,例如:

HMODULE GetmoduleHandle(LPCTSRT lpModuleName);

当调用该函数时,传递一个可执行文件或者DLL文件名字字符串。如果系统找到该文件,则返回该可执行文件的或者DLL文件映像加载到的基地址。也可以调用GetModuleHandle,传递NULL参数,则返回调用的可执行文件的基地址。

2)相对虚拟地址

在可执行文件中,有相当多的地方需要指定内存的地址。例如:引用全局变量时,需要指定它的地址。PE文件尽管有一个首选的载入地址(基地址),但是他们可以载入到进程空间的任意地方,所以不能依赖与PE的载入点。由于这个原因,必须有一个方法来指定一个地址而不是依赖于PE载入点。

为了在PE文件中避免有确定的内存地址,出现了相对虚拟地址(Relative Virtual Addres,简称RVA)的概念。RVA只是内存中的一个简单的相对于PE文件装入地址的偏移地址,它是一个“相对”地址,或者称位“偏移量”地址。例如:假设一个EXE文件从地址40000h处载入,并且它的代码区块开始于4010000h,代码区的RVA将是:

目标地址401000h ——转入地址400000h则RVA=1000h。

将RVA地址转换成真实地址,只需简单的翻转这个过程:将实际装入地址加上RVA即可得到实际的内存地址。顺便一提,在PE用语里,实际的内存地址被称作虚拟地址(Vritual Address,简称VA),另外也可以把虚拟地址想象为加上首选装入地址的RVA。不要忘了前面提到的装入地址等同于模块句柄,它们之间的关系如下:

虚拟地址(VA)=基地址(ImageBase)+相对虚拟地址(RVA)

3)文件偏移地址

当PE文件存储在磁盘上时,某个数据的位置相对于文件头的偏移量也称文件偏移地址(FileOffset)或者物理地址(RAW Offset)。文件偏移地址从PE文件的第一个字节开始计数,起始为零。用十六进制工具比如:winhex,hexworkshop都可以查看。注意这个物理地址和虚拟地址的区别,物理地址是文件在磁盘上相对于文件头的地址,而虚拟地址是PE可执行程序加载在内存中的地址。

0x02 几个重要头部信息介绍

接下来介绍MS-DOS头部信息,PE文件头信息及几个重要字段。

1)MS-DOS头部

每个PE文件是以一个DOS程序开始的,有了它,一旦程序在DOS下执行,DOS就能辨别出这是个有效的执行体,然后运行紧随MZ header(后面会介绍)之后的DOS stub(DOS块)。DOS stub实际上是一个有效的EXE,在不支持PE文件格式的操作系统中,它将简单显示一个错误提示,类似于字符串“This Program cannot be run in MS-DOS”。用户通常对DOS stub 不感兴趣,因为大多数情况下他们由汇编器自动生成。平常把DOS stub和DOS MZ头部合称为DOS文件头。

PE文件的第一个字节起始于一个传统的MS-DOS头部,被称作IMAGE_DOS_HEADER。其IMAGE_DOS_HEADER的结构如下(左边的数字是到文件头的偏移量):

IMAGE_DOS_HEADER STRUCT

{

+0h WORD e_magic   // Magic DOS signature MZ(4Dh 5Ah)     DOS可执行文件标记

+2h   WORD  e_cblp  // Bytes on last page of file

+4h WORD  e_cp   // Pages in file

+6h WORD  e_crlc   // Relocations

+8h WORD  e_cparhdr   // Size of header in paragraphs

+0ah WORD  e_minalloc  // Minimun extra paragraphs needs

+0ch WORD  e_maxalloc  // Maximun extra paragraphs needs

+0eh WORD  e_ss    // intial(relative)SS value      DOS代码的初始化堆栈SS

+10h WORD  e_sp    // intial SP value                 DOS代码的初始化堆栈指针SP

+12h WORD  e_csum    // Checksum

+14h WORD  e_ip    //    intial IP value                     DOS代码的初始化指令入口[指针IP]

+16h WORD  e_cs    // intial(relative)CS value                    DOS代码的初始堆栈入口

+18h WORD  e_lfarlc    // File Address of relocation table

+1ah WORD  e_ovno        //    Overlay number

+1ch WORD  e_res[4]    // Reserved words

+24h WORD  e_oemid    //    OEM identifier(for e_oeminfo)

+26h WORD      e_oeminfo   //    OEM information;e_oemid specific

+29h WORD  e_res2[10]   //    Reserved words

+3ch DWORD   e_lfanew     // Offset to start of PE header             指向PE文件头

} IMAGE_DOS_HEADER ENDS

这个结构中有两字段很重要,一个是e_magic,一个是e_lfanew。e_magic(一个字大小)字段需要被设置为5A4Dh这个也是PE程序载入的重要标志,这个值非常有意思,他们对应的字符分别位Z和M,是为了纪念MS-DOS的最初创建者Mark Zbikowski而专门设置的,由于在hex编辑器中显示是由低位到高位故显示为4D5Ah,刚好是创建者的名字缩写。另一个字段是e_lfanew。这个字段表示的是真正的PE文件头部相对偏移地址(RVA),它指出了真正PE头部文件偏移位置。它占用四个字节,位于文件开始偏移的3ch字节中。

下面我将用hexworkshop打开一个pe文件向大家展示一下上面这段话的含义。

第一张图说明的就是IMAGE_DOS_HEADER的第一个字段e_magic的值与地址。第二张图就是上面所讲的第二个关键字段e_fannew字段的值(注意:不同的PE程序这个值可能不一样,但原理一样),这个值就是PE头文件的起始偏移量。

2)PE文件头文件

相对于MS-DOS头文件,PE头文件PEheader要复杂的多,下面将详细讲解其中的几个字段。

紧跟着DOS头文件下面的就是peheader。PEheader是PE相关结构NT映像头(IMAGE_NT_HEADER)的简称,其中包含许多PE装载器用到的重要字段。执行体在支持PE文件结构的操作系统执行时,PE装载器将IMAGE_DOS_HEADER结构中的e_fanew字段找到PEheader的起始偏移量,加上基址得到PE文件头的指针:

PNTHeader=IMAGBase+dosHeader->e_lfanewr(其实就是去字段e_lfanew的值)。

下面来讨论IMAGE_NT_HEADER的结构,它是由三个字段组成(左边的数字是PE文件头的偏移量):IMAGE_NT_HEADER STRUCT

{

+0h Signature  DWORD              //PE文件标志

+4h FileHeader IMAGE_FILE_HEADER  //文件头初始偏移地址

+18 optionalHeader IMAGE_OPTION_HEADER //另一个重要头部初始偏移地址

} IMAGE_NT_HEADER ENDS

下面对这三个字段逐个详细分析:

  1. Signature字段

这个字段是PE文件的标志字段,通常设置成00004550h,其ASCII码为PE00,这个字段是PE文件头的开始,前面的DOS_HEADER结构中的字段e_lfanew字段就是指向这里。

2.IMAGE_FILE_HEADER字段

这个字段也是包含几个字段结构,它包含了PE文件的一些基本信息,最重要的是其中一个域指出了IMAGE_OPTIONAL_HEADER的大小。

typedef struct _IMAGE_FILE_HEADER {

WORD Machine;//运行平台

WORD NumberOfSections;//文件的区块数目

DWORD TimeDateStamp;//文件创建的用时间戳标识的日期

DWORD PointerToSymbolTable;//指向符号表(用于调试)

DWORD NumberOfSymbols;//符号表中符号的个数

WORD SizeOfOptionalHeader;//IMAGE_OPTIONAL_HEADER32结构大小

WORD Characteristics;//文件属性

} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

上图标出七个字段的位置及各自的值。

1)Machine字段,表示目标CPU 的类型。

几个常见的及其标识如下:

机器              标识

Intel I386          14ch

MIPS R3000        162h

Alpha AXP          184h

Power PC           1F0h

MIPS R4000         184h

根据以上信息我们知道这个PE文件要运行在Intel I386机器上。

2)NumberOfSection,标识区块的数目,关于区块后面会详细讲。

3)TimeDateStamp

这个字段没啥好说的,指的就是PE文件创建的事件,这个时间是指从1970年1月1日到创建该文件的所有的秒数。

4)PointerToSymbolTable。这个字段用的比较少,略

5)NumberOfSymbol。这个字段也用得很少,略

6)SizeOfOptionalHeader:紧跟着IMAGE_FILE_HEADER后面的数据大小,这也是一个数据结构,它叫做IMAGE_OPTIONAL_HEADER,其大小依赖于是64位还是32位文件。32位文件值通常是00EOh,对于64位值通常为00F0h。

7)Characteristics:文件属性,普通EXE文件这个字段值为010fh,DLL文件这个字段一般是0210h。

下一篇将从字段IMAGE_OPTIONAL_HEADER讲起。

PE文件格式详解(一)的更多相关文章

  1. PE文件格式详解,第一讲,DOS头文件格式

    PE文件格式详解,第一讲,DOS头文件格式 今天讲解PE文件格式的DOS头文件格式 首先我们要理解,什么是文件格式,我们常说的EXE可执行程序,就是一个文件格式,那么我们要了解它里面到底存了什么内容 ...

  2. PE文件格式详解,第二讲,NT头文件格式,以及文件头格式

    PE文件格式详解,第二讲,NT头文件格式,以及文件头格式 作者:IBinary出处:http://www.cnblogs.com/iBinary/版权所有,欢迎保留原文链接进行转载:) PS:本篇博客 ...

  3. PE文件格式详解,第三讲,可选头文件格式,以及节表

    PE文件格式详解,第三讲,可选头文件格式,以及节表 作者:IBinary出处:http://www.cnblogs.com/iBinary/版权所有,欢迎保留原文链接进行转载:) 一丶可选头结构以及作 ...

  4. PE文件格式详解(七)

    PE文件格式详解(七)   Ox00 前言 前面好几篇在讲输入表,今天要讲的是输出表和地址的是地址重定位.有了前面的基础,其实对于怎么找输出表地址重定位的表已经非常熟悉了.   0x01 输出表结构 ...

  5. PE文件格式详解(下)

    作者:MSDN译者:李马 预定义段 一个Windows NT的应用程序典型地拥有9个预定义段,它们是.text..bss..rdata..data..rsrc..edata..idata..pdata ...

  6. PE文件格式详解(上)

    作者:MSDN 译者:李马 摘要 Windows NT 3.1引入了一种名为PE文件格式的新可执行文件格式.PE文件格式的规范包含在了MSDN的CD中(Specs and Strategy, Spec ...

  7. PE 文件格式详解

    PE文件 是微软 Win32 环境下可执行文件的标准格式. 所谓的可执行文件并不仅仅是常见的 EXE 文件,DLL,SYS,VXD 等文件也都属于 PE 格式. |-------> DOS_MZ ...

  8. PE文件格式详解(六)

    0x00 前言 前面两篇讲到了输出表的内容以及涉及如何在hexWorkShop中找到输出表及输入DLL,感觉有几个地方还是没有理解好,比如由数据目录表DataDirectory[16]找到输出表表后以 ...

  9. PE文件格式详解(八)

    0x00 前言 前面了解了PE文件的输入和输出,今天来看看另一个重要的结构——资源.资源结构是很典型的树形结构,层层查找,最终找到资源位置. 0x01 资源结构介绍 Windows程序的各种界面成为资 ...

随机推荐

  1. PMBOK 基础知识(1)

    启动.结束过程 项目管理计划 第一章  引论 第2章项目运行环境 第3章 项目经理的角色 第4章 项目整合管理 第5章 项目范围管理 第6章 项目进度管理 第7章 项目成本管理 第8章 项目质量管理  ...

  2. 有没有人想和我一起编写 Clear Writer 的?

    合作内容 程序编写 了解 JS.HTML.CSS 等基础前端技能,了解 Electron 开发. 翻译 熟练运用一门外语(中文英文除外),书面表达过关. 报酬 在 Github 上本项目里面的 REA ...

  3. asp.net Mvc 路由详解,非常详细.

    关于路由的理解 为什么要定义路由?路由的定义在开发中的工作量非常小,但是非常重要,因为任何请求都离不开路由. 各个电商网站的 URL 使用非常灵活,都离不开路由的定义,请大家参考几家电商的 URL 如 ...

  4. 其他函数-web_get_int_property

    用于记录http响应的信息.这个函数在调试脚本的常用,但是在实际压力测试中请将这些注释 使用这个函数可以获取到的信息有: 1.HTTP_INFO_RETURN_CODE:返回HTTP响应码 2.HTT ...

  5. 使用Bundle在Activity中交换数据

    大概过程 编写demo activity_main.xml <?xml version="1.0" encoding="utf-8"?> <R ...

  6. jmeter的beanshell

    [beanshell] 简单介绍beanshell,小型的java源代码解释器 运行下beanshell [常用命令] print() 输出内容到命令行中 (1)也可以在beanshell中自定义 [ ...

  7. 获取系统的IP地址

    获取linux主机的IP地址 问题描述 在很多软件配置过程中,都需要设置ID信息,通常我选择使用系统配置的eth0网卡的IP地址信息,比如salt-minion-id,在通过cobbler批量安装操作 ...

  8. int与Integer的区别(基本类型与复杂类型的对比)转

    基本类型,或者叫做内置类型,是JAVA中不同于类的特殊类型. Java中的简单类型从概念上分为四种:实数.整数.字符.布尔值.但是有一点需要说明的是,Java里面只有八种原始类型,其列表如下: 实数: ...

  9. es性能调优---写优化操作

    ES 的默认配置,是综合了数据可靠性.写入速度.搜索实时性等因素.实际使用时,我们需要根据公司要求,进行偏向性的优化. 写优化 假设我们的应用场景要求是,每秒 300 万的写入速度,每条 500 字节 ...

  10. BERT的前世今生

    Transformer Transformer来自论文: All Attention Is You Need 别人的总结资源: 谷歌官方AI博客: Transformer: A Novel Neura ...