PE文件笔记一 PE介绍
近期发现了一个超牛逼的大佬,和大佬写的超详细的pe总结,所以就根据(抄袭)大佬文章做一些pe总结来巩固学习。
可执行文件的格式
Windows平台
PE(Portable Executable)文件结构
Linux平台
ELF(Executable and Linking Format)文件结构
常见的可执行文件
.exe .dll .sys都是windows下常见的可执行文件。(他们都遵循pe文件结构大二的格式)
常见的非可执行文件
- .txt .png .mp4等等都是非可执行文件,它们都需要使用其它可执行文件的软件进行加载
- .txt可以使用Notepad、UltraEdit等 文本 工具查看
- .png可以使用PhotoShop等 图片 工具查看
- .mp4可以使用PotPlayer等 播放器 工具查看
为什么要学习pe
- pe是windows下可执行文件必须遵循的规范
- 对软件的加壳与脱壳都基于pe
- EXE文件如何加载到内存中也涉及PE的知识
- 一个合格的逆向人员,必须熟悉PE
如何识别pe文件
不管是.exe .dll还是.sys ,他们都是pe文件,所以他们的前两个字节一定都是4D 5A(ASCII码为MZ)
我们用winhex打开三种文件观察一下(这里直接没用大佬的三张图)
3Ch位置的数据(不做总结了)
小总结
如果一个文件,它的头两个字节为4D 5A(ASCII码为MZ),并且通过3Ch位置的数据再找到的位置里的数据为PE则基本可以断定这个文件是Windows下的可执行文件(满足PE结构)
反例
随便拉一个图片png文件进来看看
很显然,开头的两个字节就已经表明它不是一个PE文件了
PS:识别可执行文件不能通过文件的后缀名来判断,而应该采用上述的方式进行判断,因为后缀名是可以改的。
通过前面列举的知识,我们已经知道如何识别一个pe文件了,但是为什么是查看一个文件的前2个字节和3Ch的位置,以及其它位置数据作用呢。
这便是PE结构所规定的
下面是PE文件的总体结构
可以看到先前判断PE文件特征里的头两个字节对应这里的文件头:DOS ‘MZ’ HEADER
后面根据3Ch得到的50 45(对应ACSII码为PE)对应这里的PE文件头中的”PE”
(接下来是重点)
pe在c中的定义
pe文件结构自然也是一种数据结构(比较复杂的数据结构)
在c语言中的winnt.h这个头文件中定义了pe文件结构相关的结构体。
所以我们可以直接通过c语言中的pe的定义来更好的学习pe
(直接cv大佬)
随便创建一个空的控制台项目,然后引入winnt.h这个头文件
|
如下图
然后在引入的头文件处右键转到文档
接下来大佬就会根据这个头文件来学习pe文件的总体结构了
DOS部首
该部分结构对应winnt.h中的**_IMAGE_DOS_HEADER**结构体
可以在先前打开的winnt.h中Ctrl+F搜索_IMAGE_DOS_HEADER
查找后得到
这里贴上大佬提出来的字段
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header |
这里我们只需要关注这两个字段就好了
WORD e_magic * "MZ标记" 用于判断是否为可执行文件. |
PE文件头(NT头)
该部分结构对应winnt.h中的**_IMAGE_NT_HEADERS**结构体
使用同样的方法得到对应的代码:
复制代码 隐藏代码typedef struct _IMAGE_NT_HEADERS { |
可以看到PE文件头对应的结构体中还包含了其它结构体,这里依旧只介绍大体作用,细节留作之后的笔记
这里的PE文件头相对于先前的DOS部首则是给Windows使用的
块表(节表)
该部分结构对应winnt.h中的**_IMAGE_SECTION_HEADER**结构体
使用同样的方法得到对应的代码:
复制代码 隐藏代码typedef struct _IMAGE_SECTION_HEADER { |
块表主要用来表示当前文件一共分为几个部分,和后面的块相对应
块表决定了后面的块,每一块从哪里开始,里面存储的数据是什么等等
块
块部分是由前面的块表决定的,是具体的存储数据的部分