0x00 前言

前面了解了PE文件的输入和输出,今天来看看另一个重要的结构——资源。资源结构是很典型的树形结构,层层查找,最终找到资源位置。

0x01 资源结构介绍

Windows程序的各种界面成为资源,包括加速键,位图,光标,对话框,图标,菜单,串标,工具栏,版本信息等等,在所有的PE文件中资源结构是最为复杂的。下图为资源的树形结构图:

通常来讲,资源的目录为三层结构。最上面的为根目录,它存储了资源的类型同时存储指向下一级的指针,二级目录包含资源id(至于啥事资源ID后面会讲到)和指向第三级的指针,三级目录存储资源代码和指向真正资源的指针。这里最要理解的是这三级目录用的都是同一结构。这个结构包含两个子结构——资源目录结构(IMAGE_RESOURCE_DIRECTORY)和资源目录入口地址结构(IMAGE_RESOURCE_DIRECTOTY_RNTRY)。理解了这两个结构各自的作用就能明白整个资源结构。下面分别从这两个结构讲起。

0x02 资源目录结构(IMAGE_RESOURCE_DIRECTORY)

资源目录结构是由数据目录表的第三个子项(Resource Table)所指向的(想想数据目标表有多重要把,基本上后面所讲都要从它开始)。该结构包含16个字节,共6个字段,下面的该结构的定义:

// 【资源表位于数据目录表的第三项,共动态分配字节, 其中结构体中的成员指出的RVA偏移量都是对于此结构体的地址作为基地址】

typedef struct _IMAGE_RESOURCE_DIRECTORY

{

DWORD Characteristics; //理论上为资源的属性,不过事实上总是0

DWORD TimeDateStamp; //资源的产生时刻

WORD MajorVersion; //理论上为资源的版本,不过事实上总是0

WORD MinorVersion

WORD NumberOfNamedEntries;      //以名称(字符串)命名的入口数量

WORD NumberOfIdEntries; //以ID(整型数字)命名的入口数量

} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;

这六个字段真正有用的是最后两个字段:

WORD NumberOfNamedEntries:标明入口数量,所谓入口数量,资源目录入口地址结构(IMAGE_RESOURCE_DIRECTOTY_RNTRY)结构的数量,这个结构都是紧紧跟着资源目录结构(IMAGE_RESOURCE_DIRECTORY),不过它标记数量的方式是用字符串。

WORD NumberOfIdEntries:这个字段本质上和前一个字段一模一样,不过它是用id来标明数量。注意:最后统计资源入口地址结构数量的时候是这两个的相加的和。

0x03 资源目录入口地址结构(IMAGE_RESOURCE_DIRECTORY_ENTRY)

资源目录入口地址结构虽然很简单,但是却非常重要。它不仅包含了指向下一级目录的地址,好包含了指向真正资源的数据入口地址。

typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY

{

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

DWORD  OffsetToData;    //资源数据偏移地址或者子目录偏移地址

}_IMAGE_RESOURCE_DIRECTORY_ENTRY, *P_IMAGE_RESOURCE_DIRECTORY_ENTRY;

这两个字段都是极为重要的,下面将详细讲解这两个字段的含义:

Name:大小为双字,该字段定义了目录项的名称或者ID。当用于第一级目录时,它表示的是资源的类型,用于第二级目录时表示资源的名称,用于第三级目录时,用于表示资源的代码页号编号。当最高位是0的时候,表示字段的值作为ID来使用(前面说了该字段可以表示资源的类型,资源的类型就是用ID来区分的,不同资源类型ID不一样)。当最高位是1时,地位字段表示一个指针,这个指针就是指向了资源的名称的UNICODE编码(前面也讲到该字段可以表示目录的名称)。下表统计了系统已经定义的资源类型。表一

类型ID值

资源类型

类型ID值

资源类型

01h

光标(Cursor)

08h

字体(Font)

02h

位图(Bitmap)

09h

加速键(Accelerator)

03h

图标(Icon)

0ah

未格式资源(Unformatted)

04h

菜单(Menu)

Obh

消息表(MessageTable)

05h

对话框(Dialog)

0ch

光标组(Group Cursor)

06h

字符串(Stiring)

0eh

图标组(Group Icon)

07h

字体目录(Font Directory)

10h

版本信息(Version Information)

OffsetToData:双字结构,是一个指针。当最高为为1时,低位指向的是下一级目录的起始地址,当最高为是0时,指向的是真正的数据资源的目录入口结构(IMAGE_RESOURCR_DIRCTORY_DATA)。

重要说明:当字段Name和Offset作为指针时,该指针是从资源区块开始的地方算起的偏移量,不是RVA,即根目录的起始位置偏移量(就是从第一级资源目录结构(IMAGE_RESOURCE_DIRECTORY)的起始地址算起)

0x03 实例讲解资源的结构

工具:hexworkshop,lordPE,目标PE文件:pediy.exe。

下面我将一级级逐级追击资源:

1)根目录

首先找到数据目录表的第三项,它指向了第一级目录即根目录地址。它在PE文件头偏移88h处。地址为:0ch+88h=148h。直接跳转至148h处,如下图:

标明RVA=4000h,这里本来如果要跳转至根目录是要进行地址转化,但是这里是特殊情况,由于这个PE文件磁盘分页和内存分页的值相等,故RVA=Offset,缘由可看下图:

我们现在直接跳转至4000h处,该处即为根目录起始地址,如下图:

现在我们按照顺序以西读出这个第一个结构IMAGE_RESOURCE_DIRECTORY的六个字段的值。记在下表中:表二

Charateristics

TimeStamp

MajorVersion

MinnorVersion

NumberOfEntris

NumberOfIdEntries

0000 0000

0000 0000

0000

0000

0000

0003

由最后两个字段可知紧随IMAGE_RESOURCE_DIRECTORY的共有三个IMAGE_RESOURCE_DIRECTORY_ENTRY结构,如下图:

依次将数据读出登记在下表:表三

第一个Dir_entry结构

第二个Dir_entry结构

第三个Dir_entry结构

偏移地址

4010h

4018h

4020h

字段Name

0000 0003h

0000 0004h

0000 000Eh

字段OffsetToData

8000 0028h

8000 0040h

8000 0058h

由于有三个下级目录,我们就以第二个IMAGE_RESOURCE_DIRECTORY_ENTRY结构来分析下一级资源结构。

2)二级目录

根目录的IMAGE_RESOURCE_DIRECTORY_ENTRY结构的字段Name=0000 0004h,最高为0,所以它表示资源类型,低位值为0004h,这个资源的ID号,查询表一可得这是个菜单(Mune资源)。再来看字段OffsetToData=8000 0040h,明显最高为是1,所以这个指针指向的是下一级资源目录。其低31位值是40h,这个就是下级目录距离根目录的偏移地址,地址为:

4000h+40h=4040h。我们跳往地址4040h处,得到下图:

依次读出IMAGE_RESOURCE_DIRECTORY结构的六个字段统计在下表:

Charateristics

TimeStamp

MajorVersion

MinnorVersion

NumberOfEntris

NumberOfIdEntries

0000 0000

0000 0000

0000

0000

0000

0000 0001

根据最后一个字段可知,紧跟这结构IMAGE_RESOURCE_DIRECTORY的结构IMAGE_RESOURCE_DIRECTORY_ENTRY只有一个,如下图:

我们依次读出两个字段的值:Name=8000 00E8h OffsetToData=8000 0088h。由于字段Name的最高位是1,所以低位字段表示指向结构IMAGE_RESOURCE_DATA_STRING_U结构,这个结构存储了资源名的unicod值,我们跳往40E8h处,如下图:

由上图可知资源名是PEDIY。第二个字段OffsetToData的最高位是1,低位表示指向下级目录的地址,我们跳往4088h。

3)第三级目录

跳转至地址4088h,我们来到了第三级目录,如下图:

依次读出六个字段统计在下表:

Charateristics

TimeStamp

MajorVersion

MinnorVersion

NumberOfEntris

NumberOfIdEntries

0000 0000

0000 0000

0000 0000

0000 0000

0000 0000

0000 0001

根据最后一个字段可知紧随结构IMAGE_RESOURCE_DIRECTORY只有一个IMAGE_RESOURCE_DIRECTORY_ENTRY结构,如下图:

字段Name=0000 0409h,字段OffsetToData=0000 00C8h。在第三级目录中Name字段表示代码页编号,这里是409表示英语,OffsetToData最高位是0,低31位作为指针指向资源数据入口结构(IMAGE_RESOURCE_DATA_ENTRY)。该结构的定义如下:

IMAGE_RESOURCE_DATA_ENTRY STRUCT

{

OffsetToData  DWORD //资源数据的RVA

Size         DWORD//资源数据的长度

CodePage    DWORD//代码页,一般为0

Reserved     DWORD//保留字段

};IMAGE_RESOURCE_DATA_ENTRY ENDS

我们直接跳转至40c8h处,如下图:

逐个读出各个字段的值统计在下表中:

OffsetToData

Size

CodePage

Reserved

0000 4400

0000 005a

0000 0000

0000 0000

至此,我们总算找到了资源的真正地址即在字段OffsetToData=4400h,大小为字段Size=5ah。

如下图就是资源:

PE文件格式详解(八)的更多相关文章

  1. PE文件格式详解(七)

    PE文件格式详解(七)   Ox00 前言 前面好几篇在讲输入表,今天要讲的是输出表和地址的是地址重定位.有了前面的基础,其实对于怎么找输出表地址重定位的表已经非常熟悉了.   0x01 输出表结构 ...

  2. PE文件格式详解,第一讲,DOS头文件格式

    PE文件格式详解,第一讲,DOS头文件格式 今天讲解PE文件格式的DOS头文件格式 首先我们要理解,什么是文件格式,我们常说的EXE可执行程序,就是一个文件格式,那么我们要了解它里面到底存了什么内容 ...

  3. PE文件格式详解,第二讲,NT头文件格式,以及文件头格式

    PE文件格式详解,第二讲,NT头文件格式,以及文件头格式 作者:IBinary出处:http://www.cnblogs.com/iBinary/版权所有,欢迎保留原文链接进行转载:) PS:本篇博客 ...

  4. PE文件格式详解,第三讲,可选头文件格式,以及节表

    PE文件格式详解,第三讲,可选头文件格式,以及节表 作者:IBinary出处:http://www.cnblogs.com/iBinary/版权所有,欢迎保留原文链接进行转载:) 一丶可选头结构以及作 ...

  5. PE文件格式详解(六)

    0x00 前言 前面两篇讲到了输出表的内容以及涉及如何在hexWorkShop中找到输出表及输入DLL,感觉有几个地方还是没有理解好,比如由数据目录表DataDirectory[16]找到输出表表后以 ...

  6. PE文件格式详解(下)

    作者:MSDN译者:李马 预定义段 一个Windows NT的应用程序典型地拥有9个预定义段,它们是.text..bss..rdata..data..rsrc..edata..idata..pdata ...

  7. PE文件格式详解(上)

    作者:MSDN 译者:李马 摘要 Windows NT 3.1引入了一种名为PE文件格式的新可执行文件格式.PE文件格式的规范包含在了MSDN的CD中(Specs and Strategy, Spec ...

  8. PE 文件格式详解

    PE文件 是微软 Win32 环境下可执行文件的标准格式. 所谓的可执行文件并不仅仅是常见的 EXE 文件,DLL,SYS,VXD 等文件也都属于 PE 格式. |-------> DOS_MZ ...

  9. PE文件格式详解(一)

    PE文件格式介绍(一) 0x00 前言 PE文件是portable File Format(可移植文件)的简写,我们比较熟悉的DLL和exe文件都是PE文件.了解PE文件格式有助于加深对操作系统的理解 ...

随机推荐

  1. 权限系统设计(0):权限系统设计基本概念改需-MAC/RBAC引子

    此篇主要对权限系统设计所涉的一些专业术语重点梳理.从我们windows的文件系统 自主访问控制 到基于角色访问控制. 权限设计基本术语 对后面会用到的词汇做一个简要说明 什么是权限(许可) 权限(Pr ...

  2. iOS -NSOperation——高级的并发处理方法

    NSOperation是Objective-C中一种高级的并发处理方法,现在对GCD的封装;功能比GCD更强大! 两个概念      操作:      操作队列:      NSOperation多线 ...

  3. 指定web默认首页,导致访问路径的问题

    今天写了一个登陆页面,登陆成功跳转时,url中的路径不对 这是目录结构 |-web |---login |-----login.jsp |---success |-----success.jsp 这是 ...

  4. JS 姓氏,区域,消息组成的随机内容定时随机展示

    var surname_g = "\u8D75\u94B1\u5B59\u674E\u5468\u5434\u90D1\u738B\u51AF\u9648\u891A\u536B\u848B ...

  5. @codefoces - 1313E@ Concatenation with intersection

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定两个长度为 n 的字符串 a, b 与一个长度为 m 的字符 ...

  6. 这一次搞懂Spring事务是如何传播的

    文章目录 前言 正文 事务切面的调用过程 事务的传播性概念 实例分析 总结 前言 上一篇分析了事务注解的解析过程,本质上是将事务封装为切面加入到AOP的执行链中,因此会调用到MethodIncepto ...

  7. Ios App破解之路二 JJ斗地主

    前提条件: 越狱手机里, 安装了 <JJ斗地主> 使用砸壳工具clutch 下载地址: https://github.com/KJCracks/Clutch/releases dzq:~/ ...

  8. 04.开发REST 接口

    使用Django开发REST 接口 我们以在Django框架中使用的图书英雄案例来写一套支持图书数据增删改查的REST API接口,来理解REST API的开发. 在此案例中,前后端均发送JSON格式 ...

  9. FastJson对实体类和Json还有JSONObject相互转换

    1. 实体类或集合转JSON串 String besnString = JSONObject.toJSONString(实体类); 2.JSON串转JSONObject JSONObject json ...

  10. Centos 7使用systemctl补全服务名称

    使用jsw将程序打包成服务后,发现不能使用service + 服务名前几个字母 + tab 快捷键补全服务名,但是tab键可以补全文件夹名,翻阅了各个文档后,最终还是找到了问题所在. 本人安装的是Ce ...