原文出自:www.fishc.com

最近一直在安排第一届鱼C 学习班的事情,忙活了好一阵子,真是对不住大家,还大家久等了,这里要跟大家说声不好意思 ^_^

今天我们来谈谈资源部分,资源部分可以说是 PE 文件所有结构中,最复杂的一部分,也最让人揪心。很多朋友都想通过自己动手修改一些游戏的资源、工具的界面、或者一些软件的图标等,都知道要改资源部分。但纯粹一进去就像走进了迷宫……出不来……

虽然说是迷雾重重,但是本节的学习确意义非凡,例如我们可以对游戏进行汉化!怎么样?刺激吧?给力吧?我们可以自己汉化我们喜欢的**游戏哦!

小甲鱼PE详解之资源(PE详解11)

我们知道,Windows 将程序的各种界面定义为资源,包括加速键(Accelerator)、位图(Bitmap)、光标(Cursor)、对话框(Dialog Box)、图标(Icon)、菜单(Menu)、串表(String
Table)、工具栏(Toolbar)和版本信息(Version Information)等。

为了吸引大家的兴趣和目光,咱先来做个学前试验,然后再憧憬一下我们将来学习的内容有啥意义!好,小甲鱼先来演示一下如何用工具来修改资源实现汉化、改图
标等,接着我们进一步从原理上来解剖 PE文件如何对资源进行存放和索引。最后,在
PE系列章节讲解完毕后,小甲鱼和大家将所有学到的知识结合在一起,我们自己打造属于我们的个性 PE工具。

试验对象:360zip(实在找不到几个鸟文软件,我们就随便改改,不做汉化了,做“英化”^_^)
所需工具:Resource Hacker,eXeScope(附件提供下载
小小演示:请看视频哈 @_@

资源结构

资源是PE 文件中非常重要的部分,几乎所有的PE 文件中都包含着资源,与导入表和导出表相比,资源的组织方式要复杂很多,其实我们只要看下图就知道俺所言不虚。

我们知道我们的资源有很多种类型,每种类型的资源中可能存在多个资源项,这些资源项用不同的ID 或者名称来区分。但是要将这么多种类型的不同ID
的资源有序地组织起来是一件非常痛苦的事情,因此,我们采取类似于磁盘目录结构的方式保存。

从图中我们可以看到,PE 文件中的资源是按照 资源类型 -> 资源ID -> 资源代码页 的3层树型目录结构来组织资源的,通过层层索引才能够进入相应的子目录找到正确的资源。

资源目录结构

数据目录表中的 IMAGE_DIRECTORY_ENTRY_RESOURCE 条目(第三项)包含资源的 RVA 和大小。资源目录结构中的每一个节点都是由 IMAGE_RESOURCE_DIRECTORY
结构和紧跟其后的数个IMAGE_RESOURCE_DIRECTORY_ENTRY
结构组成的。(是不是有点像我们之前提到的文件目录?文件夹每个都长得一样,一个嵌套另一个,这样子可以实现将非常复杂的数据细化切分,小泽玛利亚、苍井空、吉泽明步、松岛枫……)

我们再来看这张图:

认识了这层关系后,我们来看下 IMAGE_RESOURCE_DIRECTORY
这个结构,该结构长度为 16 字节,共有 6 个字段,定义如下:

IMAGE_RESOURCE_DIRECTORY STRUCT

Characteristics       
DWORD      ?   ;理论上为资源的属性,不过事实上总是0
TimeDateStamp     
DWORD      ?   ;资源的产生时刻
MajorVersion         
WORD        ?   ;理论上为资源的版本,不过事实上总是0
MinorVersion         
WORD        ?
NumberOfNamedEntries 
WORD     ?   ;以名称(字符串)命名的入口数量
NumberOfIdEntries        
WORD     ?   ;以ID(整型数字)命名的入口数量

IMAGE_RESOURCE_DIRECTORY ENDS

其实在这里边我们唯一要注意的就是 NameberOfNamedEntries 和 NumberOfIdEntries,它们说明了本目录中目录项的数量。两者加起来就是本目录中的目录项总和。也就是后边跟着的IMAGE_RESOURCE_DIRECTORY_ENTRY
数目。


资源目录入口的结构(
IMAGE_RESOURCE_DIRECTORY_ENTRY

IMAGE_RESOURCE_DIRECTORY_ENTRY
紧跟在资源目录结构后,此结构长度为 8 个字节,包含 2 个字段。该结构定义如下:

IMAGE_RESOURCE_DIRECTORY_ENTRY STRUCT

Name                 
DWORD    ?   ;目录项的名称字符串指针或ID
OffsetToData       
DWORD    ?   ;目录项指针

IMAGE_RESOURCE_DIRECTORY_ENTRY ENDS

Name 字段完全是个百变精灵,改字段定义的是目录项的名称或ID。当结构用于第一层目录时,定义的是资源类型;当结构定义于第二层目录时,定义的是资源的名称;当结构用于第三层目录时,定义的是代码页编号。

注意:当最高位为 0  的时候,表示字段的值作为 ID 使用;而最高位为 1 的时候,字段的低位作为指针使用(资源名称字符串是使用
UNICODE编码),但是这个指针不是直接指向字符串哦,而是指向一个 IMAGE_RESOURCE_DIR_STRING_U 结构的。
该结构定义如下:
IMAGE_RESOURCE_DIR_STRING_U STRUCT

Length            
DWORD       ?   ; 字符串的长度
NameString     
DWORD       ?   ; UNICODE字符串,由于字符串是不定长的。由Length 制定长度

IMAGE_RESOURCE_DIR_STRING_U
ENDS

OffsetOfData 字段是一个指针,当最高位为 1 时,低位数据指向下一层目录块的其实地址;当最高位为 0 时,指针指向 IMAGE_RESOURCE_DATA_ENTRY 结构。

注意:将 Name 和 OffsetToData 用做指针时需要注意,该指针是从资源区块开始的地方算起的偏移量(即根目录的起始位置的偏移量),不是我们习惯的 RVA 哦。

最后,在上图中我们看到,在第一层的时候,IMAGE_RESOURCE_DIRECTORY_ENTRY的Name
字段作为资源类型使用。

具体类型匹配见下表:

资源数据入口


过三层 IAMGE_RESOURCE_DIRECTORY_ENTRY
(一般是3层,偶尔更年期少一些。第一层资源类型,第二层资源名,第三层是资源的 Language),第三层目录结构中的 OffsetOfData
指向 IMAGE_RESOURCE_DATA_ENTRY 结构。该结构描述了资源数据的位置和大小,定义如下:

IMAGE_RESOURCE_DATA_ENTRY STRUCT

OffsetToData
    DWORD     ?    ; 资源数据的RVA
Size
                 DWORD     ?    ; 资源数据的长度
CodePage
         DWORD     ?    ; 代码页, 一般为0
Reserved
          DWORD     ?    ; 保留字段

IMAGE_RESOURCE_DATA_ENTRY
ENDS

千山万水,此处的 IMAGE_RESOURCE_DATA_ENTRY
结构就是真正的资源数据了。结构中的OffsetOfData 指向资源数据的指针,其为 RVA 值。

资源结构实例分析(具体过程将在视频中演示,这里不再罗嗦^_^)

工具:PEinfo.exe, UltraEdit

小甲鱼PE详解之资源(PE详解11)的更多相关文章

  1. 小甲鱼PE详解之输入表(导出表)详解(PE详解09)

    小甲鱼PE详解之输出表(导出表)详解(PE详解09) 当PE 文件被执行的时候,Windows 加载器将文件装入内存并将导入表(Export Table) 登记的动态链接库(一般是DLL 格式)文件一 ...

  2. 小甲鱼PE详解之基址重定位详解(PE详解10)

    今天有一个朋友发短消息问我说“老师,为什么PE的格式要讲的这么这么细,这可不是一般的系哦”.其实之所以将PE结构放在解密系列继基础篇之后讲并且尽可能细致的讲,不是因为小甲鱼没事找事做,主要原因是因为P ...

  3. 小甲鱼PE详解之区块描述、对齐值以及RVA详解(PE详解06)

    各种区块的描述: 很多朋友喜欢听小甲鱼的PE详解,因为他们觉得课堂上老师讲解的都是略略带过,绕得大家云里雾里~刚好小甲鱼文采也没课堂上的教授讲的那么好,只能以比较通俗的话语来给大家描述~ 通常,区块中 ...

  4. 小甲鱼PE详解之IMAGE_OPTIONAL_HEADER32 结构定义即各个属性的作用(PE详解03)

    咱接着往下讲解IMAGE_OPTIONAL_HEADER32 结构定义即各个属性的作用! (视频教程:http://fishc.com/a/shipin/jiemixilie/) 接着我们来谈谈 IM ...

  5. 小甲鱼PE详解之输入表(导入表)详解(PE详解07)

    捷径并不是把弯路改直了,而是帮你把岔道堵上! 走得弯路跟成长的速度是成正比的!不要害怕走上弯路,弯路会让你懂得更多,最终还是会在终点交汇! 岔路会将你引入万劫不复的深渊,并越走越深…… 在开始讲解输入 ...

  6. 小甲鱼PE详解之区块表(节表)和区块(节)(PE详解04)

    到此为止,小甲鱼和大家已经学了许多关于 DOS header 和 PE header 的知识.接下来就该轮到SectionTable (区块表,也成节表).(视频教程:http://fishc.com ...

  7. 小甲鱼PE详解之IMAGE_NT_HEADERS结构定义即各个属性的作用(PE详解02)

    PE Header 是PE相关结构NT映像头(IMAGE_NT_HEADER)的简称,里边包含着许多PE装载器用到的重要字段.下边小甲鱼将为大家详细讲解哈~ (视频教程:http://fishc.co ...

  8. 小甲鱼PE详解之输入表(导入表)详解2(PE详解08)

    在此之前,我们已经对这个输入表进行了一些实践和理解,这有助于大家对这个概念更进一步的加深认识.小甲鱼觉得,越是复杂的问题我们应该越是去动手操作它,认识它,这样才容易熟悉它! 在上一节课我们像小鹿一样的 ...

  9. 小甲鱼PE详解之区块表(节表)和区块(节)续(PE详解05)

    这一讲我们结合实例来谈谈区块表的定义以及各个属性的含义. 首先,我们先用之前学过的一点知识在二进制文件中手动翻找区块表,这样做的好处是可以使你很快的对PE结构牢记于心.学来的东西就是能用的东西,不能用 ...

随机推荐

  1. 十五、MySQL DELETE 语句

    MySQL DELETE 语句 你可以使用 SQL 的 DELETE FROM 命令来删除 MySQL 数据表中的记录. 你可以在 mysql> 命令提示符或 PHP 脚本中执行该命令. 语法 ...

  2. 关于poi的坑

    背景故事 今天遇上一个坑,关于poi公式计算结果出错的问题,自己打断点debug了半天,虽然没彻底搞清楚为啥不行,但所幸找到了解决办法. 干货 下面不废话,直接贴干货,原先的公式处理代码如下: fin ...

  3. ES6 的解构赋值前每次都创建一个对象吗?会加重 GC 的负担吗?

    本文来源于知乎上的一个提问. 为了程序的易读性,我们会使用 ES6 的解构赋值: function f({a,b}){} f({a:1,b:2}); 这个例子的函数调用中,会真的产生一个对象吗?如果会 ...

  4. 微信小程序 onLoad 函数

    小程序注册完成后,加载页面,触发onLoad方法. 页面载入后触发onShow方法,显示页面. 首次显示页面,会触发onReady方法,渲染页面元素和样式,一个页面只会调用一次. 当小程序后台运行或跳 ...

  5. PHP 作用域

  6. 学习Spring框架系列(一):通过Demo阐述IoC和DI的优势所在

    Spring框架最核心东西便是大名鼎鼎的IoC容器,主要通过DI技术实现.下面我通过Demo的演变过程,对比学习耦合性代码,以及解耦和的过程,并深入理解面向接口编程的真正内涵. 这个例子包括如下几个类 ...

  7. Flask初学者:g对象,hook钩子函数

    Flask的g对象 作用:g可以可以看作是单词global的缩写,使用“from flask import g”导入,g对象的作用是保存一些在一次请求中多个地方的都需要用到的数据,这些数据可能在用到的 ...

  8. 最短路径:HDU2006-一个人的旅行(多个起点,多个终点)

    题目: 一个人的旅行 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  9. C# datagridview列绑定类中类的属性

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://www.cnblogs.com/linghaoxinpian/p/5906374. ...

  10. “帮你APP”团队冲刺6

    1.整个项目预期的任务量 (任务量 = 所有工作的预期时间)和 目前已经花的时间 (所有记录的 ‘已经花费的时间’),还剩余的时间(所有工作的 ‘剩余时间’) : 所有工作的预期时间:88h 目前已经 ...