要分析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檔案頭資訊給分析完成了.
下一篇我們來瞭解一下《匯入表和函數地址匯入表》