PE文件之资源表

PE文件之资源表

资源(光标、图标、菜单等)一般写在资源脚本文件中,通过RC编译器进行编译供可执行程序使用。在资源文件中,字符串都以Unicode的形式存储。

在PE文件格式中,这些资源的二进制格式统一放在一个单独的节区中:.rsrc。

如何找到一个程序的资源呢?我们可以通过PE文件可选头中的数据目录的第三项来定位程序资源:

在获取资源块地址的时候,注意不要使用查找".rsrc"节起始地址的方法,虽然在一般情况下资源总是在".rsrc"节中,但这并不是必然的。

得到了资源块的RVA和大小之后,我们就来解析这些字节,看看它们的组织形式。

资源的组织方式

上图很直观地展现了资源的组织方式,三种类型的结构加上资源数据组成了资源块。

资源目录头IMAGE_RESOURCE_DIRECTORY

写过资源脚本文件的都知道,我们可以使用资源名称(字符串)或者资源ID来命名一个资源:

所以IMAGE_RESOURCE_DIRECTORY的最后两项的总和,才是IMAGE_RESOURCE_DIRECTORY下面IMAGE_RESOURCE_DIRECTORY_ENTRY结构的数量。

资源目录项IMAGE_RESOURCE_DIRECTORY_ENTRY

Name1字段

这个字段用于定义资源目录项的名称或者ID,在不同级别的目录中,有着不同的含义:

  1. 一级目录:表示资源的类型
  2. 二级目录:表示资源的名称
  3. 三级目录:表示资源的代码页编号

对于一级目录,该字段作为资源类型的来使用,当资源类型以ID来表示的时候(最高位是0),并且ID的数值在1到16之间,那么这种类型是系统定义的类型,如果ID数值大于16,这是用户自定义的类型:

当字段作为ID使用的时候,是可以放入一个双字的,如果使用字符串定义的时候,一个双字是不够的,这就需要将两种

情况分别对待,区分的方法是使用字段的最高位(位31)。当位31是0的时候,表示字段的值作为ID使用;而位31为1的时候,字段的低位作为指针使用,但由于资源名称字符串是使用UNICODE来编码的,所以这个指针并不直接指向字符串,而是指向一个IMAGE_RESOURCE_DIR_STRING_U结构,这个结构包含UNICODE字符串的长度和字符串本身,其定义如下:

OffsetToData字段

这个字段是一个指针,在不同的级别中也有不同的含义:

  1. 在一二级目录中:当它的最高位(位31)为1时,低位数据指向下一层目录块的起始地址,也就是一个IMAGE_RESOURCE_DIRECTORY结构
  2. 在三级目录中:当字段的位31为0时,指针指向的是用来描述资源数据块情况的IMAGE_RESOURCE_DATA_ENTRY指针

注意,上面两个字段如果表示的是地址,那么这个地址是相对于资源块开始的地方的偏移地址(RESOURCES数据目录项中指定的RVA)。

资源数据项IMAGE_RESOURCE_DATA_ENTRY

结构中的OffsetToData字段的值是指向资源数据的指针,奇怪的是,这个指针却是一个RVA值,而不是以资源块的起始地址为基址的,这是读者需要特别注意的地方。

结构中的第3个字段是CodePage,这个字段的名称有些奇怪,因为当前资源的代码页已经在第3层目录中指明了,在这里再定义一次有重复之嫌,在实际的应用中,这个字段好像未被使用,因为随便找一个PE文件看看就会发现这里的值总是为0。

通过工具解析资源

这里推荐使用Resource Hacker来查看一个程序的资源,该工具还可以编辑程序中的资源:

相关推荐
Pure_White_Sword20 天前
bugku-reverse题目-NoString
网络安全·ctf·reverse·逆向工程
阿昭L1 个月前
PE文件之导入表(一):导入函数调用机制、导入表基本结构
逆向工程·pe文件
Pure_White_Sword1 个月前
bugku-reverse题目-游戏过关
游戏·网络安全·ctf·reverse·逆向工程
阿昭L1 个月前
C++异常处理机制反汇编(三):32位下的异常结构分析
c++·windows·逆向工程
明洞日记1 个月前
【软考每日一练030】软件维护:逆向工程与再工程的区别与联系
c++·软件工程·软考·逆向工程
阿昭L1 个月前
C++异常处理机制反汇编(二):32位下基本类型异常分析
c++·逆向工程
羑悻的小杀马特1 个月前
逆向之刃出鞘!Ghidra 全栈部署 + 实战破译手册(2026 硬核版)
反编译·逆向工程
Pure_White_Sword2 个月前
bugku-reverse题目-树木的小秘密
网络安全·ctf·reverse·逆向工程
阿昭L2 个月前
继承和多继承反汇编
逆向工程·c++反汇编