扩展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 可用于终端服务器
相关推荐
死磕音视频4 小时前
让小模型做选择题:限定候选项并读取 logits 概率的入门实践(附 Python 代码)
开发语言·python·大模型·文本分类·transformers
顽疲7 小时前
Java vue 养老系统源码详解:月账单 care_month_bill 与 Quartz 扣费 Job 实践
java·开发语言·vue.js·vue养老·springboot养老·java养老
看着博客敲代码7 小时前
nikto 扫描报 0 host(s) tested 与 Web 服务器漏洞扫描用法
安全·web安全·网络安全
Wang's Blog7 小时前
Java 项目实战: 交友项目 - 安装开发工具与环境准备
java·开发语言·交友
看着博客敲代码9 小时前
gobuster 报 the server returns a status code that matches 与 目录爆破用法
安全·网络安全·系统安全
程序喵大人9 小时前
【C++入门】编译链接模型 - 07 链接器怎样把符号对上号
开发语言·c++·编译器·编译链接·链接器
微三云 - 廖会灵 (私域系统开发)9 小时前
供应链系统实战:多渠道订单聚合与分布式库存一致性方案总结
开发语言·分布式·php
小枣信安9 小时前
MCP安全系列之缺乏日志审计
安全·网络安全·ai安全·大模型安全·智能体安全·mcp安全
学逆向的9 小时前
C 数据溢出与精度丢失
c语言·开发语言·网络安全
霸道流氓气质10 小时前
AgentFlow 入门与实战:Task-Based 并发、EWMA 动态调度与四道门禁的 Java 生产级编排
java·开发语言