3、 PE文件结构
MS-DOS头在winnt.h中定义成为IMAGE_DOS_HEADER,这个结构中,最需要关心的是成员e_lfanew,它给出了PE Header在文件中的偏移量。比如,e_lfanew的值是0xE0,则PE Header在文件距离开头0xE0处。
这是一段DOS程序,如果把win32的可执行文件放到dos上执行,这段代码将在屏幕上显示类似于“This program can not run in dos”的信息。
③ Magic Number和PE Header
这才是真正的win32可执行文件的开始。Magic Number是一个DWORD类型的数,值是0x4550,对应的ASCII值就是“PE”。PE Header在winnt.h里被定义成为:
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:声明PE文件是在那种CPU架构下运行,它可以是下表中所列出的值:(通常PE文件运行在x86系列的CPU架构下,这个值就应该是0x14C。)
标志 | 值 | 说明 |
IMAGE_FILE_MACHINE_UNKNOWN | 0x0 | 假定在所有机器上运行 |
IMAGE_FILE_MACHINE_AM33 | 0x1d3 | Matsushita AM33 |
IMAGE_FILE_MACHINE_AMD64 | 0x8664 | x64 |
IMAGE_FILE_MACHINE_ARM | 0x1c0 | ARM little endian |
IMAGE_FILE_MACHINE_EBC | 0xebc | EFI byte code |
IMAGE_FILE_MACHINE_I386 | 0x14c | Intel 386家族及其兼容CPU |
IMAGE_FILE_MACHINE_IA64 | 0x200 | Intel Itanium处理器家族 |
IMAGE_FILE_MACHINE_M32R | 0x9041 | Mitsubishi M32R little endian |
IMAGE_FILE_MACHINE_MIPS16 | 0x266 | MIPS16 |
IMAGE_FILE_MACHINE_MIPSFPU | 0x366 | MIPS with FPU |
IMAGE_FILE_MACHINE_MIPSFPU16 | 0x466 | MIPS16 with FPU |
IMAGE_FILE_MACHINE_POWERPC | 0x1f0 | Power PC little endian |
IMAGE_FILE_MACHINE_POWERPCFP | 0x1f1 | 有浮点支持的Power PC |
IMAGE_FILE_MACHINE_R4000 | 0x166 | MIPS little endian |
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 little-endian WCE v2 |
NumberOfSections:表示PE文件中节的数量。
TimeDateStamp:链接器产生这个文件的时间,是自从1969 年12 月31 日4:00 P.M. 之后的总秒数。
PointerToSymbolTable、NumberOfSymbols:一般只对COFF(Common Object File Format)格式文件有用。
SizeOfOptionalHeader:它是Optional header的大小,也就是sizeof(IMAGE_OPTIONAL_HEADER)(Optional header被定义成为IMAGE_OPTIONAL_HEADER结构)。
Characteristics:声明这个PE文件的性质,它可以是下表列出的值,并且可以按位或:(对于一个DLL文件,这个值应该通常是0x2102;对于一个EXE文件,这个值通常是0x0103)
标志 | 值 | 描述 |
IMAGE_FILE_RELOCS_STRIPPED | 0x0001 | 用于Windows CE,Windows NT以及后续操作系统。声明此PE文件没有基础重定位,并且必须装载到预先定义的基地址。如果基地址不可用,装载器将报错。 |
IMAGE_FILE_EXECUTABLE_IMAGE | 0x0002 | 这是一个可执行文件。 |
IMAGE_FILE_LINE_NUMS_STRIPPED | 0x0004 | 这一位应该置零。 |
IMAGE_FILE_LOCAL_SYMS_STRIPPED | 0x0008 | 这一位应该置零。 |
IMAGE_FILE_AGGRESSIVE_WS_TRIM | 0x0010 | 建议不要再Windows 2000机器后续系统中使用,应该置零。 |
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 | 这一位应该置零。 |