PE檔案簡介(一)-資料結構
PE檔案主要涉及的資料結構:
MS-DOS頭佔據PE檔案的頭64(0x40)個位元組。反映它的內容的一個結構如下所述:
WINNT.H
typedef struct _IMAGE_DOS_HEADER { // DOS下的.EXE檔案頭
USHORT e_magic; // 魔數
USHORT e_cblp; // 檔案最後一頁的位元組數
USHORT e_cp; // 檔案的頁數
USHORT e_crlc; // 重定位
USHORT e_cparhdr; // 段中頭的大小
USHORT e_minalloc; // 需要的最少額外段
USHORT e_maxalloc; // 需要的最多額外段
USHORT e_ss; // 初始的(相對的)SS暫存器值
USHORT e_sp; // 初始的SP暫存器值
USHORT e_csum; // 校驗和
USHORT e_ip; // 初始的IP暫存器值
USHORT e_cs; // 初始的(相對的)CS暫存器值
USHORT e_lfarlc; // 重定位表在檔案中的地址
USHORT e_ovno; // 交疊數
USHORT e_res[4]; // 保留字
USHORT e_oemid; // OEM識別符(用於e_oeminfo成員)
USHORT e_oeminfo; // OEM資訊; e_oemid中指定的
USHORT e_res2[10]; // 保留字
LONG e_lfanew; // 新exe頭在檔案中的地址
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
其中最後一個e_lfanew最為重要,它指出了IMAGE_NT_HEADER的檔案內偏移,幫助我們讀取IMAGE_NT_HEADER.
下來就是PE頭了:
PE header 實際就是一個 IMAGE_NT_HEADERS 結構。定義如下:
IMAGE_NT_HEADERS STRUCT
Signature dd ?
FileHeader IMAGE_FILE_HEADER <>
OptionalHeader IMAGE_OPTIONAL_HEADER32 <>
IMAGE_NT_HEADERS ENDS
typedef struct _IMAGE_FILE_HEADER {
USHORT Machine; //機器
USHORT NumberOfSections; //節數
ULONG TimeDateStamp; //時間日期戳
ULONG PointerToSymbolTable; //符號表指標
ULONG NumberOfSymbols; //符號數
USHORT SizeOfOptionalHeader; //可選頭的大小
USHORT Characteristics; //特性
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
typedef struct _IMAGE_OPTIONAL_HEADER {
//
//標準域
//
USHORT Magic; //魔數
UCHAR MajorLinkerVersion; //連結器主版本號
UCHAR MinorLinkerVersion; //連結器小版本號
ULONG SizeOfCode; //程式碼大小
ULONG SizeOfInitializedData; //已初始化資料大小
ULONG SizeOfUninitializedData; //未初始化資料大小
ULONG AddressOfEntryPoint; //入口點地址
ULONG BaseOfCode; //程式碼基址
ULONG BaseOfData; //資料基址
//
//NT增加的域
//
ULONG ImageBase; //映像檔案基址
ULONG SectionAlignment; //節對齊
ULONG FileAlignment; //檔案對齊
USHORT MajorOperatingSystemVersion;//作業系統主版本號
USHORT MinorOperatingSystemVersion;//作業系統小版本號
USHORT MajorImageVersion; //映像檔案主版本號
USHORT MinorImageVersion; //映像檔案小版本號
USHORT MajorSubsystemVersion; //子系統主版本號
USHORT MinorSubsystemVersion; //子系統小版本號
ULONG Reserved1; //保留項1
ULONG SizeOfImage; //映像檔案大小
ULONG SizeOfHeaders; //所有頭的大小
ULONG CheckSum; //校驗和
USHORT Subsystem; //子系統
USHORT DllCharacteristics; //DLL特性
ULONG SizeOfStackReserve; //保留棧的大小
ULONG SizeOfStackCommit; //指定棧的大小
ULONG SizeOfHeapReserve; //保留堆的大小
ULONG SizeOfHeapCommit; //指定堆的大小
ULONG LoaderFlags; //載入器標誌
ULONG NumberOfRvaAndSizes; //RVA的數量和大小
IMAGE_DATA_DIRECTORY DataDirectory [IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; //資料目錄陣列
} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
每個節的資料結構:
typedef struct _IMAGE_SECTION_HEADER {
UCHAR Name[IMAGE_SIZEOF_SHORT_NAME]; //名字陣列
union { //共用體標誌
ULONG PhysicalAddress; //實體地址
ULONG VirtualSize; //虛擬大小
} Misc;
ULONG VirtualAddress; //虛擬地址
ULONG SizeOfRawData; //原始資料的大小
ULONG PointerToRawData; //原始資料指標
ULONG PointerToRelocations; //重定位指標
ULONG PointerToLinenumbers; //行數指標
USHORT NumberOfRelocations; //重定位數目
USHORT NumberOfLinenumbers; //行數數目
ULONG Characteristics; //特徵
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
這樣就可以讀取PE檔案的重要資訊。為以後的操作奠定基礎。