扩展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 可用于终端服务器
相关推荐
小羊没烦恼!3 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
伞伞悦读3 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
C语言小火车3 天前
C/C++ 为什么需要编译器?
开发语言·c++
霍霍的袁3 天前
【C++】map 和 set 的使用 | 从用法到底层
开发语言·c++·学习·visual studio
孙启超3 天前
【AI开发之Rust】第 11 课:智能指针与内部可变性
开发语言·后端·rust
此生决int3 天前
深入理解C++系列(20)——C++11(下)
开发语言·c++
XUEYUAN52123 天前
ASN 自治系统号风控:平台如何通过 IP 所属自治域批量识别代理流量
python·网络协议·http·网络安全·socks5
其实防守也摸鱼3 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
TechEdu2026063 天前
[人工智能]人工智能时代的零日漏洞与零日攻击
人工智能·网络安全·ai·信息安全
CoderYanger3 天前
A.每日一题:835. 图像重叠
java·开发语言·程序人生·leetcode·面试·职场和发展·学习方法