大致结构

  • DOS头和NT头之间通常还有个DOS Stub

DOS头

  • DOS头的作用是兼容MS-DOS操作系统中的可执行文件
  • 一般没啥用
  • 记录着PE头的位置
  • 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;
  • 主要主要两个域
  • e_magic:DOS头的开始,即MZ
  • e_lfanew:DOS头结尾,存放着NT头的地址一般为80(值),位置是在文件偏移32的位置,0x3c
  • 以下即是DOS头

DOS Stub

  • 是链接器链接执行文件的时候加入的部分数据,一般是“This program must be run under Microsoft Windows”。这个可以通过修改链接器的设置来修改成自己定义的数据。

NT头

  • 定义:
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;"双字节的数字签名,一般为PE.. | 50 45 00 00 "
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
  • IMAGE_FILE_HEADER: PE文件头
  • 定义:
typedef struct _IMAGE_FILE_HEADER {
WORD Machine;"文件的运行平台 如Intel386 (01 4c)"
WORD NumberOfSections;"文件节信息,节表中的项数"
DWORD TimeDateStamp;"文件创建时间"
DWORD PointerToSymbolTable; "COFF文件符号表在文件中的偏移"
DWORD NumberOfSymbols; "符号表的数量"
WORD SizeOfOptionalHeader; '可选头的大小'
WORD Characteristics; '可执行文件的属性'
"如 0x2000 // File is a DLL, "
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
  • 0x014c:运行平台 Intel386
  • 0x0010:节表项数
  • 5E3FA758:创建时间
  • COFF偏移:0E78
  • 符号表数量 ;052c
  • 可选头大小:00E0
  • 属性:0107

PE可选头

32位:IMAGE_OPTIONAL_HEADER32

64位:IMAGE_OPTIONAL_HEADER64

  • IMAGE_OPTIONAL_HEADER32

    定义:
typedef struct _IMAGE_OPTIONAL_HEADER {
WORD Magic; '可选头的类型'
BYTE MajorLinkerVersion;"链接器的版本号"
BYTE MinorLinkerVersion;
DWORD SizeOfCode;'代码段的长度,如果有多个代码段,则是代码段长度的总和'
DWORD SizeOfInitializedData;'初始化的数据长度'
DWORD SizeOfUninitializedData;'未初始化的数据长度'
DWORD AddressOfEntryPoint; '程序入口的RVA(偏移地址),程序入口地址'
DWORD BaseOfCode;'代码段起始地址的RVA'
DWORD BaseOfData;'数据段起始地址的RVA'
DWORD ImageBase;'映象(加载到内存中的PE文件)的基地址,这个基地址是建议'
DWORD SectionAlignment;'节对齐,PE中的节被加载到内存时会按照这个域指定的值来对齐,比如这个值是0x1000,那么每个节的起始地址的低12位都为0。'
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;'0'
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;

DataDirectory是个数组,数组中的每一项对应一个特定的数据结构,包括导入表,导出表等

#define IMAGE_DIRECTORY_ENTRY_EXPORT          0   // Export Directory
#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory
#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory
#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory
#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table
#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory
// IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // (X86 usage)
#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 // Architecture Specific Data
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // RVA of GP
#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers
#define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 // Delay Load Import Descriptors
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 // COM Runtime descriptor

参考:https://blog.csdn.net/evileagle/article/details/11903197

PE文件学习(1)DOS和NT的更多相关文章

  1. 【学习】Windows PE文件学习(一:导出表)

    今天做了一个读取PE文件导出表的小程序,用来学习. 参考了<Windows PE权威指南>一书. 首先, PE文件的全称是Portable Executable,可移植的可执行的文件,常见 ...

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

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

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

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

  4. PE文件学习系列三-PE头详解

    合肥程序员群:49313181.    合肥实名程序员群:128131462 (不愿透露姓名和信息者勿加入) Q  Q:408365330     E-Mail:egojit@qq.com 最近比较忙 ...

  5. PE文件学习系列笔记四-C++实现PE文件的分析

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

  6. PE文件学习系列一为什么是PE

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

  7. PE文件学习(2)导入表导出表

    转自:evil.eagle https://blog.csdn.net/evileagle/article/details/12176797 导出表是用来描述模块中的导出函数的结构,如果一个模块导出了 ...

  8. 解析PE文件

    最近在自学解析PE文件,根据小辣椒(CFF Explorer)以及各论坛上大佬的帖子,做了个黑屏打印PE文件的,历时7天完成,在此想跟有相关需要的同学们分享下思路,有不足之处也希望大家不吝赐教,指点出 ...

  9. 深入学习PE文件(转)

    PE文件是Win32的原生文件格式.每一个Win32可执行文件都遵循PE文件格式.对PE文件格式的了解可以加深你对Win32系统的深入理解. 一. 基本结构. 上图便是PE文件的基本结构.(注意:DO ...

随机推荐

  1. 快速创建Flask Restful API项目

    前言 Python必学的两大web框架之一Flask,俗称微框架.它只需要一个文件,几行代码就可以完成一个简单的http请求服务. 但是我们需要用flask来提供中型甚至大型web restful a ...

  2. 使用Gitee搭建个人图床

    使用Gitee搭建个人图床 一.前言 搭建个人的图床可以更加方便地管理个人图片,虽然Github也可以实现个人图床的搭建,但是,Github毕竟是外网,访问速度慢且不稳定.因此采用Gitee来搭建图床 ...

  3. Linux:注册系统服务

    [参考文章]:Systemd 入门教程:实战篇 [参考文章]:linux systemctl命令详解 1. 简介 将程序注册为系统服务后,可通过 systemctl 和 service 系统命令启动, ...

  4. Java 中为什么不能创建泛型数组?

    之前只是知道在 Java 中不能创建泛型数组,今天翻看 <Effective Java>其中对这个部分有讲解,记录一下. 现在我们假设在 Java 中可以创建泛型数组,看看可能会发生什么情 ...

  5. Python起步学习

    Python起步学习 案例1:程序输入输出 案例2:判断合法用户 安全3:编写判断成绩的程序 1 案例1:程序输入输出 1.1 问题 编写login.py脚本,实现以下目标: 提示用户输入用户名 将用 ...

  6. 【前端】HTML总结

    一. HTML介绍:---------------------------------------1. 什么是HTML?   超文本标记语言,  <标签名>--标记(标签.节点)   2. ...

  7. Vulnhub DC-7靶机渗透

    信息搜集 nmap -sP 192.168.146.0/24 #主机发现 nmap -A 192.168.146.144 #端口扫描 查看robots.txt,看看admin,403,其他没有什么可利 ...

  8. django发邮件

    django发邮件 配置setting信息 EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'sm ...

  9. 解决:docker-compose端口绑定

    docker-compose 进程绑定 Bind for 0.0.0.0:3825 failed: port is already allocated 查看进程发现有进程在关闭后继续进行 docker ...

  10. 33 File 文件及目录操作

    /* * File:文件和目录路径名的抽象表示形式,File 类的实例是不可变的 * * 构造方法: * File(String pathname) 将指定的路径名转换成一个File对象 * File ...