文章中的图片大部分为自己做截屏,少量摘自网络,若有侵权请及时告知,我会尽快删除。转载请注明出处。
1.MS-DOS头
DOS头主要就是为了兼容之前的DOS操作系统,DOS头后面便是DOS Stub,这两部分构成了MS-DOS可执行文件的基本要素,如果PE文件运行在DOS系统中便会执行Stub中的代码,一般上都是“Thisprogram cannot run in DOS mode ”。所以DOS没有什么可以讲的,主要就是开头两个字节MZ表明他是一个PE文件的DOS头开始。还有就是距离MZ偏移量为0x3C的内容便是PE头的位置。
2.PE文件头
下面便是PE文件头的数据结构(来自WinNT.h头文件)
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature; //PE标识
IMAGE_FILE_HEADER FileHeader; //文件头
IMAGE_OPTIONAL_HEADER32 OptionalHeader; //可选头(扩展头)
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
2.1 Signature字段
可以看到Signature字段是固定的0x50450000用来标识从这里开始便是PE头。
#define IMAGE_NT_SIGNATURE 0x50450000 // PE00
2.2 IMAGE_FILE_HEADER结构
下面可以针对这个结构结合实际的十六进制数据来熟悉:
typedef struct _IMAGE_FILE_HEADER {
WORD Machine; //运行平台0x14C表示Intel 386,64位则是0x200
WORD NumberOfSections; //区段的数量0x0002,表示这个文件有2个段
DWORD TimeDateStamp; //文件创建时间,3D91AA47是从GMT的1970.1.1以来秒数
DWORD PointerToSymbolTable;//指向COOF符号表偏移,为0则不存在该符号表
DWORD NumberOfSymbols;//符号数,如果前一个为0这个也为0
WORD SizeOfOptionalHeader;//这个结构的下一个结构即可选头的大小0xE0
WORD Characteristics; //表示PE文件的属性,普通文件0x10F,dll文件为0x210
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;