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 |
这一位应该置零。 |