2.8 PE结构:资源表详细解析

在Windows PE中,资源是指可执行文件中存放的一些固定不变的数据集合,例如图标、对话框、字符串、位图、版本信息等。PE文件中每个资源都会被分配对应的唯一资源ID,以便在运行时能够方便地查找和调用它们。PE文件中的资源都被组织成一个树形结构,其中最顶层为根节点(Root),下一级为资源类型(Type),再下一级为资源名称(Name),最终是实际的资源内容。

PIMAGE_RESOURCE_DIRECTORY是Windows PE可执行文件中的一个结构类型,用于描述资源(Resource)的树形结构,其中包括了每个资源的类型(Type)、名称(Name)和语言(Language),以及指向下一级PE资源目录的地址和相关信息等。

typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY
{union {struct {DWORD NameOffset:31;DWORD NameIsString:1;} DUMMYSTRUCTNAME;DWORD   Name;WORD    Id;} DUMMYUNIONNAME;union {DWORD   OffsetToData;struct {DWORD   OffsetToDirectory:31;DWORD   DataIsDirectory:1;} DUMMYSTRUCTNAME2;} DUMMYUNIONNAME2;
} IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;

PIMAGE_RESOURCE_DIRECTORY描述了Windows PE资源的目录结构,每个资源目录包括以下字段:

  • Characteristics:指定该目录的属性,如是否允许命名、是否允许ID等;
  • TimeDateStamp:指定该目录的时间戳;
  • MajorVersion / MinorVersion:指定PE文件中允许的最高版本和最低版本;
  • NumberOfNamedEntries:指定该目录中已经命名的资源条目数量;
  • NumberOfIdEntries:指定资源ID类型的数量;
  • PIMAGE_RESOURCE_DIRECTORY_ENTRY:指针,指向资源入口表,即PE文件中每个资源的入口地址。
  • PIMAGE_RESOURCE_DIRECTORY_ENTRY用于引用PE文件中资源的名称、类型和语言信息,它包括了Name/Id:指定资源的名称或ID,根据缩小范围的优先级进行查找,ID的优先级高于名称;
  • OffsetToData:指向该资源的数据偏移地址或其Resource Data Entry的地址。

读者在解析时通常需要在数据目录表PIMAGE_DATA_DIRECTORY中定位到IMAGE_DIRECTORY_ENTRY_RESOURCE资源表,通过循环的方式以此遍历出PIMAGE_RESOURCE_DIRECTORY_ENTRY中的每一个节点,最终输出资源信息,这段输出代码如下所示;

// --------------------------------------------------
// 定义资源表解析结构
// --------------------------------------------------
static char* szResName[0x11] = { 0, (char*)"鼠标指针", (char*)"位图", (char*)"图标", (char*)"菜单", (char*)"对话框", (char*)"字符串列表", (char*)"字体目录", (char*)"字体", (char*)"快捷键", (char*)"非格式化资源", (char*)"消息列表", (char*)"鼠标指针组", (char*)"zz", (char*)"图标组", (char*)"xx", (char*)"版本信息" };int main(int argc, char * argv[])
{BOOL PE = IsPeFile(OpenPeFile("c://pe/x86.exe"), 0);if (PE == TRUE){// 获取数据目录表PIMAGE_DATA_DIRECTORY pData = NtHeader->OptionalHeader.DataDirectory;// 获取到资源目录表pData = &(pData[IMAGE_DIRECTORY_ENTRY_RESOURCE]);// 获取资源目录表的偏移DWORD dwResOffset = RVAtoFOA(pData->VirtualAddress);// 获取到资源目录表PIMAGE_RESOURCE_DIRECTORY pRes = (PIMAGE_RESOURCE_DIRECTORY)(GlobalFileBase + dwResOffset);// 获取紧跟着的IMAGE_RESOURCE_DIRECTORY_ENTRY的个数DWORD dwResSize = pRes->NumberOfNamedEntries + pRes->NumberOfIdEntries;// 获取到PIMAGE_RESOURCE_DIRECTORY_ENTRY PIMAGE_RESOURCE_DIRECTORY_ENTRY  pResEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pRes + 1);printf("资源类型ID \t 类型 \n");for (DWORD i = 0; i < dwResSize; i++){// 如果为0则执行if (!pResEntry[i].NameIsString){if (pResEntry[i].Id < 0x11){// printf("资源类型ID: %p --> 类型: %s\n", pResEntry[i].Id, szResName[pResEntry[i].Id]);printf("%p \t %s \n", pResEntry[i].Id, szResName[pResEntry[i].Id]);}else{char  type[20];sprintf_s(type, "%d", pResEntry[i].Id);// printf("资源类型ID: %p --> 类型: %s\n", pResEntry[i].Id, type);printf("%p \t %s \n", pResEntry[i].Id, type);}}// 如果为1则执行else{PIMAGE_RESOURCE_DIR_STRING_U pstcString = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD)pRes + pResEntry[i].NameOffset);WCHAR szStr[MAX_PATH] = { 0 };memcpy_s(szStr, MAX_PATH, pstcString->NameString, pstcString->Length * sizeof(WCHAR));// printf("资源字符串: %ls\n", szStr);}}}else{printf("非标准程序 \n");}system("pause");return 0;
}

编译并运行上述程序片段,则读者可以看到当前程序中所包含的所有资源信息,为了简单可用此处并没有输出递归资源,仅仅输出了第一层,输出效果图如下所示;

本文作者: 王瑞
本文链接: https://www.lyshark.com/post/6532d336.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/103246.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Splunk Enterprise for Mac:卓越的数据分析与管理工具

在当今的数字化时代&#xff0c;数据已经成为企业成功的核心驱动力。然而&#xff0c;如何有效地管理和分析这些数据&#xff0c;却常常让企业感到困惑。Splunk Enterprise for Mac 是一款领先的数据分析和管理工具&#xff0c;可以帮助你解决这一难题。 Splunk Enterprise fo…

Win11打不开组策略编辑器怎么办

近期有小伙伴反映在使用Win11打开组策略编辑器的时候发现无法打开&#xff0c;这是怎么回事&#xff0c;遇到这种问题应该怎么解决呢&#xff0c;下面小编就给大家详细介绍一下Win11打不开组策略编辑器的解决方法&#xff0c;有需要的小伙伴快来和小编一起看看吧。 Win11打不开…

乐鑫 ESP-Mesh-Lite:轻松覆盖更大范围,连接更多设备

乐鑫科技 (688018.SH) 基于 Wi-Fi 协议推出了 Mesh 组网方案 ESP-Mesh-Lite&#xff0c;支持更多设备在更大范围内轻松联网。这一创新性的 Wi-Fi Mesh 技术通过构建灵活、可靠的物联网组网方案&#xff0c;使用户可以享受到快速、稳定且安全的 Wi-Fi 覆盖&#xff0c;不再受到设…

提升你的Android开发技能:从AR/VR沉浸到UI设计和故障排除

文章目录 探索最新AR/VR应用在教育、游戏、医疗等领域的应用教育领域游戏领域医疗领域 深入了解Android内存管理与性能优化的方法与技巧垃圾回收机制内存泄漏使用弱引用避免过度渲染内存优化图像优化延迟加载Android中的调试技术应用程序分析 分享如何提高Android应用的易用性和…

npm publish包报404,is not in the npm registry错误

1. 指定发布目标2. 登录npm&#xff0c;使用登录名发布包&#xff0c;包名命名原则“登录名/包名”&#xff0c;或 “包名” 3. 删除某一个版本npm unpublish pvfhv/eslint-config-prettier1.0.1 --force 删除后的版本不能重复使用&#xff0c;正式解释&#xff1a; Unfortun…

BMS电池管理系统——BMS的功能模块及基本要素(二)

BMS电池管理系统 文章目录 BMS电池管理系统前言一、BMS电池管理系统各个功能模块的关系二、BMS的边界及基本要素 前言 前面了解了BMS以及他的功能模块&#xff0c;这些功能模块之间的关系是什么呢&#xff1f; 一、BMS电池管理系统各个功能模块的关系 下面我们分析一下这张图…

java文件命令行报错: 找不到或无法加载主类XXX报错及解决

前言 之前遇到过几次&#xff0c;后面稀里糊涂的解决了。今天详细记录一下&#xff0c;可能不全或有些错误&#xff0c;还请各位指正。 你要启动一个类的话首先要有类。 在这里&#xff0c;类有两种&#xff0c; 一个是带包名&#xff08;package&#xff09;的还有一个是没包…

redis高可用——主从复制、哨兵模式、cluster集群

1、redis群集有三种模式 分别是主从同步/复制、哨兵模式、Cluster&#xff0c;下面会讲解一下三种模式的工作方式&#xff0c;以及如何搭建cIustr群集 主从复制:主从复制是高可用Redis的基础&#xff0c;哨兵和集群都是在主从复制基础上实现高可用的。主从复制主要实现了数据的…

VSCode学习笔记一:添加代码模板

一目了然 1 简述2 设置模板3 Global Snippets file示例 1 简述 问&#xff1a;为什么要设置代码模板&#xff1f; 答&#xff1a;编程语言是有个性的&#xff0c;不同语言的演讲风格是不一样的。 旁白&#xff1a;我不懂&#xff1f;&#xff01; 问&#xff1a;为什么要设置…

idea2021.1.3版本双击启动,没反应

今天打开电脑&#xff0c;点开idea&#xff0c;界面悬在这里&#xff0c;几秒然后就是没了。然后就一直打不开idea了。 然后又是卸载重装&#xff0c;又是删除缓存文件。我把电脑关于idea的文件全都删除了 。重新安装后&#xff08;首次运行倒是可以打开&#xff0c;但是关掉id…

搭建自己的OCR服务,第三步:PPOCRLabel标注工具安装

一、安装说明 安装好了PaddleOCR后&#xff0c;还需要安装PPOCRLabel这个标注工具&#xff0c;想要自己训练模型的话&#xff0c;有个标注工具会起很大作用。 尤其是PPOCRLabel就是跟PaddleOCR配套的标注工具&#xff0c;同样是开源的。 在下载 PaddleOCR 整个源码中&#x…

冠达管理:“旺季”来临,煤炭板块走高,云煤能源、陕西黑猫涨停

煤炭板块1日盘中发力走高&#xff0c;截至发稿&#xff0c;云煤动力、陕西黑猫涨停&#xff0c;兖矿动力涨超7%&#xff0c;晋控煤业、华阳股份涨超6%&#xff0c;山西焦煤、平煤股份涨超5%。 组织表明&#xff0c;动力大通胀背景下&#xff0c;未来3-5年煤炭供需偏紧的格局仍…