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

news2024/10/6 23:16:19

在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.coloradmin.cn/o/989323.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

“链主品牌”竞争战略四大误区

在《财富》500 强企业名单中&#xff0c;2008 年中国企业仅有 37 家&#xff0c;而 2019 年攀升至 119 家&#xff0c;与美国仅相差两家。2008 年&#xff0c;中国关注的问题是其在世界 500 强榜单上的企业数量太少。而如今的讨论则集中在为何中国企业规模大却实力不强。原因在…

有哪些做流程图的软件?分享一些制作方法和注意事项

流程图是一种常用的图表&#xff0c;可以用于表示各种工作流程、系统架构、决策流程等。在现代工作生活中&#xff0c;制作流程图已经成为了必备的技能之一。本文将介绍一些常用的做流程图的工具&#xff0c;并分享一些制作方法和注意事项。 做流程图的工具 1.迅捷画图&#x…

Node.js安装教程图文详解

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 下载Node.js 请下载Node.js并保存至本地&#xff0c;官方网址&#xff1a;https://nodejs.org/zh-cn/ 在此&#xff0c;选择windows系统64位的16.13.1版本进行下载。 下载…

【SLAM】Sophus库的超详细解析

在视觉SLAM中&#xff0c;李群李代数是描述位姿比较常用的一种表达形式。但是&#xff0c;在Eigen中并不提供对它的支持&#xff0c;一个较好的李群和李代数的库是Sophus库&#xff0c;它很好的支持了SO3、so3、SE3、se3。 Sophus简介 代码仓库&#xff1a;https://github.com…

laravel系列(二) Dcat admin框架开发工具使用

开发工具可以非常好的帮助我们去快速的开发CURD等操作,但也是有部分框架有些不是太便捷操作,这篇博客主要为大家介绍Dcat admin的开发工具详细使用. 如何创建页面: 在联表我们首先要去.env文件中去找连接数据库方法: APP_NAMELaravel APP_ENVlocal APP_KEYbase64:thO0lOVlzj0…

机器学习入门教学——人工智能、机器学习、深度学习

1、人工智能 人工智能相当于人类的代理人&#xff0c;我们现在所接触到的人工智能基本上都是弱AI&#xff0c;主要作用是正确解释从外部获得的数据&#xff0c;并对这些数据加以学习和利用&#xff0c;以便灵活的实现特定目标和任务。例如&#xff1a; 阿尔法狗、智能汽车简单…

苹果跨入“迷你超级周期”:iPhone15Pro占比提升75%,性价比高?

据美国投行韦德布什证券的分析师Daniel Ives最近发布的投资者报告&#xff0c;苹果公司今年推出的iPhone 15机型比例已经从往年的3&#xff1a;2调整为了3&#xff1a;1&#xff0c;这标志着苹果公司跨入了“迷你超级周期”。 分析师郭明錤曾预测&#xff0c;今年iPhone 15系列…

【深度学习】 Python 和 NumPy 系列教程(二):Python基本数据类型:3、字符串(索引、切片、运算、格式化)

目录 一、前言 二、实验环境 三、Python基本数据类型 3. 字符串&#xff08;Strings&#xff09; 1. 初始化 2. 索引 3. 切片 4. 运算 a. 拼接运算 b. 复制运算 c. 子串判断 d. 取长度 5. 格式化 a. 使用位置参数 b. 使用关键字参数 c. 使用属性访问 f-string…

在家也能轻松使用用友畅捷通T3管理财务,实现高效率远程办公!

文章目录 前言1. 用友畅捷通T3借助cpolar实现远程办公1.1 在被控端电脑上&#xff0c;点击开始菜单栏&#xff0c;打开设置——系统1.2 找到远程桌面1.3 启用远程桌面 2. 安装cpolar内网穿透2.1 注册cpolar账号2.2 下载cpolar客户端 3. 获取远程桌面公网地址3.1 登录cpolar web…

三.listview或tableviw显示

一.使用qt creator 转变类型 变形为listview或tableviw 二.导出ui文件为py文件 # from123.py 为导出 py文件 form.ui 为 qt creator创造的 ui 文件 pyuic5 -o x:\xxx\from123.py form.uifrom123.py listview # -*- coding: utf-8 -*-# Form implementation generated fro…

GDAL Python 过滤Shape Polygon中的面积小于某个阈值的小图斑

# -*- coding: utf-8 -*- # !/usr/bin/mgdal_env # Time : 2023/9/6 9:36 # Author : Hexk # 过滤矢量文件中的面积小于某个阈值的小图斑from osgeo import ogr, gdal, osr import osdef ShapeFiltratePitch(_input_path, _output_path, _area_threshold):"""过…

logback/log4j基本配置和标签详解

什么是logback logback 继承自 log4j&#xff0c;它建立在有十年工业经验的日志系统之上。它比其它所有的日志系统更快并且更小&#xff0c;包含了许多独特并且有用的特性。 logback.xml 首先直接上配置&#xff0c;我在项目过程中发现一些同时遇到需要logback文件的时候就去…

2023-9-8 求组合数(一)

题目链接&#xff1a;求组合数 I #include <iostream> #include <algorithm>using namespace std;const int mod 1e9 7;int n; const int N 2010; int c[N][N];void init() {for(int i 0; i < N; i )for(int j 0; j < i; j)if(!j) c[i][j] 1;else c[i]…

学习SpringMvc第三战-利用SpringMvc实现CRUD

前言&#xff1a; 小编讲述了参数传递&#xff0c;返回值以及页面跳转&#xff01;为我们的CRUD提供了理论基础&#xff0c;接下来小编会通过SpringMvc实现CRUD来讲述在企业开发中必须要学会的CRUD 一.前期环境搭建 1.替换pom.xml的内容 <properties><project.buil…

C# WPF 自己写的一个模拟病毒传播的程序,有可视化

原程序下载: https://download.csdn.net/download/qq_34677276/88314649 主要代码 using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks;n…

向量数据库Milvus Cloud 2.3 Attu 界面升级,用户体验更友好

全新升级的Milvus Cloud 2.3 Attu带来了全新的界面设计,为用户提供了更加友好的使用体验。作为向量数据库的专家和《向量数据库指南》的作者,我将在本文中详细讲解该版本的升级内容,并提供一些案例来加深大家对于Milvus Cloud 2.3 Attu的理解。 一、界面设计优化 1.1 界面整…

使用正则表达式总结

多行匹配 使用Pattern.DOTALL | Pattern.MULTILINE参数 Pattern.CASE_INSENSITIVE&#xff1a;不区分大小写 public static void main(String[] args) {String teststr "AA aa AASSF \n\r */ DDET AA";String regStr "(?AA)\\w\\b";extracted(testst…

LeetCode(力扣)90. 子集 IIPython

LeetCode90. 子集 II 题目链接代码 题目链接 https://leetcode.cn/problems/subsets-ii/ 代码 class Solution:def subsetsWithDup(self, nums):result []path []used [False] * len(nums)nums.sort() # 去重需要排序self.backtracking(nums, 0, used, path, result)retu…

十二、集合(5)

本章概要 for-in 和迭代器 适配器方法惯用法 本章小结 简单集合分类 for-in和迭代器 到目前为止&#xff0c;for-in 语法主要用于数组&#xff0c;但它也适用于任何 Collection 对象。实际上在使用 ArrayList 时&#xff0c;已经看到了一些使用它的示例&#xff0c;下面是它…

软件生命周期及流程【软件测试】

软件的生命周期 软件生命周期是软件开始研制到最终被废弃不用所经历的各个阶段。 瀑布型生命周期模型 规定了它们自上而下、相互衔接的固定次序&#xff0c;如同瀑布流水&#xff0c;逐级下落&#xff0c;具有顺序性和依赖性。每个阶段规定文档并需进行评审。 特点&#xff…