http://www.cnblogs.com/skymouse/archive/2012/05/10/2493725.html
要分析PE文件我们首先要对PE结构有一个大致的了解,大体上PE结构可以看成是一个平面空间里面包含有如下内容
相应的MSDOS头结构定义如下,Windows加载器在加载的过程中会判断dos头是否合法
typedef
struct
_IMAGE_DOS_HEADER {
// DOS .EXE header
WORD e_magic;
// Magic number
WORD e_cblp;
// Bytes on last page of file
WORD e_cp;
// Pages in file
WORD e_crlc;
// Relocations
WORD e_cparhdr;
// Size of header in paragraphs
WORD e_minalloc;
// Minimum extra paragraphs needed
WORD e_maxalloc;
// Maximum extra paragraphs needed
WORD e_ss;
// Initial (relative) SS value
WORD e_sp;
// Initial SP value
WORD e_csum;
// Checksum
WORD e_ip;
// Initial IP value
WORD e_cs;
// Initial (relative) CS value
WORD e_lfarlc;
// File address of relocation table
WORD e_ovno;
// Overlay number
WORD e_res[4];
// Reserved words
WORD e_oemid;
// OEM identifier (for e_oeminfo)
WORD e_oeminfo;
// OEM information; e_oemid specific
WORD e_res2[10];
// Reserved words
LONG e_lfanew;
// File address of new exe header
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
|
通过以上结构我们可以看到e_lfanew(60=0x3c个字节偏移)字段代表exe头在文件中的位置(00F8)
所以可以断定00F8位置指向的内容为PE头结构定义如下
typedef
struct
_IMAGE_NT_HEADERS {
DWORD Signature;
//PE头签名PE\0\0
IMAGE_FILE_HEADER FileHeader;
//PE文件头
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
//PE扩展头
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
|
0xF9=50 45 00 00=PE\0\0->Signature签字段
|
000000fch=镜像头结构开发位置占20个字节
typedef
struct
_IMAGE_FILE_HEADER {
WORD Machine;
//014C-IMAGE_FILE_MACHINE_I386
WORD NumberOfSections;
//PE节数量-0007个节
DWORD TimeDateStamp;
//时间戳E72B4FA9
DWORD PointerToSymbolTable;
//指向符号表0000
DWORD NumberOfSymbols;
//符号表数量0000
WORD SizeOfOptionalHeader;
//扩展PE头大小00E0
WORD Characteristics;
//文件属性0102-IMAGE_FILE_32BIT_MACHINE|IMAGE_FILE_EXECUTABLE_IMAGE
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
|
00000110h=扩展文件头起始位置占224个字节(E0)
typedef
struct
_IMAGE_OPTIONAL_HEADER {
//
// Standard fields.
//
WORD Magic;
//010B-IMAGE_NT_OPTIONAL_HDR32_MAGIC
BYTE MajorLinkerVersion;
//0A-连接器主版本号
BYTE MinorLinkerVersion;
//00-连接器小版本号
DWORD SizeOfCode;
//0000008A(138)-代码节大小
DWORD SizeOfInitializedData;
//0000004C(76)-已初始化数据大小
DWORD SizeOfUninitializedData;
//00000000(0)-为初始化数据大小
DWORD AddressOfEntryPoint;
//000110AA程序入口地址
DWORD BaseOfCode;
//00001000程序段基地址
DWORD BaseOfData;
//00001000数据段基地址
//
// NT additional fields.
//
DWORD ImageBase;
//镜像加载基地址00400000
DWORD SectionAlignment;
//节对其0001000(4096)
DWORD FileAlignment;
//文件对齐0000200(512)
WORD MajorOperatingSystemVersion;
//操作系统主版本号0005
WORD MinorOperatingSystemVersion;
//操作系统小版本号0001
WORD MajorImageVersion;
//镜像主版本号0000
WORD MinorImageVersion;
//镜像小版本号0000
WORD MajorSubsystemVersion;
//子系统主版本号0005
WORD MinorSubsystemVersion;
//子系统小版本号0001
DWORD Win32VersionValue;
//0
DWORD SizeOfImage;
//镜像大小00022000
DWORD SizeOfHeaders;
//头大小0400
DWORD CheckSum;
//0
WORD Subsystem;
//03-IMAGE_SUBSYSTEM_WINDOWS_CUI
WORD DllCharacteristics;
//8140IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE
DWORD SizeOfStackReserve;
//栈初始化大小010000
DWORD SizeOfStackCommit;
//栈提交大小01000
DWORD SizeOfHeapReserve;
//堆初始化大小010000
DWORD SizeOfHeapCommit;
//堆提交大小01000
DWORD LoaderFlags;
//0
DWORD NumberOfRvaAndSizes;
//10(16)
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
//数据目录表
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
|
到这里我们基本上已经将PE文件头信息给分析完成了.
下一篇我们来了解一下《导入表和函数地址导入表》