码迷,mamicode.com
首页 > 其他好文 > 详细

PE文件格式详解,第一讲,DOS头文件格式

时间:2017-10-10 10:03:09      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:ble   src   base   loader   www.   开始   一段   arch   binary   

 

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

标签:ble   src   base   loader   www.   开始   一段   arch   binary   

原文地址:http://www.cnblogs.com/iBinary/p/7643695.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!