参考:http://blog.csdn.net/huanjieshuijing/article/details/5874365
http://lwglucky.blog.51cto.com/1228348/283812
涉及到的数据结构
我们可以在Winnt.h这个文件中找到关于PE文件头的定义:
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;
//PE文件头标志 :“PE/0/0”。在开始DOS header的偏移3CH处所指向的地址开始(待研究和考证)
IMAGE_FILE_HEADER FileHeader; //PE文件物理分布的信息
IMAGE_OPTIONAL_HEADER32 OptionalHeader;//PE文件逻辑分布的信息
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
typedef struct _IMAGE_FILE_HEADER {
WORD Machine;//该文件运行所需要的CPU,对于Intel平台是14Ch
WORD NumberOfSections;//文件的节数目
DWORD TimeDateStamp;//文件创建日期和时间
DWORD PointerToSymbolTable;//用于调试
DWORD NumberOfSymbols;//符号表中符号个数
WORD SizeOfOptionalHeader;//OptionalHeader 结构大小
WORD Characteristics; //文件信息标记,区分文件是exe还是dll
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
typedef struct _IMAGE_OPTIONAL_HEADER {
//
// Standard fields.
//
WORD Magic;//标志字(总是010bh)
BYTE MajorLinkerVersion;//连接器版本号
BYTE MinorLinkerVersion;
DWORD SizeOfCode;//代码段大小
DWORD SizeOfInitializedData;//已初始化数据块大小
DWORD SizeOfUninitializedData;//未初始化数据块大小
DWORD AddressOfEntryPoint;
PE装载器准备运行的PE文件的第一个指令的RVA,若要改变整个执行的流程,可以将该值指定到新的RVA,这样新RVA处的指令首先被执行(以往许多文章都有介绍RVA,请大家先了解)。
DWORD BaseOfCode;//代码段起始RVA
DWORD BaseOfData;//数据段起始RVA
//
// NT additional fields.
//
DWORD ImageBase;//PE文件的装载地址
DWORD SectionAlignment;//块对齐
DWORD FileAlignment;//文件块对齐
WORD MajorOperatingSystemVersion;//所需操作系统版本号
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;//用户自定义版本号
WORD MinorImageVersion;
WORD MajorSubsystemVersion;//win32子系统版本。若PE文件是专门为Win32设计的
WORD MinorSubsystemVersion;//该子系统版本必定是4.0否则对话框不会有3维立体感
DWORD Win32VersionValue;
DWORD SizeOfImage;//内存中整个PE映像体的尺寸
DWORD SizeOfHeaders;//所有头+节表的大小
DWORD CheckSum;//校验和
WORD Subsystem; //NT用来识别PE文件属于哪个子系统
WORD DllCharacteristics;
DWORD SizeOfStackReserve;
DWORD SizeOfStackCommit;
DWORD SizeOfHeapReserve;
DWORD SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];//IMAGE_DATA_DIRECTORY 结构数组。每个结构给出一个重要数据结构的RVA,比如引入地址表等 IMAGE_NUMBEROF_DIRECTORY_ENTRIES=16
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;//表的RVA地址
DWORD Size;//大小
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
PE文件头后是节表,在winnt.h下如下定义
typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];//节表名称,如“.text” IMAGE_SIZEOF_SHORT_NAME = 8
union {
DWORD PhysicalAddress;//物理地址
DWORD VirtualSize;//真实长度
} Misc;
DWORD VirtualAddress;//RVA
DWORD SizeOfRawData;//物理长度
DWORD PointerToRawData;//节基于文件的偏移量
DWORD PointerToRelocations;//重定位的偏移
DWORD PointerToLinenumbers;//行号表的偏移
WORD NumberOfRelocations;//重定位项数目
WORD NumberOfLinenumbers;//行号表的数目
DWORD Characteristics;//节属性
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;