这一章的上半部分大体介绍了下PE文件头,下半部分是详细介绍里面的内容,这一章一定要多读几遍,好好记记基础概念和知识,方便之后的学习。

简单回忆一下:

3.4  PE文件头部解析

3.4.1 DOS MZ头
IMAGE_DOS_HEADER

DOS MZ头的下面是DOSS Stub。整个DOSS Stub是一个字节块,其内容随着链接时使用的连接器不同而不同,PE中没有与之对应的相关结构。

3.4.2 PE头标识Signature

紧跟在DOS Stub后面的是PE头标识Signature。与大部分分支文件格式的头部结构一样,PE头部信息中有一个四字节的标识,该标识位于指针IMAGE_DOS_HEANDER.e_lfanew指向的位置。其内容固定,对应于ASCII码的字符串”PE\0\0”

3.4.3  标准PE头IMAGE_FILE_HANDER

标准PE头IMAGE_FILE_HEADER紧跟在PE头标识后,即位于IMAGE_DOS_HEADER的e_lfanew值+4的位置。由此位置开始的20个字节为数据结构标准PE头IMAGE_FILE_HEANDER的内容。该结构在微软的官方文档中被称为标准通用对象文件格式(Common
Object File Format,COFF)头,它记录了PE文件的全局属性,该PE文件运行的平台、PE文件类型(是EXE还是DLL文件)、文件中存在的节的总数,其详细定义如下:

该结构常用于判断PE文件是EXE还是DLL类型,不但可以通过该结构得到PE文件中节的数量,还可以当成对接信息进行遍历操作时的循环次数。

3.4.4  扩展PE头IMAGE_OPTIONAL_HEADER32

尽管从名字上看好像该部分数据是可选的,但在PE文件结构中,它却有着比标准PE头更多的内容。详细定义如下:

文件执行时的入口地址、文件被操作系统装入内存后的默认基地址,以及节在磁盘和内存中的对齐单位等信息均可以在此结构中找到。对于该结构中的某些数值的随意改动可能造成对PE文件的加载或运行失败。

3.4.5 PE头IMAGE_NT_HEADERS

这个结构是广义上的PE头,在标准的PE文件中器大小为456个字节。它是3.4.2节、3.4.3节和3.3.4节中提到的三个数据结构的组合,即

IMAGE_NT_HEADERS=4个字节的PE标识  +
  IMAGE_FILE_HEADER +IMAGE_OPTIONAL_HEADER32:

该结构定义如下(汇编):

IMAGE_NT_HEADERS STRUCT

Signature DWORD ?   ;0000h                       -PE文件标识,”PE\0\0”

FileHeader IMAGE_FILE_HEADER <> ;0004h             -PE标准头

OptionalHeader IMAGE_OPTIONAL_HEADER32<>;0018h  -PE扩展头

IMAGE_NT_HEADERS ENDS

3.4.6  数据目录项IMAGE_DATA_DIRECTORY

IMAGE_OPTIONAL_HEADER32(扩展PE头)结构的最后一个字段位DataDirectory。

该字段定义了PE文件中出现的所有不同类型的目录信息。如前所述,应用程序中的数据被按照用途分成很多种类,如导入表、导出表、资源、重定位表等。在内存中,这些数据被操作系统以页位单位组织起来,并赋以不同的访问属性;在文件中,这些数据也同样被组织起来,按照不同的类别分别放在文件的指定位置。该结构就是用来描述这些不同类别的数据在文件(和内存)中的位置及大小的,因为这个字段比较重要。

从Windows NT 3.1
操作系统开始到现在,该数据目录中定义的数据类型一直是16种。PE中使用了一种称作“数据目录项IMAGE_DATA_DIRECTORY”的数据结构来定义每种数据。该结构只有两个字段,结构具体定义如下:

IMAGE_DATA_DIRECTORY STRUCT

VirtualAddress DWORD ? ;000h -
数据其实RVA

isize DWORD ?         ;004h -
数据块的长度

IMAGE_DATA_DIRECTORY ENDS

两个字段依次为VirtualAddress
和 isize。如图3-11所示,总的数据目录一共由16个相同的IMAGE_DATA_DIRECTORY结构连续排列在一起组成。

这16个元组的没组每一项均代表PE中的某一个类型的数据,各数据类型详见表3-1。

如果想在PE文件中寻找特定类型的数据,就需要从该结构开始。比如,要想查看PE中都调用了哪些动态间接库的函数,则需要从数据目录表的第2个元素的IMAGE_DATA_DIRECTORY结构获取导入表在文件中的起始位置和大小,然后再根据VirtualAddress_1地址指向的位置找到导入表相关的字节码。这种信息组织方式正式本章开始的“头部+身体”的数据组织方式。

下面是这16个数据目录项依次展开后的新结构:

3.4.7  节表项IMAGE_SECTION_HEADER

PE头IMAGE_NT_HEADERS后面紧跟着节表。它由许多节表项(IMAGE_SECTION_HEADER)组成,每个节表项纪录了PE中与某个特定节有关的信息,如节的属性、节的大小、在文件和内存中的起始位置等。节表中节的数量有字段IMAGE_FILE_HEADER.NumberOfSections来定义。

节表项的数据结构详细定义如下:

节表后面就是节的内容。截至节表,PE文件头设计的所有数据结构已经全部介绍完毕。接下来,集中对以上所有数据结构中每个字段进行详细介绍。

Windows Pe 第三章 PE头文件(中)的更多相关文章

  1. Windows Pe 第三章 PE头文件(上)

    第三章  PE头文件 本章是全书重点,所以要好好理解,概念比较多,但是非常重要. PE头文件记录了PE文件中所有的数据的组织方式,它类似于一本书的目录,通过目录我们可以快速定位到某个具体的章节:通过P ...

  2. Windows Pe 第三章 PE头文件(下)

    3.5  数据结构字段详解 3.5.1  PE头IMAGE_NT_HEADER的字段 1.IMAGE_NT_HEADER.Signature +0000h,双字.PE文件标识,被定义为00004550 ...

  3. Windows Pe 第三章 PE头文件-EX-相关编程-2(RVA_FOA转换)

    RVA-FOA之间转换 1.首先PE头加载到内存之后是和文件头内容一样的,就算是偏移不同,一个是磁盘扇区大小(400H)另一个是内存页大小(1000H),但是因为两个都是开头位置,所以相同. 2.看下 ...

  4. Windows Pe 第三章 PE头文件-EX-相关编程-1(PE头内容获取)

    获取pE头相关的内容,就是类似如下内容 原理:比较简单,直接读取PE到内存,然后直接强转就行了. #include <windows.h> #include <stdio.h> ...

  5. Android JNI入门第三篇——jni头文件分析

    一. 首先写了java文件: public class HeaderFile { private native void  doVoid(); native int doShort(); native ...

  6. C++-模板的声明和实现为何要放在头文件中

    源: http://blog.csdn.net/lqk1985/archive/2008/10/24/3136364.aspx 如何组织编写模板程序 发表日期: 1/21/2003 12:28:58 ...

  7. C ++模板的声明和实现为何要放在头文件中?

    源: http://blog.csdn.net/lqk1985/archive/2008/10/24/3136364.aspx 如何组织编写模板程序 发表日期: 1/21/2003 12:28:58 ...

  8. c语言头文件中定义全局变量的问题

    c语言头文件中定义全局变量的问题 (转http://www.cnblogs.com/Sorean/) 先说一下,全局变量只能定义在 函数里面,任意函数,其他函数在使用的时候用extern声明.千万不要 ...

  9. 在头文件中声明class 类 与 include类所在的头文件区别---理解

    在头文件中声明class 类 与 include类所在的头文件的理解: 在头文件中,声明类 它告诉编译器:存在这样的类.而实际的类则可以位于同一个编译单元中,也可以放在其他编译单元中.没有这个类原型, ...

随机推荐

  1. Centos mini系统下的Hadoop集群搭建

    1.事前了解 1.1 Hadoop 百度百科:https://baike.baidu.com/item/Hadoop/3526507?fr=aladdin Hadoop是一个由Apache基金会所开发 ...

  2. url里bookmark是什么意思

    <a rel="bookmark" href="abc.com"> 点击查看 </a> rel 这个属性的全称是  relationsh ...

  3. Python字典与集合

    一 字典创建.访问.添加.删除.修改.内建函数.内建方法 创建,列表不能作为键,因为键不能变?字典也不能作为键 dict1 = {} dict2 = {'name':'qq','sex':'male' ...

  4. vue全家桶和react全家桶

    vue全家桶:vue  +  vuex (状态管理)  + vue-router (路由) + vue-resource +axios +elementui react全家桶 : react + re ...

  5. EntityFrameworkCore之工作单元的封装

    1. 简介 2. DbContext 生命周期和使用规范 2.1. 生命周期 2.2. 使用规范 2.3. 避免 DbContext 线程处理问题 3. 封装-工作单元 3.1. 分析 3.2. 设计 ...

  6. 【ZeyFraのJavaEE开发小知识05】Mybatis-Plus & Axios

    关于如何在Mybatis-Plus中添加SQL拦截器 之前ZeyFra在MyBatis-Plus[踩坑记录01]一文中提到过,使用Mybatis-Plus时最好使用MybatisSqlSessionF ...

  7. python3 中is和==的区别

    is    身份运算符,用来判断对象是否属于同一地址 (python内置函数id() 可以返回对象地址) ==  比较运算符,用于判断值是否相同

  8. LinkedList类详解

    LinkedList类中的方法与实现原理 目录 一.数据结构 二.类标题 三.字段 四.构造函数 五.方法分析 5.1 共有方法 public boolean add(Object o) public ...

  9. Python3实现短信轰炸机

    短信轰炸机的基本原理:利用某些限制不严格的网站短信注册接口,用Python模拟请求,传入被炸人手机号码,实现轰炸 实现方式:利用requests模块.time模块.完成请求模拟 模块安装: 在终端窗口 ...

  10. ECMAScript 2018(ES9)新特性简介

    目录 简介 异步遍历 Rest/Spread操作符和对象构建 Rest Spread 创建和拷贝对象 Spread和bject.assign() 的区别 正则表达式 promise.finally 模 ...