• PE结构学习笔记(十一)


    Chinese:

    不得不说资源的结构比较复杂。。其实就类似于文件系统,一个文件夹中嵌套着另一个文件夹,而文件则是我们需要找的资源数据。

    1、数据目录表中的IMAGE_DIRECTORY_ENTRY_RESOURCE的第三项包含资源的RVA和大小。

    2、数据目录结构中的每一个节点都是由IMAGE_RESOURCE_DIRECTORY结构和紧跟其后的数个IMAGE_RESOURCE_DIRECTORY_DIRECTORY_ENTRY结构组成的。

    3、IMAGE_RESOURCE_DIRECTORY结构

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

    4、资源目录入口结构IMAGE_RESOURCE_DIRECTORY_ENTRY

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

    [Name]

    当结构用于第一层目录时,定义的是资源类型;当结构定义于第二层目录时,定义的是资源名称;当结构用于第三层目录时,定义的是代码页编号。

    当最高位为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

    Name的ID意义如下图:


    [OffsetOfData]

    当最高位为1时,指向下一层目录块的地址;最高位为0时,指针指向IMAGE_RESOURCE_DATA_ENTRY结构

    注意:将Name和OffsetToData用作指针时,该指针是从资源区块开始的地方计算的偏移量。

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

    这个结构就是真正的资源数据了。OffsetToData就是指向资源数据的指针,RVA

    5、实例寻找练练手

    (1) 通过PEInfo获得数据目录的资源地址

    (2) 查找该地址所在区块,对应的物理地址(ROffset)为0x00206200

    (3) 用16进制编辑器打开该程序,定位到0x00206200地址,第一层就是IMAGE_RESOURCE_DIRECTORY结构,我们可以看到该结构没有以字符串命名的入口,但有4个以ID命名的入口,这说明,该结构体并不是我们要找的资源结构,还要深入。

    (4) 我们看到接下来的IMAGE_RESOURCE_DIRECTORY_ENTRY结构,发现Name=3,最高位果然是0(说明是ID),3代表的资源是图标,而指针指向的地址是0x80000030,可见最高位是1(8=1000b),所以不是指向真正的资源数据,而是下一个IMAGE_RESOURCE_DIRECTORY结构(第二层),偏移为0x30,我们加上资源目录的首地址得到0x206230。

    (5) 同理我们在该地址找到Name=1,仍然是ID,OffsetToData=0x800000A8,最高位仍然是1,所以继续指向下一个IMAGE_RESOURCE_DIRECTORY结构(第三层),偏移为0xA8,加上资源目录首地址为0x2062A8

    (6) 同理Name=0x0411,仍然是ID,OffsetToData=0x00000150,最高位是0了!这说明我们终于找到了头,也就是指向了真正的资源结构IMAGE_RESOURCE_DATA_ENTRY,地址为0x206350。

    (7) 该地址的前两个双字类型记录了资源数据的RVA和长度,OffsetToData=0x5021D0,Size=0xD3D6,我们定位到0x206200+0x1D0=0x2063D0。从这个地址开始计算0xD3D6个长度就是我们的第一个图标资源。

  • 相关阅读:
    ESP32 SDA和SCL
    ESP32的HSPI和VSPI区别
    ffmpeg生成视频封面图
    小程序读取几种不同格式json数据(小程序json解析)
    ajax
    使用Java语言,连接linux服务器,并远程执行shell 脚本
    Echarts饼图的使用
    js提取对象数组中的某一个属性
    java读取文件推送报文
    java读取本地文件内容TXT文件
  • 原文地址:https://www.cnblogs.com/maplewan/p/3236685.html
Copyright © 2020-2023  润新知