WindowsPE 第七章 资源表
资源表
在程序设计中,总会设计一些数据。这些数据可能是源代码内部需要用到的常量,菜单选项、界面描述等;也可能是源代码外部的,比如程序的图标文件、北京音乐文件、配置文件等,以上这些数据统称为资源。按照程序与数据分离的设计思想,最理想的方案是单独为程序所需要的数据安排一节来存储-PE中的资源就是这么做的。
7.1资源分类
资源数据在PE里是最复杂的一种。其难度主要体现在对资源数据的遍历定位上,以及资源块的不易阅读性。因为即使通过信息定位方法找到了资源块,其内部结构还需要进一步解析。首先来看资源分类的历史。
刚开始资源类型方面,以为16个种类足以了,然而后来发现并不够,这类问题再之前很容易理解。就如千年虫问题...
程序中常用的六类资源包括:
位图资源、光标资源、图标资源、菜单资源、对话框资源、自定义资源。
7.1.1 位图、光标、图标资源
位图、光标和图标是标识程序用途、修饰程序的最简约的符号,一般对应ico、cur、ani和bmp文件内容。这三种资源最终都是基于图片文件。在对资源脚本文件进行定义时,通常使用文件名,最后由资源编译器rc.exe将像素数据读入,在转化为二进制格式存储在PE的资源表指向的位置。位图、光标、图标这三类资源在脚本文件中的定义格式如下:
7.1.2 菜单资源
菜单资源是大部分应用程序都具备的资源。在资源脚本文件中,菜单的定义格式如下所示:
菜单ID MENU [DISCARDABLE]
BEGIN
菜单项定义
......
END
7.1.3 对话框资源
对话框也是大部分程序具备的一种资源。弹出式对话框人性化地排列着文本框、说明文字和按钮等可视化控件,使复杂的计算机操作变得容易。语法如下:
对话框ID DIALOG[DISCARDABLE] x坐标,y坐标,宽度,高度[options]
BEGIN
子窗口控件1
子窗口控件2
......
END
对话框的可可选属性及描述:
7.1.4 自定义资源
通常,当开发者需要在PE文件中附带自定义数据时,可以使用自定义资源。其在资源文件中的定义语法如下:
资源ID 类型ID [DISCARDABLE]
BEGIN
数据定义
......
END
大部分情况下,都是讲一个磁盘文件当做资源的内容。此时的语法简化为:
资源ID 类型ID [DISCARDABLE] 文件名
类型ID可以是大于255的数值或字符串,如可以定义如下自定义资源:
7.2 PE资源表组织
这节主要说PE文件中资源数据的组织方式,并通过实例介绍针对资源数据定义的数据结构以及在PE中定位资源表的方法。
7.2.1 资源表的组织方式
PE的资源组织方式类似于操作系统的文件管理方式。从根目录开始,下设一级子目录、二级子目录和三级子目录;三级子目录下才是文件。其三级目录结构如下:
一级子目录按照资源类型分类。
二级子目录按照资源ID分类。
三级子目录按照资源代码页分类。
三级子目录后即为节点,也就是所说的文件。这里的文件其实就是包含了资源数据的指针和大小等信息的一个数据结构而已。对于所有资源数据块的访问均可以从这里开始。
由于一、二、三级目录的数据结构是相同的,均是由一个资源目录头加上多个现行跟随着的资源目录项组成,将主干和枝干的节点成为资源目录结构单元。如下图:
从数据结构的角度来看,资源表示一个四层的儿茶排序树结构。其中,第一层为主干,第二、三层为枝干,叶子节点为第四层。主干和枝干的节点即为资源目录结构单元,完整示意图如下:
7.2.2 资源表数据定位
资源表是一张描述资源数据在PE中的分布情况的表。资源表是数据目录中注册的数据类型之一,其描述信息位于数据目录第3个目录项中。
7.2.3 资源目录头IMAGE_RESOURCE_DIRECTORY
资源表数据从第一级资源目录开始。资源的每一级目录都会有一个资源目录头,它标识了该类资源的属性、创建日期和版本等信息,其中也包含了随后的目录项的数量描述信息。
详细结构定义如下:
然后是结构详解:
73.MAGE_RESOURCE_DIRECTORY.Characteristics
+0000h,双字。资源属性,保留为将来使用,必须为0。
74.MAGE_RESOURCE_DIRECTORY.TimeDateStamp
+0004h,双字。时间戳,即创建该资源的时间。
75.MAGE_RESOURCE_DIRECTORY.MajorVersion/MinorVersion;
+0008h,双字。资源版本号。未用,大部分情况为0。
76.MAGE_RESOURCE_DIRECTORY.NumberOfNamedEntries
+000ch,双字。以名称命名的资源个数。
77.MAGE_RESOURCE_DIRECTORY.NumberOfIdEntries
+000eh,双字。以ID命名的资源个数。
以上字段中,最重要的是76和77两个字段。在资源脚本文件中,定义资源时,既可以使用字符串作为名称来标识一个资源,也可以通过ID号来标识资源。资源目录项的数量等于两者之和。
7.2.4资源目录项IMAGE_RESOURCE_DIRECTORY_ENTRY
紧跟在资源目录后的数据结构,就是在资源目录中声明的资源目录项。一个资源目录可能有多个资源目录项(以名称定义的资源目录项或以ID定义的资源目录项,或两者组合),目录项和目录项之间是线性排列的。首先按照字母升序(不区分大小写)排列名称资源目录项,然后再按照ID升序排列资源目录项。下图是资源目录项及目录项之间的关系示意图。
资源目录项数据结构的详细定义如下:
上面有一个union定义,我也是第一次看到这个类型,百度了一下:
78.IMAGE_RESOURCE_DIRECTORY_ENTRY.Namee1
+0000h,双字。第一个union字段,它定义了目录项的名称或者ID。
该双字的高位(即31位)如果为1,则表示低地址部分为一个纸箱Uniconde字符串的指针(注意,这里的字符串不是Ansi字符串,所以另有规定);如果为0,则表示该字段为一个编号。
资源中对字符串的定义全部采用Unicode编码,该指针并不是直接指向一个以“\0”结尾的字符串所在地址,而是指向了结构IMAGE_RESOURCE_DIR_STRING_U。
该结构完善了指针的定义(即不仅包含指针,还包含指针纸箱的块的长度),其详细结构如下:
79.IMAGE_RESOURCE_DIRECTORY_ENTRY.OffsetToData
+0004h,双字。这个字段是一个指针,当它的高位(第31位)为0时,指针指向的是描述资源数据块的指针,通常出现在第三级目录中;当高位为1时,地位数据指向下一级目录快的起始地址。
提示:字段78、79中的地址并不是基于文件起始地址的,它的偏移是基于资源表的起始位置。一定要清楚这一点,否则在定位资源表的时候会出现错误。
7.2.5 资源数据项IMAGE_RESOURCE_DATA_ENTRY
资源数据项其实就是前面所说的目录-文件中的文件。他是通过三次目录定位后找到的一个数据结构,下图显示了资源数据项与三级目录和最终的资源数据块之间的关系。
第三级目录项中的字段IMAGE_RESOURCE_DIREXTORY_ENTRY.OffsetToData指向了资源数据项,而资源数据项中的OffsetToData字段则指向了资源数据块。
资源数据项的详细结构如下:
80.IMAGE_RESOURCE_DATA_ENTRY.OffsetToData
+0000h,双字。该字段是一个纸箱资源数据块的指针,是一个RVA值,在文件中访问时需要注意转换成文件偏移。此处指向的资源数据块还不是赤裸裸的资源信息,而是附加了一些数据结构的资源快。
81.IMAGE_RESOURCE_DATA_ENTRY.Size1
+0004h,双字。资源数据的大小。
82.IMAGE_RESOURCE_DATA_ENTRY.CodePage
+0008h,双字。代码页,未用,大多数情况下为0.
83.IMAGE_RESOURCE_DATA_ENTRY.Reserved
+000ch,双字。保留字段。总是0。
对资源表的大部分编程,只要能解析出该结构中制定资源快所处的地址和资源快的大小,资源表的使命也就算完成了。
7.2.6 三级结构中目录项的区别
由于目录处的级别不同,目录中各字段所表述的内容也不一样;尽管他们具有相同的数据结构和完全相同的字段,在不同级别的目录项中有些数字段的含义是不一样的。
1.IMAGE_RESOURCE_DATA_ENTRY.Name1
(1)字段最高位(即31位)为1
当结构用于第一层目录时,表示这是一个非标准的类型。
当结构用于第二层目录时,表示这是一个非标准的命名。
当结构用于第三层目录时,表示这是一个非标准的语言。
(2)字段31位为0
当结构用于第一层目录时,表示这是一个标准的类型。
当结构用于第二层目录时,表示这是一个标准的命名。
当结构用于第三层目录时,表示这是一个标准的语言。
2.IMAGE_RESOURCE_DATA_ENTRY.OffsetToData
(1)字段第31位为1
当结构用于第一层目录时,下一级目录地址。
当结构用于第二层目录时,下一级目录地址。
当结构用于第三层目录时,第31位不为0。
(2)字段第31位为0
第一层,第二层的这一位都不为0。
当结构用于第三层目录时,表示该字段指向一个数据项IMAGE_RESOURCE_DATA_ENTRY。
注意:由低31位组成的地址是基于资源起始地址的。
WindowsPE 第七章 资源表的更多相关文章
- SQL笔记-第七章,表连接
SQL中使用JOIN 关键字来使用表连接.表连接有多种不同的类型,被主流数据库系统支持的有交叉连接(CROSS JOIN).内连接(INNER JOIN).外连接(OUTTER JOIN),另外在有的 ...
- 第七章 资源在Windows编程中的应用 P157 7-8
资源在基于SDK的程序设计中的应用实验 一.实验目的 1.掌握各种资源的应用及资源应用的程序设计方法. 二.实验内容及步骤 实验任务 1.熟悉菜单资源的创建过程: 2.熟悉位图资源的创建: 3.熟 ...
- 【原创】构建高性能ASP.NET站点 第七章 如何解决内存的问题(前中篇)—托管资源优化—监测CLR性能
原文:[原创]构建高性能ASP.NET站点 第七章 如何解决内存的问题(前中篇)-托管资源优化-监测CLR性能 构建高性能ASP.NET站点 第七章 如何解决内存的问题(前中篇)—托管资源优化—监测C ...
- 第三百七十四节,Django+Xadmin打造上线标准的在线教育平台—创建课程app,在models.py文件生成4张表,课程表、课程章节表、课程视频表、课程资源表
第三百七十四节,Django+Xadmin打造上线标准的在线教育平台—创建课程app,在models.py文件生成4张表,课程表.课程章节表.课程视频表.课程资源表 创建名称为app_courses的 ...
- 2017.2.28 activiti实战--第七章--Spring容器集成应用实例(五)普通表单
学习资料:<Activiti实战> 第七章 Spring容器集成应用实例(五)普通表单 第六章中介绍了动态表单.外置表单.这里讲解第三种表单:普通表单. 普通表单的特点: 把表单内容写在 ...
- apue第七章学习总结
apue第七章学习总结 1.main函数 程序是如何执行有关的c程序的? C程序总是从main函数开始执行.main函数的原型是 int main(int argc,char *argv[]); 其中 ...
- 第七章——DMVs和DMFs(3)——用DMV和DMF监控TempDB
原文:第七章--DMVs和DMFs(3)--用DMV和DMF监控TempDB 前言: 我们都知道TempDB是SQLServer的系统数据库,且SQLServer的日常运作严重依赖这个库.因此,监控T ...
- Linux内核分析——第七章 链接
第七章——链接 1.链接是将各种代码和数据部分收集起来并组合成为一个单一文件的过程,这个文件可被加载到存储器并执行. 2.链接可以执行于编译时,加载时,运行时. 7.1编译器驱动程序 1.大多数编译系 ...
- 【黑金原创教程】【TimeQuest】【第七章】供源时钟与其他
声明:本文为黑金动力社区(http://www.heijin.org)原创教程,如需转载请注明出处,谢谢! 黑金动力社区2013年原创教程连载计划: http://www.cnblogs.com/al ...
随机推荐
- 如何在 C# 中使用 const,readonly,static
平时在开发时经常会用到 const,readonly,static 关键字,可以肯定这些关键词是完全不同的概念,但有时候他们在用法上很相似以至于在场景中不知道选择哪一个,这篇文章我们就来讨论 C# 中 ...
- 2020年12月-第02阶段-前端基础-CSS Day03
CSS Day03 盒子模型(CSS重点) css学习三大重点: css 盒子模型 . 浮动 . 定位 主题思路: 理解: 1.能说出盒子模型有那四部分组成 2.能说出内边距的作用以及对盒子的影响 3 ...
- WebRTC 音视频同步原理与实现
所有的基于网络传输的音视频采集播放系统都会存在音视频同步的问题,作为现代互联网实时音视频通信系统的代表,WebRTC 也不例外.本文将对音视频同步的原理以及 WebRTC 的实现做深入分析. 时间戳 ...
- 性能追击:万字长文30+图揭秘8大主流服务器程序线程模型 | Node.js,Apache,Nginx,Netty,Redis,Tomcat,MySQL,Zuul
本文为<高性能网络编程游记>的第六篇"性能追击:万字长文30+图揭秘8大主流服务器程序线程模型". 最近拍的照片比较少,不知道配什么图好,于是自己画了一个,凑合着用,让 ...
- WPF 基础 - Binding 的源与路径
1. 源与路径 把控件作为 binding 源与 binding 标记拓展: 控制 Binding 的方向及数据更新: Binding 的路径 Path: 没有路径的 Binding: 为 Bindi ...
- Azure AD, Endpoint Manger(Intune), SharePoint access token 的获取
本章全是干货,干货,干货,重要的事情说三遍. 最近在研究Azure, Cloud相关的东西,项目中用的是Graph API(这个在下一章会相信介绍),可能是Graph API推出的时间比较晚,部分AP ...
- uniCloud的简单使用 增删改查
新建一个uni-app 项目 启动云开发 选择想要的云服务 在次之前先完成uniCloud 的实名认证 https://unicloud.dcloud.net.cn 有在Web控制台创建过云服务空间就 ...
- Python3中变量作用域nonlocal的总结
最近,在工作中踩到了一个关于Python3中nonlocal语句指定的变量作用域的坑.今天趁周六休息总结记录一下. 众所周知,Python中最常见的作用域定义如下: 但是,为了更加方便地在闭包函数 ...
- POJ_1458 Common Subsequence 【LCS】
一.题目 Common Subsequence 二.分析 比较基础的求最长升序子序列. $DP[i][j]$表示的是字符串$S1[1...i]$与$S2[1...j]$的最长公共子序列长度. 状态转移 ...
- [换根DP]luogu P3647 [APIO2014]连珠线
题面 https://www.luogu.com.cn/problem/P3647 不重复地取树中相邻的两条边,每次得分为两条边权和,问最大得分 分析 容易想到状态 f[i][0/1] 分别表示 i ...