PE文件格式詳解,第一講,DOS頭文件格式
今天講解PE文件格式的DOS頭文件格式
首先我們要理解,什么是文件格式,我們常說的EXE可執行程序,就是一個文件格式,那么我們要了解它里面到底存了什么內容
簡短的說明.
我們要知道,PE文件格式,是微軟半公開的,因為微軟並沒有說明這個文件格式.但是微軟有定義的結構體.
文件格式,是記錄文件加載到內存中執行的位置,和偏移
在DOS16位年代下,主要記錄分段等等的信息.
在32位年代下,主要記錄分區位置,代碼位置,各種表等等..
作者:IBinary
出處:http://www.cnblogs.com/iBinary/
版權所有,歡迎保留原文鏈接進行轉載:)
一丶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;
可以看出,這個結構體中已經明確定義了各種DOS(16位年代的)頭了.
我們在32位年代下,主要要知道第一個成員和最后一個成員
第一個成員: 標志MZ,記錄了MZ,占兩個字節,這個是DOS系統作者的名字
最后一個成員: 這個成員主要記錄了新的文件開始執行的地址位置.
因為微軟為了兼容16位程序,所以還保留DOS頭,但是32位程序,是不會執行DOS頭了,重要的就是這兩個成員.
二丶WinHex對比

第一個成員,對應4D 5A兩個字節
最后一個成員,對應 00 00 00 D0 (小尾方式) 最后一個成員是保存了新的文件格式地址.所以我們看到D0的位置,正好是PE
那么我們如果不是在16位程序下使用,那么上面除了最后一個成員,其余的位置都可以隨便改.

正常運行

三丶DOS頭的代碼區
我們上面看到了,DOS頭就一個結構體大小,到了最后一個成員位置,則是這個結構體結束,那么在這個結構體結束的后面,一直到PE的位置的二進制到底是什么?

可以看出,在DOS頭的位置,也就是成員 WORD e_lfarlc; 記錄的是DOS的代碼執行位置,這塊區域屬於DOS的代碼執行區域
主要作用是,在16位系統下,不能運行32位程序,如果運行,則利用中斷,顯示 This is Program cannot be run in Dos Mode (這個程序不能運行在DOS系統)
如果在32位系統下使用,那么這一段是沒有任何作用的.DOS頭只需要知道 第一個成員,和最后一個成員你的指向即可.
如果是16位系統下,那么你這個DOS頭記錄的信息就有用了(保存了頁大小,頁的個數,SS段.IP執行位置,校驗和等等)
四丶NT頭,PE頭,以及可選頭(第一講介紹,不講解具體作用)
到了PE位置,那么我們要了解一下NT頭,PE頭,可選頭的結構到底是什么.新的格式是怎么樣子的.
NT頭:
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
NT頭分為32和64位版本的,這里說下32的,
第一個成員: 4個字節,也就是和4D 5A 一樣,都是固定的標志,而這個標志則是

也就是我們說的PE頭.
下面還有兩個結構體,分別是文件頭,還有可選頭.
文件頭:
typedef struct _IMAGE_FILE_HEADER {
WORD Machine;
WORD NumberOfSections;
DWORD TimeDateStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
可選頭:
可選頭:
typedef struct _IMAGE_OPTIONAL_HEADER {
//
// Standard fields.
//
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
DWORD BaseOfData;
//
// NT additional fields.
//
DWORD ImageBase;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage;
DWORD SizeOfHeaders;
DWORD CheckSum;
WORD Subsystem;
WORD DllCharacteristics;
DWORD SizeOfStackReserve;
DWORD SizeOfStackCommit;
DWORD SizeOfHeapReserve;
DWORD SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
最后一個成員是數據目錄
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
節頭:
typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
union {
DWORD PhysicalAddress;
DWORD VirtualSize;
} Misc;
DWORD VirtualAddress;
DWORD SizeOfRawData;
DWORD PointerToRawData;
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
可以看出,一個PE文件,主要是結構體套結構體,里面的每個成員都代表什么意義,結構體就怎么多.
五丶大體的PE結構分布圖
DOS頭
NT頭
{
文件頭
可選頭
數據目錄
}
節頭
今天主要是要了解PE的DOS頭,以及PE結構的分布圖.具體作用以后慢慢講,主要了解大體框架,隨着框架深入.
如果想一次了解全部PE,請參考網上大神的博客. http://www.cppblog.com/oosky/archive/2016/07/15/15614.html
作者:IBinary
出處:http://www.cnblogs.com/iBinary/
版權所有,歡迎保留原文鏈接進行轉載:)
