今天讲解PE文件格式的DOS头文件格式

  首先我们要理解,什么是文件格式,我们常说的EXE可执行程序,就是一个文件格式,那么我们要了解它里面到底存了什么内容

简短的说明.

我们要知道,PE文件格式,是微软半公开的,因为微软并没有说明这个文件格式.但是微软有定义的结构体.

文件格式,是记录文件加载到内存中执行的位置,和偏移

在DOS16位年代下,主要记录分段等等的信息.

在32位年代下,主要记录分区位置,代码位置,各种表等等..

PE总体格式:

+-------------------+
    | DOS-stub          |    --DOS-头
    +-------------------+
    | file-header       |    --文件头
    +-------------------+
    | optional header   |    --可选头
    |- - - - - - - - - -|
    |                   |
    | data directories  |    --数据目录
    |                   |
    +-------------------+
    |                   |
    | section headers   |     --节头
    |                   |
    +-------------------+
    |                   |
    | section 1         |     --节1
    |                   |
    +-------------------+
    |                   |
    | section 2         |     --节2
    |                   |
    +-------------------+
    |                   |
    | ...               |
    |                   |
    +-------------------+
    |                   |
    | section n         |     --节n
    |                   |
    +-------------------+

一丶DOS头文件格式

我们看下结构体.

  1.  
  2. typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
  3.  
  4. WORD e_magic; // Magic number (标志,不会变的标志)
  5.  
  6. WORD e_cblp; // Bytes on last page of file
  7.  
  8. WORD e_cp; // Pages in file
  9.  
  10. WORD e_crlc; // Relocations
  11.  
  12. WORD e_cparhdr; // Size of header in paragraphs
  13.  
  14. WORD e_minalloc; // Minimum extra paragraphs needed
  15.  
  16. WORD e_maxalloc; // Maximum extra paragraphs needed
  17.  
  18. WORD e_ss; // Initial (relative) SS value
  19.  
  20. WORD e_sp; // Initial SP value
  21.  
  22. WORD e_csum; // Checksum
  23.  
  24. WORD e_ip; // Initial IP value
  25.  
  26. WORD e_cs; // Initial (relative) CS value
  27.  
  28. WORD e_lfarlc; // File address of relocation table
  29.  
  30. WORD e_ovno; // Overlay number
  31.  
  32. WORD e_res[]; // Reserved words
  33.  
  34. WORD e_oemid; // OEM identifier (for e_oeminfo)
  35.  
  36. WORD e_oeminfo; // OEM information; e_oemid specific
  37.  
  38. WORD e_res2[]; // Reserved words
  39.  
  40. LONG e_lfanew; // File address of new exe header
  41.  
  42. } 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:

  1. typedef struct _IMAGE_NT_HEADERS {
  2.  
  3. DWORD Signature;
  4.  
  5. IMAGE_FILE_HEADER FileHeader;
  6.  
  7. IMAGE_OPTIONAL_HEADER32 OptionalHeader;
  8.  
  9. } IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32; 

NT头分为32和64位版本的,这里说下32的,

第一个成员: 4个字节,也就是和4D 5A 一样,都是固定的标志,而这个标志则是

也就是我们说的PE头.

下面还有两个结构体,分别是文件头,还有可选头.

文件头:

  1. typedef struct _IMAGE_FILE_HEADER {
  2.  
  3. WORD Machine;
  4.  
  5. WORD NumberOfSections;
  6.  
  7. DWORD TimeDateStamp;
  8.  
  9. DWORD PointerToSymbolTable;
  10.  
  11. DWORD NumberOfSymbols;
  12.  
  13. WORD SizeOfOptionalHeader;
  14.  
  15. WORD Characteristics;
  16.  
  17. } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

 可选头:  

  1. <em id="__mceDel"> 可选头:
  2.  
  3. typedef struct _IMAGE_OPTIONAL_HEADER {
  4.  
  5. //
  6.  
  7. // Standard fields.
  8.  
  9. //
  10.  
  11. WORD Magic;
  12.  
  13. BYTE MajorLinkerVersion;
  14.  
  15. BYTE MinorLinkerVersion;
  16.  
  17. DWORD SizeOfCode;
  18.  
  19. DWORD SizeOfInitializedData;
  20.  
  21. DWORD SizeOfUninitializedData;
  22.  
  23. DWORD AddressOfEntryPoint;
  24.  
  25. DWORD BaseOfCode;
  26.  
  27. DWORD BaseOfData;
  28.  
  29. //
  30.  
  31. // NT additional fields.
  32.  
  33. //
  34.  
  35. DWORD ImageBase;
  36.  
  37. DWORD SectionAlignment;
  38.  
  39. DWORD FileAlignment;
  40.  
  41. WORD MajorOperatingSystemVersion;
  42.  
  43. WORD MinorOperatingSystemVersion;
  44.  
  45. WORD MajorImageVersion;
  46.  
  47. WORD MinorImageVersion;
  48.  
  49. WORD MajorSubsystemVersion;
  50.  
  51. WORD MinorSubsystemVersion;
  52.  
  53. DWORD Win32VersionValue;
  54.  
  55. DWORD SizeOfImage;
  56.  
  57. DWORD SizeOfHeaders;
  58.  
  59. DWORD CheckSum;
  60.  
  61. WORD Subsystem;
  62.  
  63. WORD DllCharacteristics;
  64.  
  65. DWORD SizeOfStackReserve;
  66.  
  67. DWORD SizeOfStackCommit;
  68.  
  69. DWORD SizeOfHeapReserve;
  70.  
  71. DWORD SizeOfHeapCommit;
  72.  
  73. DWORD LoaderFlags;
  74.  
  75. DWORD NumberOfRvaAndSizes;
  76.  
  77. IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
  78.  
  79. } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
  80.  
  81.     </em>

最后一个成员是数据目录

  1. typedef struct _IMAGE_DATA_DIRECTORY {
  2.  
  3. DWORD VirtualAddress;
  4.  
  5. DWORD Size;
  6.  
  7. } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

节头:

  1. typedef struct _IMAGE_SECTION_HEADER {
  2.  
  3. BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
  4.  
  5. union {
  6.  
  7. DWORD PhysicalAddress;
  8.  
  9. DWORD VirtualSize;
  10.  
  11. } Misc;
  12.  
  13. DWORD VirtualAddress;
  14.  
  15. DWORD SizeOfRawData;
  16.  
  17. DWORD PointerToRawData;
  18.  
  19. DWORD PointerToRelocations;
  20.  
  21. DWORD PointerToLinenumbers;
  22.  
  23. WORD NumberOfRelocations;
  24.  
  25. WORD NumberOfLinenumbers;
  26.  
  27. DWORD Characteristics;
  28.  
  29. } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

可以看出,一个PE文件,主要是结构体套结构体,里面的每个成员都代表什么意义,结构体就怎么多.

五丶大体的PE结构分布图

DOS头

NT头

{  

 文件头

 可选头

  数据目录 

}

节头

今天主要是要了解PE的DOS头,以及PE结构的分布图.具体作用以后慢慢讲,主要了解大体框架,随着框架深入.

参考于:

http://www.cppblog.com/oosky/archive/2016/07/15/15614.html

http://www.cnblogs.com/iBinary/

第一讲,DOS头文件格式的更多相关文章

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

    PE文件格式详解,第一讲,DOS头文件格式 今天讲解PE文件格式的DOS头文件格式 首先我们要理解,什么是文件格式,我们常说的EXE可执行程序,就是一个文件格式,那么我们要了解它里面到底存了什么内容 ...

  2. PE文件格式详解,第二讲,NT头文件格式,以及文件头格式

    PE文件格式详解,第二讲,NT头文件格式,以及文件头格式 作者:IBinary出处:http://www.cnblogs.com/iBinary/版权所有,欢迎保留原文链接进行转载:) PS:本篇博客 ...

  3. 第二讲,NT头文件格式,以及文件头格式

    今天详解NT 头格式,以及文件头格式,以及作用, 关于DOS头文件格式,以及DOSStub昨天的博客已经写过了.主要是分散讲解.便于理解. 一丶最小PE的生成,以及标准PE的生成 ps: (如果直接学 ...

  4. PE文件格式详解,第三讲,可选头文件格式,以及节表

    PE文件格式详解,第三讲,可选头文件格式,以及节表 作者:IBinary出处:http://www.cnblogs.com/iBinary/版权所有,欢迎保留原文链接进行转载:) 一丶可选头结构以及作 ...

  5. PE 学习之路 —— DOS 头、NT 头

    1. 前述 可执行文件的格式是操作系统本身执行机制的反映,理解它有助于对操作系统的深刻理解,掌握可执行文件的数据结构及其一些机理,是研究软件安全的必修课.`PE(Portable Executable ...

  6. PE文件介绍 (2)-DOS头,DOS存根,NT头

    PE头 PE头由许多结构体组成,现在开始逐一学习各结构体 0X00 DOS头 微软创建PE文件格式时,人们正广泛使用DOS文件,所以微软充分考虑了PE文件对DOS文件的兼容性.其结果是在PE头的最前面 ...

  7. PE文件学习系列二 DOS头分析

    合肥程序员群:49313181.    合肥实名程序员群 :128131462 (不愿透露姓名和信息者勿加入)Q  Q:408365330     E-Mail:egojit@qq.com PE文件结 ...

  8. DOS头分析

    DOS头分析 PE文件结构综览: 首先上图片: 看到上面的图片可以清晰的看到PE结构复杂结构式什么样子的.有DOS首部,PE头部,PE节表,很多的表块,最后就是一些调试信息. DOS头由DOS 'MZ ...

  9. 32位汇编第一讲x86和8086的区别,以及OllyDbg调试器的使用

    32位汇编第一讲x86和8086的区别,以及OllyDbg调试器的使用 一丶32位(x86也称为80386)与8086(16位)汇编的区别 1.寄存器的改变 AX 变为 EAX  可以这样想,16位通 ...

随机推荐

  1. Redis使用Docker镜像安装

    详细见本人以下文档: https://www.cnblogs.com/zyc-blogs/p/9621727.html

  2. ubuntu下安装g++

    主要来自ubuntu中文社区http://www.ubuntu.org.cn/support/documentation/doc/VMware 首选,确认你已经安装了build-essential程序 ...

  3. java递归复制文件夹

    package com.haiyisoft.hyoaService; import java.io.BufferedInputStream;import java.io.BufferedOutputS ...

  4. 三、Navicat将远程MySql数据库数据导入本地

    1.安装本地的MySql.记住用户名和密码,这里以root,root为例. 2.打开Navicat,新建连接(连接),输入连接名,用户名,密码.确定,连接测试.这里连接名为luzhanshi.这样本地 ...

  5. 13 Flutter仿京东商城项目 商品列表筛选以及上拉分页加载更多

    ProductList.dart import 'package:flutter/material.dart'; import '../services/ScreenAdaper.dart'; imp ...

  6. 阶段5 3.微服务项目【学成在线】_day04 页面静态化_08-freemarker基础-空值处理

    把stus注释掉 正常访问就会报错 第20行 这里的stus为空,所以造成了这个错误. 非空判断 不为空用双问号来判断 <#if stus??><#list stus as stu& ...

  7. koa中 log4js使用

    一.新建一个log4js.js配置文件 let path = require('path'); // 日志根目录 let baseLogPath = path.resolve(__dirname, ' ...

  8. iOS——偏好设置的创建,数据写入与读取

    NSUserDefaults与NSDictinary? 应用通过NSUserDefaults用键值对的方式来读取和保存偏好设置数据,与通过键从NSDictionary对象中获取数据一样,不同之处在于N ...

  9. Hadoop 部署之 Hive (五)

    目录 一.Hive 简介 1.什么是 Hive 2.为什么使用 Hive 3.Hive 的特点 4.Hive 的架构 二.Hive 安装 1.MySQL 安装(datanode01) 2.MySQL ...

  10. Linux上安装Julia-1.1

    Julia 在Linux上的安装 浙江大学Julia镜像: 浙江大学Julia镜像 下载1.1版本: wget https://mirrors.zju.edu.cn/julia/releases/v1 ...