什么是PE文件?
PE文件的全称是Portable Executable,意为可移植的可执行的文件
PE文件是指32位可执行文件,也称为PE32。64位的可执行文件称为PE+或PE32+,是PE(PE32)的一种扩展形式(请注意不是PE64)。
常见种类
种 类 | 主扩展名 | 种 类 | 主扩展名 |
可执行系列 | EXE、SCR | 驱动程序系列 | SYS、VXD |
库系列 | DLL、OCX、CPL、DRV | 对象文件系列 | OBJ |
展示使用软件
PEview.exe工具是一款可以进行PE文件解析的强大PE文件解析工具。通过PEview软件,我们一起来分析PE文件的详细格式。
通过PEview查看PE文件格式
1.DOS头
PE文件头部中的DOS头分为MZ文件头和DOS块
分别对应的是IMAGE_DOS_HEADER和MS-DOS Stub Program
IMAGE_DOS_HEADER头的大小是64个字节
从4D 5A开头 一直到F0 00 00 00
前两个字节0x4D和0x5A,是字母“M”和“Z”的ASCII码,是MS-DOS设计者Mark Zbikowski的姓名缩写。
最后四个字节,表示下一个头部,即NT头的偏移地址,可以看到,该值是0x000000F0,即NT头的起始地址是0x000000F0
DOS块
DOS块跟在IMAGE_DOS_HEADER后面,其中,“MS-DOS stub Program”即为DOS块。从字面上理解,DOS块是一个在DOS环境下可以运行的程序,在图3所示的界面中点击左侧的“MS-DOS stub Program”,则会在右侧显示该程序的数据.
“This program cannot be run in DOS mode”,来提示用户PE程序必须在Windows下才能运行
IMAGE_DOS_HEADER STRUCT
{
+0h WORD e_magic // Magic DOS signature MZ(4Dh 5Ah) DOS可执行文件标记
+2h WORD e_cblp // Bytes on last page of file
+4h WORD e_cp // Pages in file
+6h WORD e_crlc // Relocations
+8h WORD e_cparhdr // Size of header in paragraphs
+0ah WORD e_minalloc // Minimun extra paragraphs needs
+0ch WORD e_maxalloc // Maximun extra paragraphs needs
+0eh WORD e_ss // intial(relative)SS value DOS代码的初始化堆栈SS
+10h WORD e_sp // intial SP value DOS代码的初始化堆栈指针SP
+12h WORD e_csum // Checksum
+14h WORD e_ip // intial IP value DOS代码的初始化指令入口[指针IP]
+16h WORD e_cs // intial(relative)CS value DOS代码的初始堆栈入口
+18h WORD e_lfarlc // File Address of relocation table
+1ah WORD e_ovno // Overlay number
+1ch WORD e_res[4] // Reserved words
+24h WORD e_oemid // OEM identifier(for e_oeminfo)
+26h WORD e_oeminfo // OEM information;e_oemid specific
+29h WORD e_res2[10] // Reserved words
+3ch DWORD e_lfanew // Offset to start of PE header 指向PE文件头
} IMAGE_DOS_HEADER ENDS
e_magic:一个WORD类型,值是一个常数0x4D5A,用文本编辑器查看该值位‘MZ’,可执行文件必须都是'MZ'开头。
e_lfanew:为32位可执行文件扩展的域,用来表示DOS头之后的NT头相对文件起始地址的偏移。
有用的只有两个数据,一个是 e_magic 固定为 “MZ”,另外一个是最后的 e_lfanew ,指向pe头
2.NT头
NT头包括Signatrue、IMAGE_FILE_HEADER和IMAGE_OPTIONAL_HEADER三部分。
Signatrue
- Signatrue也叫做PE文件的文件签名,标志该文件的类型为PE。
- Signatrue共4个字节,其值为0x00004550,即为字符串“PE”。
- 这个值也是不会变化的。
IMAGE_FILE_HEADER
IMAGE_FILE_HEADER部分共20字节。
从上往下看,
①头两个字节表示机器类型,用于标识CPU的类型,后两个字节表示CPU为Intel 386或后继处理器及其兼容处理器;
②接下来的Number of Section表示节的数目,0x0010表示本应用程序有16个节(section)
③第三个Time date stamp表示时间,这里没有值,如果有值可以换算成十进制秒然后再换算成年月日之类的
④Size of optional header这两个字节是IMAGE_OPTIONAL_HEADER,即NT头的第三部分的大小,其值为0x00E0;
0x00E0就是十进制的224,也就是说OptionalHeader的大小是224字节。
⑤Characteristics这两个字节指定了文件特征值,其值为0x0106
IMAGE_OPTIONAL_HEADER
IMAGE_OPTIONAL_HEADER头由两部分组成:参数部分和数据目录部分;OptionalHeader,占224个字节
3.section头
- PE文件的NT头之后就是节(section)头,
- 每个节头的大小是40字节。
- PE文件包含的节,可以从图中找到这些节对应的节头
- 后缀的意义
- .bss 未初始化的数据
.data 代码节
.edata 导出表
.idata 导入表
.pdata 异常信息
.rdata 只读的已初始化数据(常量)
.reloc 重定位信息
.rsrc 资源目录
.sbss 与GP相关的未初始化数据
.sdata 与GP相关的已初始化数据
.text 默认代码节
.idlsym 包含已注册的SEH,以支持IDL
• Name表示节头的名称,其大小为8个字节;
Virtual Size表示节头对应的节的大小,其大小为4个字节;
RVA是Relative Virtual Address的简称,即相对虚拟地址,指定了节头对应节的RVA,其大小为4个字节;
Size of Raw Data指的是磁盘文件中已经初始化数据的大小,其大小为4个字节;
Pointer to Raw Data、Pointer to Relocations和Pointer to Line Numbers分别保存了节中数据起始地址、重定位项起始地址和行号信息数量的地址,大小均为4个字节;
Number of Relocations和Number of Line Numbers分别表示节中重定位项的数量和行号信息的数量,大小均为2个字节,
Characteristics是描述节特征的标志,大小为4个字节。
Characteristics是描述节特征的标志,其大小为4个字节,共32位,
Characteristics各位含义
1-5 未使用 6 此节包含可执行代码
7 此节包含已初始化的数据 8 此节包含未初始化的数据
9-15 未使用 16 此节包含通过全局指针来引用的数据
17-24 未使用 25 此节包含扩展的重定位信息
26 此节可以在需要时被丢弃 27 此节不能被缓存
28 此节不能被交换到页面文件中 29 此节可以在内存中共享
30 此节可以作为代码执行 31 此节可读
32 此节可写
地址位置