下表列出了PE的总体结构:
DOS MZ header
DOS stub
PE header
Section table
Section 1
Section 2
…
Section n
PE文件的结构
(1)开头是IMAGE_DOS_HEADER结构的数据,有64个字节(4X16),其中最主要的是e_lfanew字段,
它指向PE Header 在磁盘文件中相对于文件开始的偏移地址;
typedef struct _IMAGE_DOS_HEADER
{
WORD e_magic;//魔术数字,0x5A4D->‘MZ’
WORD e_cblp; //文件{zh1}页的字节数
WORD e_cp; //文件页数
WORD e_crlc; //重定义元素个数
WORD e_cparhdr; //头部尺寸,以段落为单位
WORD e_minalloc; //所需的最小附加段
WORD e_maxalloc; //所需的{zd0}附加段
WORD e_ss; //初始的SS值(相对偏移量)
WORD e_sp; //初始的SP值
WORD e_csum; //效验和
WORD e_ip;//初始的IP值
WORD e_cs; //初始的CS值(相对偏移量)
WORD e_lfarlc;//重分配表文件地址
WORD e_ovno;//覆盖号
WORD e_res[4]; //保留字
WORD e_oemid;//OEM标识符
WORD e_oeminfo;//OEM信息
WORD e_res2[10];//保留字
LONG e_lfanew; //指向了PE Header 在磁盘文件中相对于文件开始的偏移地址,新的exe头部的文件地址
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
(2)DOS Stub
(3)第三部分是PE Header部分,结构是IMAGE_NT_HEADERS,有248(15.5X16)个字节,
其中重要的有AddressOfEntryPoint(PE装载器准备运行的PE文件的{dy}个指令的RVA),
NumberOfSections(文件的节数目),
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature; //PE文件头标志:PE\0\0。在开始DOS header的偏移3CH(e_lfanew)处所指向的地址开始
IMAGE_FILE_HEADER FileHeader; //PE文件物理分布的信息
IMAGE_OPTIONAL_HEADER OptionalHeader;//PE文件逻辑分布的信息
}IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
其中:
typedef struct _IMAGE_FILE_HEADER {
WORD Machine;//该文件运行所需要的CPU,对于Intel平台是14Ch
WORD NumberOfSections;//文件的节数目
DWORD TimeDateStamp;//文件创建日期和时间
DWORD PointerToSymbolTable;//用于调试,都为0
DWORD NumberOfSymbols;//符号表中符号个数,都为0
WORD SizeOfOptionalHeader;//OptionalHeader 结构大小,E0即224
WORD Characteristics;//一个标志的集合。其大部分位用于OBJ或LIB文件中
}IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
为20个字节;
重要的 Characteristics值
#define IMAGE_FILE_RELOCS_STRIPPED 0001h // 文件中是否存在重定位信息
#define IMAGE_FILE_EXECUTABLE_IMAGE 0002h // 文件是可执行的
#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0020h // 程序可以触及大于2G的地址
#define IMAGE_FILE_BYTES_REVERSED_LO 0080h // 保留的机器类型低位
#define IMAGE_FILE_32BIT_MACHINE 0100h // 32位机器
#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0400h // 不可在可移动介质上运行
#define IMAGE_FILE_NET_RUN_FROM_SWAP 0800h // 不可在网络上运行
#define IMAGE_FILE_SYSTEM 1000h // 系统文件
#define IMAGE_FILE_DLL 2000h // 文件是一个DLL
#define IMAGE_FILE_UP_SYSTEM_ONLY 4000h // 只能在单处理器计算机上运行
#define IMAGE_FILE_BYTES_REVERSED_HI 8000h //保留的机器类型高位
typedef struct _IMAGE_OPTIONAL_HEADER {
WORD Magic;//标志字(总是010bh)
BYTE MajorLinkerVersion;//连接器高版本号
BYTE MinorLinkerVersion;//连接器低版本号
DWORD SizeOfCode;//代码段大小,不是真实的代码段的大小
DWORD SizeOfInitializedData;//已初始化数据块大小
DWORD SizeOfUninitializedData;//未初始化数据块大小
DWORD AddressOfEntryPoint;//PE装载器准备运行的PE文件的{dy}个指令的RVA,若要改变整个执行的流程,可以将该
值指定到新的RVA,这样新RVA处的指令首先被执行。
DWORD BaseOfCode;//代码段起始RVA
DWORD BaseOfData;//数据段起始RVA
DWORD ImageBase;//PE文件的装载地址
DWORD SectionAlignment;//段加载后内存中的对齐方式
DWORD FileAlignment;//段在文件中的对齐方式
WORD MajorOperatingSystemVersion;//所需操作系统高位版本号
WORD MinorOperatingSystemVersion;// 所需操作系统低位版本号
WORD MajorImageVersion;//用户自定义高位版本号
WORD MinorImageVersion;//用户自定义低位版本号
WORD MajorSubsystemVersion;//win32子系统版本。若PE文件是专门为Win32设计的
WORD MinorSubsystemVersion;//该子系统版本必定是4.0否则对话框不会有3维立体感
DWORD Win32VersionValue;//保留值,系统没用到的,一般被作为是否感染的标志
DWORD SizeOfImage;//内存中整个PE映像体的尺寸
DWORD SizeOfHeaders;//所有头+节表的大小
DWORD