扩展PE头属性说明

cpp 复制代码
//大小: 32bit(0xE0) 64bit(0xF0)
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES    16
typedef struct _IMAGE_OPTIONAL_HEADER {
    WORD    Magic;                          //文件类型: 10b为32位PE文件 / 20b为64位PE文件
BYTE    MajorLinkerVersion;             //链接器(主)版本号 对执行没有任何影响
BYTE    MinorLinkerVersion;             //链接器(次)版本号 对执行没有任何影响
DWORD   SizeOfCode;                     //包含代码的节的总大小.文件对齐后的大小.编译器填的没用
DWORD   SizeOfInitializedData;          //包含已初始化数据的节的总大小.文件对齐后的大小.编译器填的没用.
DWORD   SizeOfUninitializedData;        /*包含未初始化数据的节的总大小.文件对齐后的大小.编译器填的没用. 
                                          (未初始化数据,在文件中不占用空间;但在被加载到内存后,PE加载程序 
                                          会为这些数据分配适当大小的虚拟地址空间)*/
DWORD   AddressOfEntryPoint;            //程序入口(RVA)
DWORD   BaseOfCode;                     /*代码的节的基址(RVA).编译器填的没用(代码节起始的RVA,表示  
                                               映像被加载进内存时代码节的开头相对于ImageBase的偏移地址, 
                                               节的名称通常为".text")*/
DWORD   BaseOfData;                     /*数据的节的基址(RVA).编译器填的没用(数据节起始的RVA,表示  
                                              映像被加载进内存时数据节的开头相对于ImageBase的偏移地址, 
                                              节的名称通常为".data")*/
DWORD   ImageBase;                      //内存镜像基址
DWORD   SectionAlignment;               //内存对齐大小
DWORD   FileAlignment;                  //文件对齐大小
WORD    MajorOperatingSystemVersion;    //标识操作系统主版本号 
WORD    MinorOperatingSystemVersion;    //标识操作系统次版本号 
WORD    MajorImageVersion;              //PE文件自身的主版本号
WORD    MinorImageVersion;              //PE文件自身的次版本号
WORD    MajorSubsystemVersion;          //运行所需子系统主版本号
WORD    MinorSubsystemVersion;          //运行所需子系统次版本号
DWORD   Win32VersionValue;              //子系统版本的值.必须为0,否则程序运行失败.
DWORD   SizeOfImage;                    /*内存中整个PE文件的映射尺寸.可比实际的值大.必须是SectionA 
                                              lignment的整数倍*/
DWORD   SizeOfHeaders;                  //所有头+节表按照文件对齐后的大小.
DWORD   CheckSum;                       /*校验和.大多数PE文件该值为0.在内核模式的驱动程序和系统DLL中,该 
                                          值则是必须存在且是正确的.在IMAGEHLP.DLL中函数CheckSumMapped 
                                          File就是用来计算文件头校验和的,对于整个PE文件也有一个校验函数 
                                          MapFileAndCheckSum.*/
    WORD    Subsystem;                      //文件子系统  驱动程序(1) 图形界面(2) 控制台/DLL(3)
    WORD    DllCharacteristics;             //文件特性.不是针对DLL文件的
    DWORD   SizeOfStackReserve;             /*初始化时保留的栈大小.该字段默认值为0x100000(1MB),如果调 
                                              用API函数CreateThread时,堆栈参数大小传入NULL,则创建出来 
                                              的栈大小将是1MB.*/
    DWORD   SizeOfStackCommit;              /*初始化时实际提交的栈大小.保证初始线程的栈实际占用内存空间 
                                              的大小,它是被系统提交的.这些提交的栈不存在与交换文件里,而 
                                              是在内存中.*/
    DWORD   SizeOfHeapReserve;              /*初始化时保留的堆大小.用来保留给初始进程堆使用的虚拟内存,这 
                                              个堆的句柄可以通过调用函数GetProcessHeap获得.每一个进程 
                                              至少会有一个默认的进程堆,该堆在进程启动时被创建,而且在进程 
                                              的生命期中不会被删除.默认值为1MB.*/
    DWORD   SizeOfHeapCommit;               /*初始化时实践提交的堆大小.在进程初始化时设定的堆所占用的内 
                                              存空间,默认值为PAGE_SIZE. */
    DWORD   LoaderFlags;                    //调试相关
    DWORD   NumberOfRvaAndSizes;            //目录项数目,默认为0x10
    IMAGE_DATA_DIRECTORY DataDirectory[16]; //结构数组,里面是16张表                     
} IMAGE_OPTIONAL_HEADER32, * PIMAGE_OPTIONAL_HEADER32;

扩展 PE 头概述

PE 头部整体由 PE 标识、标准 PE 头、扩展 PE 头三部分构成

32 位与 64 位程序的 PE 头结构大体一致,仅有少量区别

32 位程序扩展 PE 头默认大小为 224 字节

32 位与 64 位扩展 PE 头区别

32 位结构体:IMAGE_OPTIONAL_HEADER32

64 位结构体:IMAGE_OPTIONAL_HEADER64

核心区别:成员的数据宽度与成员数量不同

关键字段

Magic:用来区分程序是 32 位还是 64 位镜像

程序内存与入口信息

AddressOfEntryPoint:程序入口 RVA 地址

ImageBase:内存镜像基址(程序默认加载的基地址)

入口地址是相对于镜像基址的相对偏移

对齐与镜像尺寸

SectionAlignment:内存对齐大小

FileAlignment:文件对齐大小

SizeOflmage:内存中整个PE文件的映射尺寸可比实际的值大,必须是SectionAlignment的整数倍

SizeOfHeaders:所有头+节表按照文件对齐后的大小

校验和

CheckSum:文件校验值

用途:校验文件是否被篡改,驱动程序必须保证校验和有效

子系统与动态属性

Subsystem:子系统类型,区分控制台程序、窗口 GUI 程序、驱动程序等

DllCharacteristics:镜像动态属性,不是针对DLL文件的

DllCharacteristics特征位对照表:

数据位 常量符号 为 1 时的含义
0 ------(保留位) 保留,必须为 0
1 ------(保留位) 保留,必须为 0
2 ------(保留位) 保留,必须为 0
3 ------(保留位) 保留,必须为 0
4 ------(保留位) 保留,必须为 0
5 ------(保留位) 保留,必须为 0
6 IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE DLL 可以在加载时被重定位
7 IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY 强制代码实施完整性验证
8 IMAGE_DLLCHARACTERISTICS_NX_COMPAT 该映像兼容 DEP
9 IMAGE_DLLCHARACTERISTICS_NO_ISOLATION 可以隔离,但并不隔离此映像
10 IMAGE_DLLCHARACTERISTICS_NO_SEH 映像不使用 SEH
11 IMAGE_DLLCHARACTERISTICS_NO_BIND 不绑定映像
12 ------(保留位) 保留,必须为 0
13 IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 该映像为一个 WDM driver
14 ------(保留位) 保留,必须为 0
15 IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 可用于终端服务器
相关推荐
秋名RG1 小时前
Java 基础语法
java·开发语言
码行山野赴时序归途1 小时前
C 语言文件操作完全指南:从打开到关闭
c语言·开发语言
2501_937860941 小时前
Java 文件操作与IO(下):字节流、字符流实战IO读写
java·开发语言·python
事圆则缓1 小时前
Kotlin 高阶工程化与 Android 深入实践
android·开发语言·kotlin
驭渊的小故事1 小时前
java抽奖项目-奖品上传中传递参数类型的错误
java·开发语言
名字还没想好☜1 小时前
Go 时间格式化为什么用 2006-01-02:time.Format/Parse 的参考时间、时区与解析踩坑
开发语言·后端·golang·go
Dream Cosmos2 小时前
C++ 多态下篇:虚函数表、动态绑定与多态底层原理
开发语言·c++
2601_9620715710 小时前
【Java报错已解决】org.springframework.beans.factory.BeanCreationException
java·开发语言
淡海水11 小时前
07-04-并发-ConcurrentBag-T-工作窃取WorkStealing算法
开发语言·算法·c#·bag·concurrent·workstealing