PE手动解析
写这个是为了个人动手练习,不当“视频观察师”。
DOS头
16进制编辑器打开,首先两字节是0x5A4D(Ascii的MZ),在0x3C处,是e_lfanew,两个字节,储存着PE头的偏移,此文件中是0x00E0,找过去,发现0x5045(Ascii的PE),是PE头标志Signature,四个字节。

PE头

PE头标志
四字节。高两字节为0x00,低两字节为0x4550。
PE标准头
头标志后面跟着PE标准头,二十字节。
Machine
文件的运行平台,此文件中为0x014C,是Intel 386平台。
NumberOfSections
该PE文件中的节数量,也就是节表中的项数,两个字节。此处是0x0003,一共三个节。
TimeDateStamp
PE文件的创建时间,四字节。此处是0x48022587,十进制为1208100231。

PointerToSymbolTable
COFF在文件中的偏移。四字节,此处是空。
NumberOfSymbols
符号表数量,四字节。此处为空。
SizeOfOptionalHeaders
PE可选头的长度,两个字节。此处是0x00E0。
Characteristics
可执行文件的属性,两个字节,是相关属性对应的16进制按位相或的结果。此处是0x010F,即0x0100(32位)、0x0001、0x0002(可执行)、0x0004、0x0008是这个文件的属性。
1 | Characteristics的可选值 |
PE可选头
上面标准头SizeOfOptionalHeader指明长度是0x00E0,即224字节,这是32位可执行文件,一般是244字节。

Magic
魔术字,表示可选头的类型,两字节。此处是0x010B。
MajorLinkerVersion
链接器版本号,一字节。此处是0x07。
MinorLinkerVersion
链接器版本号,一字节,此处是0x0A。
SizeOfCode
代码段总长度,四字节。此处是0x00007800。
SizeOfInitializedCode
初始化的数据长度,比如全局变量,四字节。此处是0x00008800。
SizeOfUnInitializedCode
未初始化数据的长度,四字节。此处是0.
AddressOfEntryPoint
OEP入口点偏移,四字节。此处是0x0000739D。
BaseOfCode
代码段起始地址偏移,四字节。此处是0x00001000。
BaseOfData
数据段起始地址偏移,四字节。此处是0x00009000。
ImageBase
基址,四字节。此处是0x01000000。
SectionAlignment
节被夹在到内存中按照这个值对齐,四字节。此处是0x00001000.
FileAlignment
节在文件中按此值对齐,四字节。此处是0x00000200
MajorOperatingSystemVersion
操作系统版本号,两字节。此处是0x0005.
MinorOperatingSystemVersion
所需最小操作系统版本号,两字节,此处是0x0001.
MajorImageVersion
映像的版本号,两字节。此处是0x0005.
MinorImageVersion
最小映像的版本号,两字节,此处是0x0001.
MajorSubsystemVersion
所需子系统版本号,两字节。此处是0x0004.
MinorSubsystemVersion
最小所需子系统版本号,两字节。此处是0x0000.
Win32VersionValue
保留,必须为0,四字节。
SizeOfImage
映像的大小,PE加载到内存是连续的,这个值指定占用虚拟空间的大小,四字节。此处是0x00013000.
SizeOfHeaders
所有头加节表的大小,以FileAlignment对齐,四字节。此处是0x00000400.
CheckSum
文件校验和,四字节。此处是0x00018ADA.
Subsystem
运行该PE文件所需的子系统,两字节。此处是0x0002.
DllCharacteristics
DLL的文件属性,只对DLL文件有效,两字节。此处是0x0800.
SizeOfStackReserve
四字节。此处是0x00040000.
SizeOfStackCommit
四字节。此处是0x00011000.
SizeOfHeapReserve
四字节。此处是0x00100000.
SizeOfHeapCommit
四字节。此处是0x00001000.
LoaderFlags
保留,必须为0,四字节。
NumberOfRvaAndSizes
数据目录的项数,即下面这个数组的项数,四字节。此处是0x00000010.
IMAGE_DATA_DIRECTORY
数据目录,这是一个数组,如图都是它的。

节表
在PE可选头中的SizeOfHeaders指明了头加节表的长度,此处是0x400,即1024字节。
而PE标准头的SizeOfOptionalHeaders指明了可选头的长度,此处是0x00E0,即244字节。
PE标准头长度24字节。DOS头长度224字节。
所以节表长度为 1024-244-244-24=552 字节。如图所示都是节表的部分。

Name数组
八个字节,该节的名称。此处为0x00000074 7865742E(.text).
Misc
该节在没有对齐前的真实大小,该值可能不准确,联合体,四个字节。此处为0x00007748.
VirtualAddress
节区在内存中的偏移地址,加上ImageBase才是在内存中的真正地址,四个字节。此处是0x00001000.
SizeOfRawData
节在内存中对齐后的大小,四个字节。此处是0x00007800.
PointerToRawData
节在内存中的偏移,四个字节。此处是0x00000400.
PointerToRelocations
在obj文件中使用,对exe无意义,四个字节。
PointerToLinenumbers
行号表的位置,调试时使用,四个字节。
NumberOfRelocations
在obj文件中使用,对exe无意义,两个字节。
NumberOfLinenumbers
行号表中行号的数量,调试的时候使用,两个字节。
Characteristics
表示该节的属性,四个字节。此处是0x60000020.
后面紧跟着是.data节,就不分析了。