大体上,PE文件由下面几个部分组成,DOS头,PE头,可选头,节表,以及各节的数据。这些数据结构在文件中的位置如下图所示。
PE文件的第一部分是一个DOS头,一般我们称之为DOS STUB。 这个DOS头实际上就是一个完整的DOS应用程序。这样当你在DOS下试图运行这个程序的时候,DOS将会把它识别成一个DOS可执行程序。一般这个DOS STUB会在屏幕上打印一条信息“该程序需要WINDOWS环境”
在DOS头的第0x3C字节处有一个4字节的指针,指向PE文件的签名。 PE文件的签名长度为4字节,内容为 “PE/0/0”。检查过这个签名后就可以认为这是一个合法的PE文件了。
紧跟着PE签名的是一个PE头结构。这是一个标准COFF头。这个PE头的格式如下图所示:
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;
下面我们来逐个介绍各个字段。
Machine: 该文件运行的平台,具体值如下图
Constant | Value | Description |
IMAGE_FILE_MACHINE_UNKNOWN | 0x0 | 平台未知 |
IMAGE_FILE_MACHINE_AM33 | 0x1d3 | Matsushita AM33 |
IMAGE_FILE_MACHINE_AMD64 | 0x8664 | x64平台 |
IMAGE_FILE_MACHINE_ARM | 0x1c0 | ARM平台 |
IMAGE_FILE_MACHINE_EBC | 0xebc | EF字节码I |
IMAGE_FILE_MACHINE_I386 | 0x14c | x86平台 |
IMAGE_FILE_MACHINE_IA64 | 0x200 | Intel 安腾系列平台 |
IMAGE_FILE_MACHINE_M32R | 0x9041 | Mitsubishi M32R |
IMAGE_FILE_MACHINE_MIPS16 | 0x266 | MIPS16 |
IMAGE_FILE_MACHINE_MIPSFPU | 0x366 | MIPS (带 FPU) |
IMAGE_FILE_MACHINE_MIPSFPU16 | 0x466 | MIPS16 (带 FPU) |
IMAGE_FILE_MACHINE_POWERPC | 0x1f0 | Power PC |
IMAGE_FILE_MACHINE_POWERPCFP | 0x1f1 | Power PC (带 浮点支持) |
IMAGE_FILE_MACHINE_R4000 | 0x166 | MIPS R4000 |
IMAGE_FILE_MACHINE_SH3 | 0x1a2 | Hitachi SH3 |
IMAGE_FILE_MACHINE_SH3DSP | 0x1a3 | Hitachi SH3 DSP |
IMAGE_FILE_MACHINE_SH4 | 0x1a6 | Hitachi SH4 |
IMAGE_FILE_MACHINE_SH5 | 0x1a8 | Hitachi SH5 |
IMAGE_FILE_MACHINE_THUMB | 0x1c2 | Thumb |
IMAGE_FILE_MACHINE_WCEMIPSV2 | 0x169 | MIPS WCE v2 |
NumberOfSections: 节表的大小
TimeDateStamp: 文件创建时间(1970年1月1日开始的秒数)
PointerToSymbolTable: 指向符号表的指针(已经不用)
NumberOfSymbols: 符号表中符号数量(已经不用)
SizeOfOptionalHeader: 可选头大小
Characteristics: 文件属性
Flag | Value | Description |
IMAGE_FILE_RELOCS_STRIPPED | 0x0001 | 文件中没有重定位信息 |
IMAGE_FILE_EXECUTABLE_IMAGE | 0x0002 | 文件是可执行文件 |
IMAGE_FILE_LINE_NUMS_STRIPPED | 0x0004 | 已不用 |
IMAGE_FILE_LOCAL_SYMS_STRIPPED | 0x0008 | 已不用 |
IMAGE_FILE_AGGRESSIVE_WS_TRIM | 0x0010 | 已不用 |
IMAGE_FILE_LARGE_ADDRESS_ AWARE | 0x0020 | 该程序可以处理大于2G的空间 |
| 0x0040 | 保留 |
IMAGE_FILE_BYTES_REVERSED_LO | 0x0080 | 小端机 |
IMAGE_FILE_32BIT_MACHINE | 0x0100 | 32位机器 |
IMAGE_FILE_DEBUG_STRIPPED | 0x0200 | 文件中无调试信息. |
IMAGE_FILE_REMOVABLE_RUN_ FROM_SWAP | 0x0400 | 如果文件在一个可移动存储器上,则将其拷贝到交换文件 |
IMAGE_FILE_NET_RUN_FROM_SWAP | 0x0800 | 如果文件在网络上,则将其拷贝到交换文件上 |
IMAGE_FILE_SYSTEM | 0x1000 | 这是一个系统文件 |
IMAGE_FILE_DLL | 0x2000 | 这是一个动态链接库 |
IMAGE_FILE_UP_SYSTEM_ONLY | 0x4000 | 该程序必须在单处理器环境中运行 |
IMAGE_FILE_BYTES_REVERSED_HI | 0x8000 | 大端 |