PE文件解析 基础篇
来源 https://bbs.pediy.com/thread-247114.htm
前言
- 之前学习了PE格式,为了更好的理解,决定写一个类似LoadPE的小工具。
- 编译器是VS2015,采用MFC框架。
- 此系列文章采用边介绍知识点,边写代码的形式,以免变的无聊丧失兴趣。
- PE知识请参照《加密与解密》第10章
文章有错误或则不清楚的地方还请您指出。
PE文件格式
1.PE文件基本概念
- PE文件是windows系统中遵循PE结构的文件,比如以.exe .dll为后缀名的文件 以及系统驱动文件。(PE结构框架看下图)
PE文件大体分为两部分,头(包括下图中的DOS头,PE文件头,块表)与主体(块),
- PE文件从磁盘当中像内存中的映射,不是简单的“1对1”的关系,而是“拉长”了。具体的位置表现在块。 但是磁盘上的数据结构与在内存中的结构是一致的。
- 无论PE文件在磁盘中还是在内存中,都少不了地址的概念,理解一下几个概念至关重要。
虚拟地址(VA): 在一个程序运行起来的时候,会被加载到内存中,并且每个进程都有自己的4GB,这个4GB当中的某个位置叫做**虚拟地址**,由物理地址映射过来的,4GB的空间,并没有全部被用到。
基地址( Imagebase ): 磁盘中的文件加载到内存当中的时候可以加载到任意位置,而这个位置就是程序的基址。EXE默认的加载基址是400000h,DLL文件默认基址是10000000h。需要注意的是基地址不是程序的入口点。
相对虚拟地址(RVA):为了避免PE文件中有确定的内存地址,引入了相对虚拟地址的概念。RVA是在内存中相对与载入地址(基地址)
的偏移量,所以你可以发现前三个概念的关系 : 虚拟地址(VA)= 基地址+ 相对虚拟地址(RVA)
文件偏移地址(FOA):当PE文件储存在某个磁盘当中的时候,某个数据的位置相对于文件头的偏移量。
入口点(OEP):首先明确一个概念就是OEP是一个RVA,,然后使用 OEP + Imagebase == 入口点的VA,通常情况下,OEP指向的不是main函数。
- 存了张图 比较好的解释了各部分的关系
接下来依次介绍PE结构框图的每个部分
2.DOS头部
每个PE文件都是以DOS头开始的,IMAGE_DOS_HEADER 结构如下所示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
需要关注的点是结构体的第一个和第二个元素。
e_magic:DOS头的标记位,值为4D5Ah。ASCII为”MZ“,判断一个文件是否为PE文件是会用
e_lfanew:这是一个RVA,代表了PE文件头到基址的偏移量,我们可以用它来找到PE文件头的位置。
我们用010editor打开一个exe文件
3.PE文件头
IMAGE_NT_HEADERS STRUCT 结构体
1 2 3 4 5 6 |
|
- Signature 字段
在一个PE文件中Signature字段被设置为4550h,ASCII码为”PE00“。如上图所示。
- IMAGE_FILE_HEADER 结构体
1 2 3 4 5 6 7 8 9 10 |
|
在010 Editor上查看一下
- IMAGE_OPTIONAL_HEADER 结构体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
|
重要的有
AddressOfEntryPoint: 也就是上文提到的OEP,程序源入口点。
ImageBase: 默认加载基址,
SectionAlignment: 内存当中的块对齐数,一般为0x1000
FileAlignment:磁盘当中块对齐数,一般为0x200
SizeOfHeaders:所有头部大小 也就是DOS头 文件头 以及区块头的总大小 ,文件主体相对文件其实的偏移。
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]:数据目录表,保存了各种表的RVA及大小。
来看一下数据目录的定义
1 2 3 4 |
|
在010 Editor上查看一下
4.写代码操作一下
主要解析了DOS头与PE文件头比较重要的字段,直接放代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
|
实现的效果如下:
第一部分比较简单,完整代码放到附件。
============== End
原文地址:https://www.cnblogs.com/lsgxeva/p/9822289.html