找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1094

积分

0

好友

158

主题
发表于 昨天 02:56 | 查看: 7| 回复: 0

加载配置表在PE文件中的位置

加载配置表(Load Configuration Table)是存储在PE文件可选头(Optional Header)数据目录(Data Directory)数组中的一个关键结构。它位于该数组的第11个条目,索引值为10。

数据目录结构:

数据目录数组(共16个条目):
0.  导出表 (Export Table)
1.  导入表 (Import Table)
2.  资源表 (Resource Table)
3.  异常表 (Exception Table)
4.  证书表 (Certificate Table)
5.  基址重定位表 (Base Relocation Table)
6.  调试数据 (Debug Data)
7.  版权信息 (Architecture Specific Data)
8.  全局指针 (Global Pointer)
9.  TLS表 (Thread Local Storage Table)
10. 加载配置表 (Load Configuration Table) // 索引为10
11. 绑定导入表 (Bound Import Table)
12. 导入地址表 (Import Address Table)
13. 延迟导入表 (Delay Import Descriptor)
14. CLR运行时头 (CLR Runtime Header)
15. 保留 (Reserved)

加载配置表的数据结构

加载配置表的核心是一个名为IMAGE_LOAD_CONFIG_DIRECTORY的结构体,它针对32位和64位架构有不同版本,以适应不同位宽的地址。

32位版本 (IMAGE_LOAD_CONFIG_DIRECTORY32)
typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY32 {
    DWORD   Size; // 结构体大小
    DWORD   TimeDateStamp; // 时间戳
    WORD    MajorVersion; // 主版本号
    WORD    MinorVersion; // 次版本号
    DWORD   GlobalFlagsClear; // 全局标志清除
    DWORD   GlobalFlagsSet; // 全局标志设置
    DWORD   CriticalSectionDefaultTimeout; // 临界区默认超时
    DWORD   DeCommitFreeBlockThreshold; // 释放块阈值
    DWORD   DeCommitTotalFreeThreshold; // 总释放阈值
    DWORD   LockPrefixTable; // 锁前缀表地址
    DWORD   MaximumAllocationSize; // 最大分配大小
    DWORD   VirtualMemoryThreshold; // 虚拟内存阈值
    DWORD   ProcessHeapFlags; // 进程堆标志
    DWORD   ProcessAffinityMask; // 进程亲和性掩码
    WORD    CSDVersion; // CSD版本
    WORD    DependentLoadFlags; // 依赖加载标志
    DWORD   EditList; // 编辑列表地址
    DWORD   SecurityCookie; // 安全Cookie地址
    DWORD   SEHandlerTable; // SE异常处理表地址
    DWORD   SEHandlerCount; // SE异常处理程序数量
    // Windows 10 1607及以后版本新增字段
    DWORD   GuardCFCheckFunctionPointer;
    DWORD   GuardCFDispatchFunctionPointer;
    DWORD   GuardCFFunctionTable;
    DWORD   GuardCFFunctionCount;
    DWORD   GuardFlags;
    // Windows 10 1703及以后版本新增字段
    IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity;
    // Windows 10 1903及以后版本新增字段
    DWORD   GuardAddressTakenIatEntryTable;
    DWORD   GuardAddressTakenIatEntryCount;
    DWORD   GuardLongJumpTargetTable;
    DWORD   GuardLongJumpTargetCount;
    // Windows 10 2004及以后版本新增字段
    DWORD   DynamicValueRelocTable;
    DWORD   CHPEMetadataPointer;
    // Windows 10 20H1及以后版本新增字段
    DWORD   GuardRFFailureRoutine;
    DWORD   GuardRFFailureRoutineFunctionPointer;
    DWORD   DynamicValueRelocTableOffset;
    DWORD   DynamicValueRelocTableSection;
    DWORD   Reserved2;
    // Windows 10 21H1及以后版本新增字段
    DWORD   GuardRFVerifyStackPointerFunctionPointer;
    DWORD   HotPatchTableOffset;
    // Windows 11及以后版本新增字段
    DWORD   Reserved3;
    DWORD   EnclaveConfigurationPointer;
    DWORD   VolatileMetadataPointer;
} IMAGE_LOAD_CONFIG_DIRECTORY32;
64位版本 (IMAGE_LOAD_CONFIG_DIRECTORY64)

64位版本结构体与32位版本基本对应,主要区别在于地址相关的字段(如指针和阈值)使用了ULONGLONG类型以适应64位地址空间。

typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY64 {
    DWORD      Size;
    DWORD      TimeDateStamp;
    WORD       MajorVersion;
    WORD       MinorVersion;
    DWORD      GlobalFlagsClear;
    DWORD      GlobalFlagsSet;
    DWORD      CriticalSectionDefaultTimeout;
    ULONGLONG  DeCommitFreeBlockThreshold;
    ULONGLONG  DeCommitTotalFreeThreshold;
    ULONGLONG  LockPrefixTable;
    ULONGLONG  MaximumAllocationSize;
    ULONGLONG  VirtualMemoryThreshold;
    ULONGLONG  ProcessAffinityMask;
    DWORD      ProcessHeapFlags;
    WORD       CSDVersion;
    WORD       DependentLoadFlags;
    ULONGLONG  EditList;
    ULONGLONG  SecurityCookie;
    ULONGLONG  SEHandlerTable;
    ULONGLONG  SEHandlerCount;
    // 后续字段与32位版本含义相同,类型为ULONGLONG
    ULONGLONG  GuardCFCheckFunctionPointer;
    ULONGLONG  GuardCFDispatchFunctionPointer;
    ULONGLONG  GuardCFFunctionTable;
    ULONGLONG  GuardCFFunctionCount;
    DWORD      GuardFlags;
    IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity;
    ULONGLONG  GuardAddressTakenIatEntryTable;
    ULONGLONG  GuardAddressTakenIatEntryCount;
    ULONGLONG  GuardLongJumpTargetTable;
    ULONGLONG  GuardLongJumpTargetCount;
    ULONGLONG  DynamicValueRelocTable;
    ULONGLONG  CHPEMetadataPointer;
    ULONGLONG  GuardRFFailureRoutine;
    ULONGLONG  GuardRFFailureRoutineFunctionPointer;
    DWORD      DynamicValueRelocTableOffset;
    DWORD      DynamicValueRelocTableSection;
    DWORD      Reserved2;
    ULONGLONG  GuardRFVerifyStackPointerFunctionPointer;
    DWORD      HotPatchTableOffset;
    DWORD      Reserved3;
    ULONGLONG  EnclaveConfigurationPointer;
    ULONGLONG  VolatileMetadataPointer;
} IMAGE_LOAD_CONFIG_DIRECTORY64;

加载配置表各字段详解

了解PE文件结构是深入系统底层和网络/系统知识的基础。加载配置表中的字段可大致分为以下几类:

基础字段

  • Size: 结构体大小,用于标识版本和确定需要解析的字段范围。
  • TimeDateStamp: 时间戳,标识结构体的创建或修改时间。
  • MajorVersion/MinorVersion: 主次版本号,对应不同Windows版本的功能集。
  • GlobalFlagsClear/Set: 用于控制进程的全局标志位。
  • CriticalSectionDefaultTimeout: 临界区(Critical Section)操作的默认超时值。

内存管理字段

  • DeCommitFreeBlockThreshold: 内存释放的块大小阈值。
  • DeCommitTotalFreeThreshold: 内存释放的总大小阈值。
  • MaximumAllocationSize: 单次内存分配允许的最大尺寸。
  • VirtualMemoryThreshold: 虚拟内存管理的相关阈值。
  • ProcessHeapFlags: 进程堆的创建标志,影响堆的内存布局和行为。

安全防护字段
这是加载配置表在现代Windows中的核心价值所在,构成了重要的安全防护机制

  • SecurityCookie: /GS编译选项生成的安全Cookie地址,用于防范栈缓冲区溢出。
  • SEHandlerTable/SEHandlerCount: 安全结构化异常处理(SafeSEH)表的信息,防止SEH记录被恶意覆盖。
  • GuardCF...系列字段: 控制流防护(Control Flow Guard, CFG)相关数据,用于抵御面向返回编程(ROP)等代码复用攻击。
  • GuardFlags: 控制流保护的各种功能开关。
  • CodeIntegrity: 包含代码完整性校验信息。

加载配置表的核心作用与安全特性

加载配置表在程序加载和运行时扮演着关键角色,其设计初衷和主要作用集中在以下几个方面:

1. 增强程序安全性

  • 栈缓冲区溢出保护 (/GS): 通过SecurityCookie(又称“栈Cookie”)在函数栈帧中插入随机值,并在函数返回前验证其完整性,有效检测和阻止经典的栈溢出攻击。
  • 安全结构化异常处理 (/SafeSEH): 通过SEHandlerTable维护一个合法的异常处理程序列表。当异常发生时,系统会验证异常处理函数指针是否位于该表中,从而阻止攻击者利用溢出漏洞篡改SEH链并执行恶意代码。
  • 控制流防护 (/Guard:CF): 这是现代Windows最强大的缓解措施之一。它通过GuardCFFunctionTable维护一个有效的间接调用目标地址集合。在每次进行间接调用(如通过函数指针或虚函数表)前,运行时会对目标地址进行检查,确保其是合法的函数入口点,极大增加了ROP/JOP攻击的难度。

2. 优化内存管理
加载配置表提供了多个字段供系统加载器(Loader)和堆管理器(Heap Manager)进行内存管理优化,例如调整内存提交与回收的策略、设置进程堆的初始属性等,以平衡性能与资源使用。

3. 支持系统兼容性与演进
通过SizeMajorVersion/MinorVersion字段,该结构体能够优雅地扩展。新版本的Windows可以定义包含新字段的新版本结构体,而旧系统在加载时仅会处理其已知的字段部分,确保了向后兼容性。

实际应用与查看方法

编译器选项启用
在Visual Studio等编译环境中,可以通过以下选项启用相关安全功能,编译器会自动生成并填充加载配置表中的对应字段:

/GS           // 启用栈安全检查(生成SecurityCookie)
/SafeSEH      // 启用安全结构化异常处理
/Guard:CF     // 启用控制流防护

查看加载配置表内容
可以使用以下工具查看PE文件中的加载配置信息:

  • dumpbin (Visual Studio 命令行工具): 使用 dumpbin /loadconfig <filename.exe> 命令。
  • PE解析工具: 如CFF Explorer、PE-bear等图形化工具,可以直观地查看数据目录及加载配置结构的各个字段值。

一个典型的dumpbin /loadconfig输出示例如下:

Load Configuration Directory:
  Size:                        00000048
  TimeDateStamp:               00000000
  MajorVersion:                0000
  MinorVersion:                0000
  GlobalFlagsClear:            00000000
  GlobalFlagsSet:              00000000
  CriticalSectionDefaultTimeout: 00000000
  DeCommitFreeBlockThreshold:   00000000
  DeCommitTotalFreeThreshold:   00000000
  LockPrefixTable:              00000000
  MaximumAllocationSize:        00000000
  VirtualMemoryThreshold:       00000000
  ProcessHeapFlags:            00000000
  ProcessAffinityMask:          00000000
  CSDVersion:                  0000
  DependentLoadFlags:          0000
  EditList:                    00000000
  SecurityCookie:              00401000
  SEHandlerTable:              00000000
  SEHandlerCount:              00000000

版本演进与总结

加载配置表随着Windows系统的安全需求而不断演进:

  1. 早期版本 (如 Windows XP): 主要包含基础字段和内存管理字段。
  2. Windows Vista/7: 引入了SecurityCookieSEHandlerTable等关键安全字段。
  3. Windows 8/8.1 及 Windows 10 初期: 加入了控制流防护(CFG)的基础字段。
  4. Windows 10 后续更新及 Windows 11: 持续扩展,增加了更精细的CFG策略(如GuardAddressTakenIatEntryTable)、返回流防护(RFG)、代码完整性验证等高级安全字段。

总结
加载配置表是PE文件格式中至关重要的组成部分,它作为连接编译器、链接器和操作系统加载器的桥梁,承载了丰富的安全策略与运行时配置信息。其核心价值在于为现代Windows应用程序提供了纵深防御的安全基础,包括栈保护、异常处理保护和控制流完整性保护等关键缓解措施。对于软件开发者、安全研究员和逆向工程师而言,深入理解加载配置表是分析Windows程序行为、评估其安全态势和进行漏洞挖掘的必备知识。




上一篇:Vue 3与Vue 2深度对比:Composition API、性能优化与TypeScript支持全解析
下一篇:React Scan 实战指南:自动化检测 React 组件渲染性能瓶颈
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-17 16:03 , Processed in 0.117228 second(s), 38 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表