PE文件
PE文件是portable File Format(可移植文件)的简写,我们比较熟悉的DLL(动态链接库)和exe(可执行)文件都是PE文件
PE格式概览
图片转自:https://blog.csdn.net/evileagle/article/details/11693499
PE文件格式底层实现代码概览
图片转自:https://blog.csdn.net/freeking101/article/details/102752048?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.edu_weight&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.edu_weight
由于PE文件过于复杂,因此按照每段代码定义进行学习,并记录相关重要知识点
DOS_HEADER::MS-DOS头部
struct _IMAGE_DOS_HEADER
{
0x00 WORD e_magic;
0x02 WORD e_cblp;
0x04 WORD e_cp;
0x06 WORD e_crlc;
0x08 WORD e_cparhdr;
0x0a WORD e_minalloc;
0x0c WORD e_maxalloc;
0x0e WORD e_ss;
0x10 WORD e_sp;
0x12 WORD e_csum;
0x14 WORD e_ip;
0x16 WORD e_cs;
0x18 WORD e_lfarlc;
0x1a WORD e_ovno;
0x1c WORD e_res[4];
0x24 WORD e_oemid;
0x26 WORD e_oeminfo;
0x28 WORD e_res2[10];
0x3c DWORD e_lfanew;
};
显而易见,采用了结构体数据来进行定义实现,主要内容类似于C代码,但是又不像C代码,C语言的主要类型包含short、int、long、char、float、double等;此时使用的WORD:DWORD;BYTE并非C语言的标准类型,定义代码如下
WORD
typedef unsigned short WORD;
DWORD:Double WORD
typedef unsigned int DWORD;
BYTE
typedef unsigned char BYTE;
DOS-Header定义重要关键字段详解(共计64Byte)
字段 | 含义 | 大小 |
---|---|---|
e_magic | 固定头部内容为MZ [4D 5A] | 2Byte |
e_lfanew | 指定PE头位置 | 4Byte |
e-magic:DOS幻数MZ
使用系统关键的Kernel32.dll来进行分析
图中可发现前2Byte的ASCII内容位MZ,其中[4D 5A]为小端存储
e-lfanew:指定PE头位置
仍然使用系统关键的Kernel32.dll来进行分析
图中可发现Offset==0x0000003C位置时,存储的数值位[F0 00 00 00],依旧为小端存储 所以PE文件头的开始位置为0x000000F0,图中0x000000F0位置存储的内容为[50 45 00 00 4C 01 05 00]可以看到ASCII内容以PE开头
DOS-Header相关计算
DOS Header===DOS MZ头大小 + Dos sub(DOS代码块大小)
DOS sub大小 = PE起始位置 - 40Byte
DOS-sub部分如图所示
其中DOS sub为Dos-Header至PE其实部分的数据块,主要功能是为了说明在32位系统之后废弃了,只在16位的DOS环境下才会执行,在16位的DOS环境下,执行一个32位的程序将会出现This Program cannot be run in DOS mod提示。
扩展
- 对Dos-Sub代码区的利用可参考文章 PE修改DOS Sub增加电脑喇叭嘟一声的功能
- 对Dos-Sub代码区修改,添加类似文件水印 PE文件中对DOS存根的一些想法
Tips
MZ头标志和PE头标志记作PE指纹