PE文件介绍 (2)-DOS头,DOS存根,NT头
PE头
PE头由许多结构体组成,现在开始逐一学习各结构体
0X00 DOS头
微软创建PE文件格式时,人们正广泛使用DOS文件,所以微软充分考虑了PE文件对DOS文件的兼容性。其结果是在PE头的最前面添加一个 IMAGE_DOS_HEADER 结构体用来扩展DOSEXE头
IMAGE_DOS_HEADER
typedef struct _IMAGE_DOS_HEADER
{
WORD e_magic; //DOS签名 4D5A
WORD e_cblp;
WORD e_cp;
WORD e_crlc;
WORD e_cparhdr;
WORD e_minalloc;
WORD e_maxalloc;
WORD e_ss;
WORD e_sp;
WORD e_csum;
WORD e_ip;
WORD e_cs;
WORD e_lfarlc;
WORD e_ovno;
WORD e_res[4];
WORD e_oemid;
WORD e_oeminfo;
WORD e_res2[10];
LONG e_lfanew; //指向NT头所在的位置
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
IMAGE_DOS_HEADER 结构体的大小位64字节,一个WORD类型两个字节时一个字,一个LONG类型是四个字节两个字,所以该结构体为 30个WORD类型+ 1个LONG类型 为 64字节。
在该结构体中必须知道2个重要的成员:e_magic 与 e_lfanew
- e_magic: DOS签名(4D5A => ASCLL值 “MZ”)
- e_lfanew: 指示NT头的偏移(不同的文件该值不一样)
0X01 使用Hxd在电脑中查看PE格式
把炉石传说的客户端放入Hxd软件中查看

从图中可以看出标黄的是DOS签名4D5A为MZ,整个红框为 DOS头64个字节,最底下绿色框标出来的为NT文件头所在位置 0X00000120 Intel系列CPU以逆序存储数据,这称为小端序标识法。这些是值被修改后将不能够运行(根据PE规范,它以不再是PE文件)。
0X02 DOS存根
DOS存根在DOS头下面,是个可选项,且大小不固定(即使没有DOS存根,文件也能正常运行)DOS存根由代码与数据混合而成下图为炉石传说的客户端的DOS存根

DOS存根的大小不固定,从0x40开始到NT头截至。图中文件偏移40-4D区域为16位汇编指令。32位windows OS中直接忽略该命令。
0X03 NT头
下面介绍NT头 IMAGE_NT_HEADERS
代码:IMAGE_NT_HEADERS
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature; //PE签名 504500 => ("PE"00)
IMAGE_FILE_HEADER FileHeader; //文件头
IMAGE_OPTIONAL_HEADER32 OptionalHeader; //可选文件头
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
IMAGE_NT_HEADERS 结构体由三个成员组成,第一个成员为签名(Signature)结构体,其值为50450000h("PE"00)。另外两个成员分别为文件头与可选头。
在hxd中查看NT头

从图上可以看出DOS头的最后一个结构是指向NT头的0X0120,0X0120的前4个字节存储的是签名。
IMAGE_NT_HEADERS结构体的大小为F8,相当大。下面分别说明文件头和可选头结构体。
0X030 NT头:文件头
文件头是NT头第二个结构,文件头是表现文件大致属性的 IMAGE_FILE_HEADER
代码:IMAGE_FILE_HEADER
typedef struct _IMAGE_FILE_HEADER {
WORD Machine;
WORD NumberOfSections;
DWORD TimeDateStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
IMAGE_FILE_HEADER 结构体中有一下四种重要成员(若它们设置不正确,将导致文件无法运行)。
(1) Machine
每个CPU都拥有唯一的Machine码,兼容32位Intel x86芯片的Machine码为14C.
是定义在winnt.h文件中的Machine码。
(2) NumberOfSections
PE文件把代码,数据,资源等依据属性分类到各节区中存储。NumberOfSections用来指出文件中存在的节区数量。该值一定要大于0,且当定义的节区数量和实际节区不同时,将发生运行错误。
(3) SizeOfOptionalHeader
IMAGE_NT_HEADERS 结构体的最后一个成员为 IMAGE_OPTIONAL_HEADER32 结构体。SizeOfOptionalHeader 成员用来指出IMAGE_OPTIONAL_HEADER32 结构体的长度。IMAGE_OPTIONAL_HEADER32 结构体由C语言编写而成,故其大小已经确定。但是windows的PE装载器需要查看 IMAGE_NT_HEADERS 的SizeOfOptionalHeader值,从而识别出IMAGE_OPTIONAL_HEADER32 结构体的大小。
PE32+格式的文件中使用的是IMAGE_OPTIONAL_HEADER64 结构体,而不是IMAGE_OPTIONAL_HEADER32 结构体。2个结构体尺寸是不同的,所以需要在SizeOfOptionalHeader 成员中指明结构体的大小。
(4) Characteristics
该字段用于标识文件的属性,文件是否是可运行的形态,是否为DLL文件等信息,以二进制位的方式进行组合。
以下是定义在winnt.h文件中的Characteristics值
| Macro | Value | Meaning |
|---|---|---|
| IMAGE_FILE_RELOCS_STRIPPED | 0x0001 | Relocation information was stripped from the file. The file must be loaded at its preferred base address. If the base address is not available, the loader reports an error. |
| IMAGE_FILE_EXECUTABLE_IMAGE | 0x0002 | The file is executable (there are no unresolved external references). |
| IMAGE_FILE_LINE_NUMS_STRIPPED | 0x0004 | COFF line numbers were stripped from the file. |
| IMAGE_FILE_LOCAL_SYMS_STRIPPED | 0x0008 | COFF symbol table entries were stripped from file. |
| IMAGE_FILE_AGGRESIVE_WS_TRIM | 0x0010 | Aggressively trim the working set. This value is obsolete. |
| IMAGE_FILE_LARGE_ADDRESS_AWARE | 0x0020 | The application can handle addresses larger than 2 GB. |
| IMAGE_FILE_BYTES_REVERSED_LO | 0x0080 | The bytes of the word are reversed. This flag is obsolete. |
| IMAGE_FILE_32BIT_MACHINE | 0x0100 | The computer supports 32-bit words. |
| IMAGE_FILE_DEBUG_STRIPPED | 0x0200 | Debugging information was removed and stored separately in another file. |
| IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP | 0x0400 | If the image is on removable media, copy it to and run it from the swap file. |
| IMAGE_FILE_NET_RUN_FROM_SWAP | 0x0800 | If the image is on the network, copy it to and run it from the swap file. |
| IMAGE_FILE_SYSTEM | 0x1000 | The image is a system file. |
| IMAGE_FILE_DLL | 0x2000 | The image is a DLL file. While it is an executable file, it cannot be run directly. |
| IMAGE_FILE_UP_SYSTEM_ONLY | 0x4000 | The file should be run only on a uniprocessor computer. |
| IMAGE_FILE_BYTES_REVERSED_HI | 0x8000 | The bytes of the word are reversed. This flag is obsolete. |
另外,PE文件中Characteristics的值有可能不是002h吗(不可执行)?也是有可能的,比如类似*.obj的object文件及resource DLL文件等。
(5) TimeDateStamp
该成员的值不影响文件运行,用来记录编译器创建此文件的时间。有些开发工具(VB,VC++)提供了设置该值的工具。而有些开发工具(Delphi)未提供。
0X031 NT头:使用hxd查看炉石传说客户端文件头

文件头有 四个 WORD 型和三个DWORD型组成 42+34=20 一共占了20个字节
从图上可以看出:
| 名称 | 位置(偏移量) | 数据值 | 含义 |
|---|---|---|---|
| machine码 | 0x0124 | 014C | Interl 386 |
| NumberOfSections | 0x0126 | 0005 | 存在5个节区 |
| TimeDateStamp | 0x0128 | 5B89C5B2 | 2018/08/31 22:48:18 |
| SizeOfOptionalHeader | 0x0134 | 00E0 | IMAGE_OPTIONAL_HEADER32的大小为E0 |
| Characteristics | 0X0136 | 0x0102 | 是32位的文件 and 是可执行文件 |
最后一个数值 0x0102 可以看作是 0x100 | 0x002 为 IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_32BIT_MACHINE
PE文件介绍 (2)-DOS头,DOS存根,NT头的更多相关文章
- PE文件介绍 (1)
PE文件介绍 PE文件主要是windows操作系统下使用的可执行文件格式,PE文件是指32位的可执行文件也叫做PE32,64位可执行文件叫做PE+或者PE32+ PE文件格式 种类 主扩展名 可执行类 ...
- PE 学习之路 —— DOS 头、NT 头
1. 前述 可执行文件的格式是操作系统本身执行机制的反映,理解它有助于对操作系统的深刻理解,掌握可执行文件的数据结构及其一些机理,是研究软件安全的必修课.`PE(Portable Executable ...
- PE文件格式详解,第二讲,NT头文件格式,以及文件头格式
PE文件格式详解,第二讲,NT头文件格式,以及文件头格式 作者:IBinary出处:http://www.cnblogs.com/iBinary/版权所有,欢迎保留原文链接进行转载:) PS:本篇博客 ...
- 第二讲,NT头文件格式,以及文件头格式
今天详解NT 头格式,以及文件头格式,以及作用, 关于DOS头文件格式,以及DOSStub昨天的博客已经写过了.主要是分散讲解.便于理解. 一丶最小PE的生成,以及标准PE的生成 ps: (如果直接学 ...
- PE文件学习系列二 DOS头分析
合肥程序员群:49313181. 合肥实名程序员群 :128131462 (不愿透露姓名和信息者勿加入)Q Q:408365330 E-Mail:egojit@qq.com PE文件结 ...
- PE文件格式详解,第一讲,DOS头文件格式
PE文件格式详解,第一讲,DOS头文件格式 今天讲解PE文件格式的DOS头文件格式 首先我们要理解,什么是文件格式,我们常说的EXE可执行程序,就是一个文件格式,那么我们要了解它里面到底存了什么内容 ...
- PE文件学习(1)DOS和NT
大致结构 DOS头和NT头之间通常还有个DOS Stub DOS头 DOS头的作用是兼容MS-DOS操作系统中的可执行文件 一般没啥用 记录着PE头的位置 DOS头定义部分 typedef struc ...
- PE文件学习系列三-PE头详解
合肥程序员群:49313181. 合肥实名程序员群:128131462 (不愿透露姓名和信息者勿加入) Q Q:408365330 E-Mail:egojit@qq.com 最近比较忙 ...
- C/C++ 介绍的PE文件遍历工具
在前面的笔记中,我总结了Pe结构的一些结构含义,并手动编写了几段PE结构遍历代码,这里我直接把之前的C语言代码进行了封装,形成了一个命令行版的PE文件查看工具,该工具只有20kb,但却可以遍历出大部分 ...
随机推荐
- Linux的svn服务器搭建
最近把Linux上的一些服务器学习了一遍 我这里更新一下笔记——SVN服务器 我从其他博主上学习了一下——转载https://www.cnblogs.com/mymelon/p/5483215.htm ...
- Flow Control
Exercise-01 Max Of Two Numbers Write a function that takes two numbers and returns the maximum of th ...
- #!/usr/bin/python
它是用来指定用什么解释器运行脚本以及解释器所在的位置. 参考链接:https://www.cnblogs.com/qmfsun/p/6291982.html
- SpringMVC笔记总结
文章所有代码见:gitee 1.回顾MVC 1.1.什么是MVC MVC是模型(Model).视图(View).控制器(Controller)的简写,是一种软件设计规范. 是将业务逻辑.数据.显示分离 ...
- vue过渡动画样式
在进入/离开的过渡中,会有 6 个 class 切换. v-enter:定义进入过渡的开始状态.在元素被插入之前生效,在元素被插入之后的下一帧移除. v-enter-active:定义进入过渡生效时的 ...
- Python的自定义属性访问跟描述器以及ORM模型的简单介绍
一 . 自定义属性访问 1.__getattr__ 作用:当我们访问属性的时候,如果属性不存在(出现AttrError),该方法会被触发. 2.__getattribute__ 作用:访问属性的时候, ...
- 彻底理解JavaScript ES6中的import和export
0.前言 前端工程,在最早的时候是没有模块的概念的.随着前端工程的发展,前端开发也越来越规范化,更像是软件工程了.那么随之而来的,为了解决工程化的问题,就引入了模块的概念.但是在早期,因为ecmasc ...
- Linux实验
实验一 Linux系统安装与简单配置 一.实验目的 1.掌握Linux系统安装的分区准备. 2.掌握Linux系统的安装步骤. 3.掌握Linux系统分区的挂载和卸载. 4.掌握Linux系统的启动和 ...
- [验证码识别技术] 字符型验证码终结者-CNN+BLSTM+CTC
验证码识别(少样本,高精度)项目地址:https://github.com/kerlomz/captcha_trainer 1. 前言 本项目适用于Python3.6,GPU>=NVIDIA G ...
- Java 第十一届 蓝桥杯 省模拟赛 小明植树(DFS)
小明植树 题目 问题描述 小明和朋友们一起去郊外植树,他们带了一些在自己实验室精心研究出的小树苗. 小明和朋友们一共有 n 个人,他们经过精心挑选,在一块空地上每个人挑选了一个适合植树的位置,总共 n ...