吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4833|回复: 19
收起左侧

[原创] PE 文件解析5-数据目录[资源表]

[复制链接]
appsion 发表于 2020-11-3 09:27
本帖最后由 appsion 于 2020-11-3 12:33 编辑

PE 文件解析5-数据目录[资源表]
新手学习PE文件解析记录,  持续更新. 部分参考来源于网络, 无法逐一标注, 如果侵权,请及时联系. 如有错误请指正,误喷.

上文连接: https://www.52pojie.cn/thread-1295307-1-1.html

9.png


资源树分为三层:
        第一层                资源类型的数量
        第二层                资源的数量
        第三层                资源数据的数量

示意图:
10.png



结构体: IMAGE_RESOURCE_DIRECTORY
说明: 资源目录表
头文件: winnt.h
帮助文档: 仅存在于头文件, 没有帮助文档
参考文档: https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#resource-directory-table
11.png

[Asm] 纯文本查看 复制代码
typedef struct _IMAGE_RESOURCE_DIRECTORY 
{
    DWORD   Characteristics;
    DWORD   TimeDateStamp;
    WORD    MajorVersion;
    WORD    MinorVersion;
    WORD    NumberOfNamedEntries;
    WORD    NumberOfIdEntries;
//  IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];
} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;

参数说明: 仅供参考, 详细说明请参考原文.
    Characteristics
        资源描述
    TimeDateStamp
        时间日期戳
    MajorVersion
        资源主要版本
    MinorVersion
        资源次要版本
    NumberOfNamedEntries
        资源用字符串命名的数量.
    NumberOfIdEntries
        资源用ID命名的数量.



结构体: IMAGE_RESOURCE_DIRECTORY_ENTRY
说明: 资源目录项
头文件: winnt.h
帮助文档: 仅存在于头文件, 没有帮助文档
参考文档: https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#resource-directory-entries
12.png
[Asm] 纯文本查看 复制代码
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;

参数说明: 仅供参考, 详细说明请参考原文.
DUMMYUNIONNAME
    第一层: 资源类型标识, 第二层: 资源标识, 第三层: 国家地区语言标识
    DUMMYUNIONNAME.DUMMYSTRUCTNAME.NameOffset
        DUMMYUNIONNAME 的低31位值.
            当 NameIsString == 0 时表示资源目录类型. 也就是 DUMMYUNIONNAME.Id.
            当 NameIsString == 1 时表示资源目录名称的偏移. IMAGE_RESOURCE_DIR_STRING_U 结构. 相对于资源目录表(IMAGE_RESOURCE_DIRECTORY)的起始位置 + NameOffset 的偏移.
    DUMMYUNIONNAME.DUMMYSTRUCTNAME.NameIsString
        DUMMYUNIONNAME 的最高位值.用于判断 NameOffset 为名称还是资源类型.
    DUMMYUNIONNAME.Name
        DUMMYUNIONNAME 的值.
    DUMMYUNIONNAME.Id
        资源类型的ID.

DUMMYUNIONNAME2
    第一层: 资源偏移, 第二层: 资源数据偏移, 第三层: 资源数据的偏移
    DUMMYUNIONNAME2.OffsetToData
        DUMMYUNIONNAME2 的值
    DUMMYUNIONNAME2.DUMMYSTRUCTNAME2.OffsetToDirectory
        DUMMYUNIONNAME2 值的低31位值.
            当 DataIsDirectory == 0 时, 表示资源数据的偏移, IMAGE_RESOURCE_DATA_ENTRY 结构. 
            当 DataIsDirectory == 1 时, 表示资源目录的偏移, IMAGE_RESOURCE_DIRECTORY 结构. 相对资源目录表(IMAGE_RESOURCE_DIRECTORY)的起始位置 + OffsetToDirectory偏移.
    DUMMYUNIONNAME2.DUMMYSTRUCTNAME2.DataIsDirectory
        DUMMYUNIONNAME2 值的最高位值


LCID, 区域设置标识符
参考地址:
https://docs.microsoft.com/zh-cn/openspecs/windows_protocols/ms-lcid/a9eac961-e77d-41a6-90a5-ce1a8b0cdb9c#Appendix_A_8
https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/70feba9f-294e-491e-b6eb-56532684c37f

资源类型
原文地址: https://docs.microsoft.com/en-us/windows/win32/menurc/resource-types
RT_CURSOR1光标资源
RT_BITMAP2位图资源
RT_ICON3图标资源
RT_MENU4菜单资源
RT_DIALOG5对话框资源
RT_STRING6字符串表条目。
RT_FONTDIR7字体目录资源。
RT_FONT8字体资源
RT_ACCELERATOR9加速器表。
RT_RCDATA10应用程序定义的资源(原始数据)
RT_MESSAGETABLE11消息表条目。
RT_GROUP_CURSOR12与硬件无关的游标资源。
RT_GROUP_ICON14与硬件无关的图标资源。
RT_VERSION16版本资源。
RT_DLGINCLUDE17允许资源编辑工具将字符串与.rc文件关联。 通常,字符串是提供符号名称的头文件的名称。 资源编译器解析该字符串,但忽略该值。 例如,1 DLGINCLUDE“ MyFile.h”
RT_PLUGPLAY19即插即用资源。
RT_VXD20VXD。
RT_ANICURSOR21动画的光标。
RT_ANIICON22动画的图标。
RT_HTML23HTML资源。
RT_MANIFEST24并排组装清单。


结构体: IMAGE_RESOURCE_DATA_ENTRY
说明: 资源数据
头文件: winnt.h
帮助文档: 仅存在于头文件, 没有帮助文档
参考文档: https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#resource-data-entry
13.png
[Asm] 纯文本查看 复制代码
typedef struct _IMAGE_RESOURCE_DATA_ENTRY 
{
    DWORD   OffsetToData;
    DWORD   Size;
    DWORD   CodePage;
    DWORD   Reserved;
} IMAGE_RESOURCE_DATA_ENTRY, *PIMAGE_RESOURCE_DATA_ENTRY;

参数说明: 仅供参考, 详细说明请参考原文.
    OffsetToData
        资源数据的RVA
    Size
        资源数据大小
    CodePage
        代码页
    Reserved
        保留


结构体: IMAGE_RESOURCE_DIR_STRING_U
说明: 资源目录项名称
头文件: winnt.h
帮助文档: 仅存在于头文件, 没有帮助文档
参考文档:https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#resource-directory-string
14.png
[Asm] 纯文本查看 复制代码
typedef struct _IMAGE_RESOURCE_DIR_STRING_U 
{
    WORD    Length;
    WCHAR   NameString[ 1 ];
} IMAGE_RESOURCE_DIR_STRING_U, *PIMAGE_RESOURCE_DIR_STRING_U;

参数说明: 仅供参考, 详细说明请参考原文.
    Length
        字符串资源目录项名称的长度.
    NameString[1]
        资源目录项名称. 该字符串为Unicode字符串.


5.1 获取资源目录树
  注: 资源分为二种, 字符串命名的资源和ID命名的资源

示意图
            17.png

注释说明:
// 资源总数量
IMAGE_RESOURCE_DIRECTORY.NumberOfIdEntries + IMAGE_RESOURCE_DIRECTORY.NumberOfNamedEntries

// 节表
SectionHead

// 节表数量
SectionCount

// 资源表RVA
m_DataDirRVA

// RVA 转 FOA,  详情说明参见前面章节.
RVAToRaw(SectionHead, SectionCount, m_DataDirRVA)

// 文件指针
m_DataBuff

// 资源FOA
DWORD ResourceFOA = (DWORD)m_DataBuff + RVAToRaw(SectionHead, SectionCount, m_DataDirRVA);

// 获取资源树
GetResourceEntry(ResourceFOA, 0, 0);

[Asm] 纯文本查看 复制代码
// 参数说明:
//    ResourceFOA, 资源FOA
//    ResourceFOAOffset, 资源偏移
//    depth, 资源树深度
void GetResourceEntry(DWORD ResourceFOA, DWORD ResourceFOAOffset, int depth)
{
        // 获取节表
        int SectionCount = 0;
        IMAGE_SECTION_HEADER *SectionHead = GetSectionHead(m_DataBuff, SectionCount);

        // 资源树
        IMAGE_RESOURCE_DIRECTORY *ResourceDir = (IMAGE_RESOURCE_DIRECTORY*)(ResourceFOA + ResourceFOAOffset);

        // 遍历资源
        for (int i = 0; i < ResourceDir->NumberOfIdEntries + ResourceDir->NumberOfNamedEntries; i++)
        {
                // 获取资源
                IMAGE_RESOURCE_DIRECTORY_ENTRY ResourceEntry = ((IMAGE_RESOURCE_DIRECTORY_ENTRY*)((DWORD)ResourceDir + sizeof(IMAGE_RESOURCE_DIRECTORY)))[i];

                // 获取资源名称
                CString RCTypeName;
                int RCTypeId = 0;
                GetResourceName(ResourceFOA, &ResourceEntry, depth, RCTypeName, RCTypeId);



                // 最高位为1时, 低32位为 IMAGE_RESOURCE_DIRECTORY 结构的偏移
                // 最高位为0时, 低32位为 IMAGE_RESOURCE_DATA_ENTRY 结构的偏移
                if (ResourceEntry.DataIsDirectory)
                {
                        GetResourceEntry(ResourceFOA, ResourceEntry.OffsetToDirectory, depth + 1);
                }
                else
                {
                        // LCID
                        m_ResourceData->ResourceLCID = ResourceEntry.Id;

                        // 资源数据
                        IMAGE_RESOURCE_DATA_ENTRY * ResourceData = (IMAGE_RESOURCE_DATA_ENTRY *)(ResourceFOA + ResourceEntry.OffsetToDirectory);
                        m_ResourceData->ResourceDataRVA = ResourceData->OffsetToData;
                        m_ResourceData->ResourceDataFOA = RVAToRaw(SectionHead, SectionCount, ResourceData->OffsetToData);
                        m_ResourceData->ResourceDataSize = ResourceData->Size;
                }
        }
}


[Asm] 纯文本查看 复制代码
// 资源类型
void GetResourceName(DWORD ResourceFOA, IMAGE_RESOURCE_DIRECTORY_ENTRY *ResourceEntry, int depth, CString &RCTypeName, int &RCTypeId)
{
        CString Tempstr;
        if (ResourceEntry->NameIsString)
        {
                IMAGE_RESOURCE_DIR_STRING_U *ResourceDirName = (IMAGE_RESOURCE_DIR_STRING_U*)(ResourceFOA + ResourceEntry->NameOffset);
                WCHAR *Buff = new WCHAR[ResourceDirName->Length + 1];
                memset(Buff, 0, (ResourceDirName->Length + 1) * 2);
                wcsncpy_s(Buff, ResourceDirName->Length + 1, ResourceDirName->NameString, ResourceDirName->Length);
                Tempstr = (PWCHAR)Buff;
                delete Buff;
        }
        else
        {
                switch (depth)
                {
                case 0:
                                switch (ResourceEntry->Id)
                                {
                                case 1: Tempstr = "光标"; break;
                                case 2: Tempstr = "位图"; break;
                                case 3: Tempstr = "图标"; break;
                                case 4: Tempstr = "菜单"; break;
                                case 5: Tempstr = "对话框"; break;
                                case 6: Tempstr = "字符串"; break;
                                case 7: Tempstr = "字体目录"; break;
                                case 8: Tempstr = "字体"; break;
                                case 9: Tempstr = "加速键"; break;
                                case 10: Tempstr = "RC数据"; break;
                                case 11: Tempstr = "消息表"; break;
                                case 12: Tempstr = "光标组"; break;
                                case 14: Tempstr = "图标组"; break;
                                case 16: Tempstr = "版本信息"; break;
                                case 23: Tempstr = "HTML"; break;
                                case 24: Tempstr = "清单"; break;
                                default: Tempstr.Format("%d", ResourceEntry->Id); break;
                                }
                        break;

                case 1: Tempstr.Format("%d", ResourceEntry->Id); break;

                case 2:

                        Tempstr.Format("区域语言标识: 0x%04X", ResourceEntry->Id);
                        break;

                default:
                        Tempstr = "未知";
                        break;
                }
        }
        
        RCTypeName = Tempstr;
}

免费评分

参与人数 5吾爱币 +8 热心值 +5 收起 理由
zsl3399 + 1 + 1 我很赞同!
Alpaca0115 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
Hmily + 5 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
huangxw + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
fengbolee + 1 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

头像被屏蔽
a522wds 发表于 2022-3-18 23:36
提示: 作者被禁止或删除 内容自动屏蔽
碎步流年 发表于 2020-11-3 14:20
teachqwe 发表于 2020-11-3 17:20
虽然看不懂,但能知道楼主博学,楼主真牛,老湿这波操作稳了。
zouyibuzjc 发表于 2020-11-3 19:10
谢谢您的鼓励,挺不错
Insist_2020 发表于 2020-11-3 19:32
感谢分享!!!!!!!!
huangxw 发表于 2020-11-3 20:24
谢谢分享,最近正好有用
归来仍是英雄 发表于 2020-11-4 14:01
挺不错,虽然看不懂,但博主牛逼
lifz888 发表于 2020-11-4 15:36
非常好的学习资料,支持分享
kssak 发表于 2020-11-4 20:18
感谢楼主分享,学习了
碎步流年 发表于 2020-11-4 21:19
感谢,向大佬学习
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 14:32

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表