当前位置: 首页 > article >正文

Windows逆向工程提升之IMAGE_RESOURCE_DIRECTORY

  • 公开视频 -> 链接点击跳转公开课程
  • 博客首页 -> ​​​链接点击跳转博客主页

目录

资源目录概述

什么是资源目录?

资源目录的作用

资源目录的位置

资源目录核心结构

IMAGE_RESOURCE_DIRECTORY

IMAGE_RESOURCE_DIRECTORY_ENTRY

IMAGE_RESOURCE_DATA_ENTRY

资源目录的层次结构

第一层:类型(Type)​

第二层:名称(Name)​

第三层:语言(Language)​

资源目录解析流程

定位资源目录

遍历三层目录

内存布局

资源目录结构(根节点)​

资源目录条目(子节点)​

字符串名称结构

资源数据条目


资源目录概述

什么是资源目录?

资源目录(Resource Directory)是 PE 文件中用于存储程序非代码/数据资源的结构,例如:

  • 图标(ICO)​、位图(BMP)​、光标(CUR)​
  • 字符串表(String Table)​、对话框模板(Dialog Template)​
  • 版本信息(Version Info)​、菜单(Menu)​

资源目录的作用

  • 模块化存储:将资源独立于代码,便于管理和本地化。
  • 运行时访问:通过 API(如 LoadResource、FindResource)动态加载资源。
  • 多语言支持:同一资源可存储多种语言版本。

资源目录的位置

  • 资源目录的 RVA 和大小由 IMAGE_DATA_DIRECTORY[IMAGE_DIRECTORY_ENTRY_RESOURCE] 定义。

资源目录核心结构

资源目录采用 ​三层树形结构,由以下核心结构组成:

IMAGE_RESOURCE_DIRECTORY

typedef struct _IMAGE_RESOURCE_DIRECTORY {DWORD   Characteristics;      // 保留字段(通常为0)DWORD   TimeDateStamp;        // 时间戳(编译器生成时间)WORD    MajorVersion;         // 主版本号WORD    MinorVersion;         // 次版本号WORD    NumberOfNamedEntries; // 具名条目数量(按字符串名称索引)WORD    NumberOfIdEntries;    // ID条目数量(按整数ID索引)
} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;NumberOfNamedEntries + NumberOfIdEntries = 总条目数。
目按名称字符串或整数 ID 排序:​具名条目在前,ID条目在后。

IMAGE_RESOURCE_DIRECTORY_ENTRY

typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {union {struct {DWORD NameOffset:31;  // 名称偏移(高位为0时)DWORD NameIsString:1; // 名称是否为字符串(1=字符串,0=整数ID)};DWORD   Name;             // 整数ID或指向字符串的偏移};union {DWORD   OffsetToData;     // 指向子目录或资源数据的偏移struct {DWORD   OffsetToDirectory:31; // 子目录偏移(高位为1时)DWORD   DataIsDirectory:1;    // 是否为子目录(1=是,0=资源数据)};};
} IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;

IMAGE_RESOURCE_DATA_ENTRY

typedef struct _IMAGE_RESOURCE_DATA_ENTRY {DWORD   OffsetToData;  // 资源数据的RVA(相对于资源目录基址)DWORD   Size;          // 资源数据大小(字节)DWORD   CodePage;      // 代码页(通常为0)DWORD   Reserved;      // 保留字段
} IMAGE_RESOURCE_DATA_ENTRY, *PIMAGE_RESOURCE_DATA_ENTRY;

资源目录的层次结构

第一层:类型(Type)​

  • 功能:按资源类型分类(如图标、字符串表等)。
  • ​常见类型ID:
    • RT_ICON (3)、RT_BITMAP (2)、RT_STRING (6)

第二层:名称(Name)​

  • ​功能:按资源名称或ID分类(如 IDI_MAIN_ICON)。
  • ID资源:使用整数标识(如 101 表示第一个对话框)。

第三层:语言(Language)​

  • 功能:按语言和子语言分类(如英语、简体中文)。

资源目录解析流程

定位资源目录

  • 从 IMAGE_DATA_DIRECTORY[IMAGE_DIRECTORY_ENTRY_RESOURCE] 获取 RVA。

遍历三层目录

Root Directory (Type)├─ Type Entry 1 (e.g., RT_ICON)│    └─ Name Directory│         ├─ Name Entry 1 (e.g., IDI_MAIN)│         │    └─ Language Directory│         │         ├─ Language Entry 1 (e.g., 0x0409)│         │         │    └─ Data Entry (OffsetToData, Size)│         │         └─ ...│         └─ ...└─ Type Entry 2 (e.g., RT_VERSION)└─ ...

内存布局

资源目录结构(根节点)​

起始位置:由数据目录IMAGE_DIRECTORY_ENTRY_RESOURCE指定RVA,需转换为FOA访问。

typedef struct _IMAGE_RESOURCE_DIRECTORY {DWORD Characteristics;      // 资源标志(通常为0)DWORD TimeDateStamp;         // 时间戳WORD  MajorVersion;          // 主版本号WORD  MinorVersion;          // 次版本号WORD  NumberOfNamedEntries;   // 命名条目数量WORD  NumberOfIdEntries;     // ID条目数量
} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;
  • 大小:16字节(4+4+2+2+2+2)
  • 位置:资源表起始位置(FOA = RvaToFoa(ResourceDirRva))
  • 作用:描述当前层级的资源条目数量和类型。

资源目录条目(子节点)​

紧跟在每个IMAGE_RESOURCE_DIRECTORY结构之后的是多个目录条目。

typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {union {struct {DWORD NameOffset:31;  // 名称偏移(相对资源表起始地址)DWORD NameIsString:1;  // 是否为字符串名称(1=是,0=ID)};DWORD Name;                // 资源ID(当NameIsString=0时)};union {DWORD OffsetToData;        // 偏移到数据或子目录struct {DWORD OffsetToDirectory:31; // 子目录偏移(相对资源表起始地址)DWORD DataIsDirectory:1;    // 是否指向子目录(1=是,0=数据条目)};};
} IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;
  • 大小:8字节(4+4) 
  • 布局规则:
    • ameIsString=1:条目名称是Unicode字符串,通过NameOffset定位到IMAGE_RESOURCE_DIR_STRING_U结构。
    • ​DataIsDirectory=1:指向下一层级的IMAGE_RESOURCE_DIRECTORY。
    • DataIsDirectory=0:指向IMAGE_RESOURCE_DATA_ENTRY。

字符串名称结构

IMAGE_RESOURCE_DIR_STRING_U

typedef struct _IMAGE_RESOURCE_DIR_STRING_U {WORD Length;           // 字符串长度(字符数)WCHAR NameString[1];   // Unicode字符串(变长,以NULL结尾)
} IMAGE_RESOURCE_DIR_STRING_U, *PIMAGE_RESOURCE_DIR_STRING_U;
  • 大小:2 + Length*2字节
  • ​位置:资源表起始地址 + NameOffset

资源数据条目

IMAGE_RESOURCE_DATA_ENTRY

typedef struct _IMAGE_RESOURCE_DATA_ENTRY {DWORD OffsetToData;   // 资源数据RVADWORD Size;           // 资源数据大小DWORD CodePage;       // 代码页(通常为0)DWORD Reserved;       // 保留字段
} IMAGE_RESOURCE_DATA_ENTRY, *PIMAGE_RESOURCE_DATA_ENTRY;
  • 大小:16字节(4+4+4+4)
  • 位置:资源表起始地址 + OffsetToData
  • 作用:指向实际的资源数据(如版本信息、图标、位图等)。
http://www.lryc.cn/news/2385344.html

相关文章:

  • 使用ps为图片添加水印
  • x64_ubuntu22.04.5安装:cuda driver + cuda toolkit
  • 开盘啦 APP 抓包 逆向分析
  • vs2022 Qt Visual Studio Tools插件设置
  • Python包__init__.py标识文件解析
  • 【MySQL】第8节|Innodb底层原理与Mysql日志机制深入剖析(一)
  • 电商ERP管理系统,Java+Vue,含源码与文档,统筹订单、库存等,助力电商企业高效运营
  • Spring Boot微服务架构(四):微服务的划分原则
  • 【打卡】树状数组的操作
  • OpenLayers 加载动画控件
  • Oracle 基础知识作业的使用
  • HTTP协议初认识、速了解
  • C#:多线程Task使用
  • 模拟电子技术基础----绪论
  • 从零基础到最佳实践:Vue.js 系列(2/10):《模板语法与数据绑定》
  • iOS 使用 - 设置 来电震动/关闭震动
  • anaconda、miniconda、conda的关系及miniconda安装
  • [C语言初阶]扫雷小游戏
  • 谷歌medgemma-27b-text-it医疗大模型论文速读:多语言大型语言模型医学问答基准测试MedExpQA
  • Lambda表达式的高级用法
  • 速盾(sudun):如何利用CDN技术实现页面加速?
  • DeepSeek+白果AI论文:开启答辩PPT生成的「智能双引擎」时代
  • Jest入门
  • SDC命令详解:使用set_logic_dc命令进行约束
  • 小程序涉及提供提供文本深度合成技术,请补充选择:深度合成-AI问答类目
  • SQL每日一练(2)
  • 基于亚博K210开发板——lvgl 图形化实验
  • LABVIEW 通过节点属性动态改变数值显示控件的方法
  • 信息安全管理与评估2025上海卷
  • el-form 使用el-row el-col对齐 注意事项