PE文件格式詳解,第一講,DOS頭文件格式
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;
可選頭:
PE文件格式詳解,第一講,DOS頭文件格式 今天講解PE文件格式的DOS頭文件格式 首先我們要理解,什麽是文件格式,我們常說的EXE可執行程序,就是一個文件格式,那麽我們要了解它裏面到底存了什麽內容 簡短的說明. 我們要知道,PE文件格式,是微軟半公開的,因為微軟並沒有說明這個文件格式.但是微軟有定義的結構體. 文件格式,是記錄文件加載到內存中執行的位置,和偏移 在DOS16位年代下,主要記錄分段等等的信息. 在32位年代下,主要記錄分區位置,代碼位置,各種表等等.. 一丶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/
版權所有,歡迎保留原文鏈接進行轉載:)
PE文件格式詳解,第一講,DOS頭文件格式