1. 程式人生 > >PE文件格式詳解,第一講,DOS頭文件格式

PE文件格式詳解,第一講,DOS頭文件格式

www new 中斷 relative fun 意義 word 作用 nor

           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頭文件格式