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,但却可以遍历出大部分 ...
随机推荐
- 【项目练习】thinkphp用户注册
使用mvc,ajax 路由 //后台登陆 Route::group('admin', function () { Route::rule('login', 'admin/Index/login'); ...
- Java-LinkedList围圈的人名
import java.util.*; public class Example12_7 { public static void main(String[] args) { int m=5; Lin ...
- JavaScript计时
JavaScript计时分两种 setTimeout:程序在隔几秒后执行 语法: setTimeout(function(){要执行的程序},xxxx) setInterval:程序每隔几秒执行 语法 ...
- iOS开发判断手机号及其运营商
根据三大运营商出现的号段(号段来自百度百科) 判断是否是手机号 + (BOOL)isMobile:(NSString *)str { NSString *MOBILE = @"^1(3[0- ...
- JVM调优总结(五)-典型配置举例
以下配置主要针对分代垃圾回收算法而言. 堆大小设置 年轻代的设置很关键 JVM中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制:系统的可用虚拟内存限制:系统的可用物理 ...
- [JavaWeb基础] 030.dom4j读取xml的4种方法
通常我们在项目开发的过程中经常要操作到xml文件,在JAVA这边,我们会很自然的联想到Dom4J这个apache的开源插件,那么我们使用Dom4J如何来读取xml文件呢?下面我们来看看以下4种方法 1 ...
- LDA模型笔记
“LDA(Latent Dirichlet Allocation)模型,模型主要解决文档处理领域的问题,比如文章主题分类.文章检测.相似度分析.文本分段和文档检索等问题.LDA主题模型是一个三层贝叶斯 ...
- 01 . 分布式存储之FastDFS简介及部署
分布式存储简介 现代的互联网已经进入大数据时代,每天都有数以万计的数据产生,这些数据的规模轻轻松松地可以达到几P的级别,传统的的单机存储早已捉襟见肘,根本无法满足大数据对存储系统的要求.这时,各种分布 ...
- hexo搭建个人网站及hexo+nginx部署个人网站
先放个配置好了 server { # 监听端口 listen ; # 监听ip 换成服务器公网IP server_name mr-lin.site; location / { root /web/my ...
- 学习使用pyquery解析器爬小说
一.背景:个人喜欢在网上看小说,但是,在浏览器中阅读小说不是很方便,喜欢找到小说的txt版下载到手机上阅读,但是有些小说不太好找txt版本,考虑自己从网页上爬一爬,自己搞定小说的txt版本.正好学习一 ...