8.1 PE文件格式概述

PE(Portable Executable)文件,意为可移植的、可执行的文件,常见的EXE、DLL、OCX、SYS、COM都是PE文件,PE文件是微软Windows操作系统上的可执行文件的标准格式。它是微软在UNIX平台的COFF(通用对象文件格式)基础上制作而成。最初设计用来提高程序在不同操作系统上的移植性,但实际上这种文件格式仅用在Windows系列操作系统下。

PE文件的格式比较复杂,简化后的结构如图8-2所示,其中比较重要的几个部分为:DOS头、文件头、可选头、数据目录,以及节头和节区。

1.DOS头

DoS头是一个32位的签名以及魔数0x00004550。

图8-2 PE文件格式简图

2.文件头

文件头用来说明该二进制文件将运行在何种机器之上、分几个区段、链接的时间、是可执行文件还是DLL等等。文件头的C语言风格结构定义如下:


typedef struct _IMAGE_NT_HEADERS { 
        DWORD Signature; 
        IMAGE_FILE_HEADER FileHeader; 
        IMAGE_OPTIONAL_HEADER32 OptionalHeader; 
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;  
    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,机器码,每个CPU拥有唯一的Machine码,我们列举常见的几个:


#define IMAGE_FILE_MACHINE_UNKNOWN        0 
#define IMAGE_FILE_MACHINE_I386           0x014c  // Intel 386. 
#define IMAGE_FILE_MACHINE_POWERPC        0x01F0  // IBM PowerPC Little-Endian 
#define IMAGE_FILE_MACHINE_IA64           0x0200  // Intel 64 
#define IMAGE_FILE_MACHINE_MIPS16         0x0266  // MIPS 
#define IMAGE_FILE_MACHINE_ALPHA64        0x0284  // ALPHA64 

·NumberOfSections,指文件中存在的节的数量。

·Characteristics,标识文件的属性,文件是否为可运行的状态,是否为DLL文件等信息,我们列举常见的几个:


// 文件是否可以执行 
#define IMAGE_FILE_EXECUTABLE_IMAGE         0x0002  
// 是否包含调试信息  
#define IMAGE_FILE_DEBUG_STRIPPED           0x0200  
// 是否是系统文件
#define IMAGE_FILE_SYSTEM                   0x1000  
// 是否是DLL文件
 #define IMAGE_FILE_DLL                     0x2000

·TimeDateStamp,PE文件的创建时间。

·PointerToSymbolTable,COFF文件符号表在文件中的偏移。

·NumberOfSymbols,符号表的数量。

·SizeOfOptionalHeader,紧随其后的可选头的大小。

3.可选头

可选头虽然叫作可选,但是却包含了大量PE文件的重要信息。可选头的C语言风格结构定义如下:


typedef struct _IMAGE_OPTIONAL_HEADER { 
        WORD    Magic; 
        BYTE    MajorLinkerVersion; 
        BYTE    MinorLinkerVersion; 
        DWORD   SizeOfCode; 
        DWORD   SizeOfInitializedData; 
        DWORD   SizeOfUninitializedData; 
        DWORD   AddressOfEntryPoint; 
        DWORD   BaseOfCode; 
        DWORD   BaseOfData; 
        DWORD   ImageBase; 
        DWORD   SectionAlignment; 
        DWORD   FileAlignment; 
        WORD    MajorOperatingSystemVersion; 
        WORD    MinorOperatingSystemVersion; 
        WORD    MajorImageVersion; 
        WORD    MinorImageVersion; 
        WORD    MajorSubsystemVersion; 
        WORD    MinorSubsystemVersion; 
        DWORD   Win32VersionValue; 
        DWORD   SizeOfImage; 
        DWORD   SizeOfHeaders; 
        DWORD   CheckSum; 
        WORD    Subsystem; 
        WORD    DllCharacteristics; 
        DWORD   SizeOfStackReserve; 
        DWORD   SizeOfStackCommit; 
        DWORD   SizeOfHeapReserve; 
        DWORD   SizeOfHeapCommit; 
        DWORD   LoaderFlags; 
        DWORD   NumberOfRvaAndSizes; 
        IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; 
    } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

其中,比较重要的几个字段介绍如下 [1]

·Magic,标记32位和64位可选头,为IMAGE_OPTIONAL_HEADER32时,magic码为10B,为IMAGE_OPTIONAL_HEADER64时,magic码为20B。

·MajorLinkerVersion和MinorLinkerVersion,链接器的版本号。

·SizeOfCode,代码段的长度。

·MajorOperatingSystemVersion、MinorOperatingSystemVersion,所需操作系统的版本号。

·MajorImageVersion、MinorImageVersion,映像的版本号。

·MajorSubsystemVersion、MinorSubsystemVersion,所需子系统版本号。

·SizeOfImage,映像的大小。

·SizeOfHeaders,所有文件头的大小。

·Subsystem,运行该PE文件所需的子系统。

4.数据目录

数据目录包含许多指向各节数据的指针。

5.节头和节区

这块是PE文件真正的干货,和病毒检测相关的特征主要集中在这个区域,下节将重点介绍。

[1] http://www.freebuf.com/articles/system/86596.html