【EXE PE】.rsrc 节与 resource table

原文地址http://www.mouseos.com/windows/PE_image5.html

PE 文件所有使用的 resource table 非常复杂,一个典型的 windows GUI 应用程序普遍都使用到了 7 个左右的资源。

1. windows 中的资源

WinUser.h 文件里定义了 windows 中所使用的全部资源:

/*
 * Predefined Resource Types
 */
#define RT_CURSOR           MAKEINTRESOURCE(1)
#define RT_BITMAP           MAKEINTRESOURCE(2)
#define RT_ICON             MAKEINTRESOURCE(3)
#define RT_MENU             MAKEINTRESOURCE(4)
#define RT_DIALOG           MAKEINTRESOURCE(5)
#define RT_STRING           MAKEINTRESOURCE(6)
#define RT_FONTDIR          MAKEINTRESOURCE(7)
#define RT_FONT             MAKEINTRESOURCE(8)
#define RT_ACCELERATOR      MAKEINTRESOURCE(9)
#define RT_RCDATA           MAKEINTRESOURCE(10)
#define RT_MESSAGETABLE     MAKEINTRESOURCE(11)

#define DIFFERENCE     11
#define RT_GROUP_CURSOR MAKEINTRESOURCE((ULONG_PTR)(RT_CURSOR) + DIFFERENCE)
#define RT_GROUP_ICON   MAKEINTRESOURCE((ULONG_PTR)(RT_ICON) + DIFFERENCE)
#define RT_VERSION      MAKEINTRESOURCE(16)
#define RT_DLGINCLUDE   MAKEINTRESOURCE(17)
#if(WINVER >= 0x0400)
#define RT_PLUGPLAY     MAKEINTRESOURCE(19)
#define RT_VXD          MAKEINTRESOURCE(20)
#define RT_ANICURSOR    MAKEINTRESOURCE(21)
#define RT_ANIICON      MAKEINTRESOURCE(22)
#endif /* WINVER >= 0x0400 */
#define RT_HTML         MAKEINTRESOURCE(23)
#ifdef RC_INVOKED
#define RT_MANIFEST                        24
#define CREATEPROCESS_MANIFEST_RESOURCE_ID  1
#define ISOLATIONAWARE_MANIFEST_RESOURCE_ID 2
#define ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID 3
#define MINIMUM_RESERVED_MANIFEST_RESOURCE_ID 1   /* inclusive */
#define MAXIMUM_RESERVED_MANIFEST_RESOURCE_ID 16  /* inclusive */
#else  /* RC_INVOKED */
#define RT_MANIFEST                        MAKEINTRESOURCE(24)
#define CREATEPROCESS_MANIFEST_RESOURCE_ID MAKEINTRESOURCE( 1)
#define ISOLATIONAWARE_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(2)
#define ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(3)
#define MINIMUM_RESERVED_MANIFEST_RESOURCE_ID MAKEINTRESOURCE( 1 /*inclusive*/)
#define MAXIMUM_RESERVED_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(16 /*inclusive*/)

在 MSDN 上面有一篇文关于 resource types 的介绍:http://msdn.microsoft.com/en-us/library/ms648009(VS.85).aspx

 

2. .rsrc 节

.rsrc 节装载整个 resouce table 结构和资源的数据,下面是 helloworld.exe 中的 .rsrc 节的信息

.rsrc 节
VirtualSize
0x0000E71C
VirtualAddress
0x00019000
SizeOfRawData
0x0000E800
PointerToRawData
0x00006C00
PointerToRelocations
0
PointerToLinenumbers
0
NumberOfRelocations
0
NumberOfLinenumbers
0
Characteristics
0x40000040

.rsrc 被加载在 0x00419000(ImageBase + VirtualAddress)上,真实的大小为 0xE71C,这是一个很庞大的数据段,它在 image 文件的位置是 0x0006C00,占用文件的 0xE800 空间

 

3. resource table

下面是 helloworld.exe 中所使用的 resource table 信息,它是一个 IMAGE_DATA_DIRECTORY 结构

resource table
VirtualAddress
0x00019000
size
0xE71C

可以看出,resource table 就在 .rsrc 节里,它们的 size 都是一样的。

这个 resouce table 共有 0xE71C bytse,这是一个恐怖的表格,占用大量的空间,所以这个 resource table 是一棵茂密的大树。

下面继续探索整个 resource table 的结构。

 

4. resource table 的整体结构

整个 resource table 由 4 个结构组成:

  • IMAGE_RESOURCE_DIRECTORY 结构
  • IMAGE_RESOURCE_DIRECTORY_ENTRY 结构
  • IMAGE_RESOURCE_DIRECTORY_STRING 结构,或者说是:IMAGE_RESOURCE_DIR_STRING_U 结构
  • IMAGE_RESOURCE_DATA_ENTRY 结构

整个 resource 结构是一个树型结构,只有一个 root(根)节点,然后长出许多的树枝,最后是叶子。

根部和每个树技是一个节点,这个节点由 IMAGE_RESOURCE_DIRECTORY 结构和 IMAGE_RESOURCE_DIRECTORY_ENTRY 结构组成

IMGE_RESOURCE_DIRECTORY_STRINGIMAGE_RESOURCE_DIR_STRING_U)结构和 IMAGE_RESOURCE_DATA_ENTERY 都是整个 资源树 末端的 叶子

它的结构图类似下面:

5. 节点的构成

前面说到资源树的节点由 IMAGE_RESOURCE_DIRECTORYIMAGE_RESOURCE_DIRECTORY_ENTRY 构成,它们是怎样组成一个节点的呢?

  • 由 Directory(IMAGE_RESOURCE_DIRECTORY) 指出有多少个 Entry (IMAGE_RESOURCE_DIRECTORY_ENTRY)
  • 然后每个 Entry 再伸延出一个 Directory 或者指出最终的 Data(数据)

事实上 Directory 和 Entry 虽然是两个结构,但它们是一个整体,不存在单独出现的情况


5.1 Driectory(目录)

WinNT.h 文件里定义了这个 Directory 结构:

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, MajorVersion 以及 MinorVersion 一直为 0 不使用

NumberOfNamedEntries 代表一个数量,以 "Name" 作为子树的个数。

NumberOfIdEntries 代表一个数量,以 "ID" 作为子树的个数。

而 Directory 引出的 Entry 数量是 NumberOfNamedEntries 与 NumberOfIdEntries 之和,即:NumberOfNamedEntries + NumberOfIdEntries 等于 Entry 的数量

  • Entry 是紧接着 Driectory 存放的。

5.2 Entry(表项)

WinNT.h 文件中,Entry 结构的定义为:

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;

这个结构看上去很复杂,实际上它成员只有 两个 DWORD 成员 ,共 8 bytes,如下:

 typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {
    DWORD Name;
    DWORD OffsetToData;
} IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;

使用这个看上去很复杂方式定义,它想表达一个策略:

  • Name 的高最位(Bit31)为 1 时: Name[30:0](低 31 位)是一个 offset 指向 IMAGE_RESOURCE_DIR_STRING_U 结构。
    Bit310 时,Name 表示一个 ID 值。
  • OffsetToData 的最高位(Bit31)为 1 时:OffsetToData[30:0](低 31 位)是一个 offset 指向下一个 Directory 结构。
    Bit310 时,OffsetToData 仍然是一个 Offset 值,它指向一个 IMAGE_RESOURCE_DATA_ENTRY 结构。

Entry 的职责是给出下一个 DirectoryData,从资源树的角度来看,Entry 要么给出下一个节点,要么给出叶子


5.2.1 给出下一个 Directory

此时 Name 是一个 ID 值(即:Bit31 为 0),同时 OffsetToData 指向下一个 Directory 的位置(即:Bit31 为 1)

OffsetToData 提供的这个 Offset 值是基于 resource table 的,例如下面的一个 Entry 是这样的:

// entry[0]
00419010  03 00 00 00     // Name = 0x03 ====> ID = 3 (ICON)
00419014  48 00 00 80     // OffsetToData = 0x80000048

上例上所示,Name 此时表示一个 ID 值(Bit31 为 0),而 OffsetToDataBit31 为 1,此时它提供一个 offset 指向下一个 Directory 的位置。

在这个例子里,resource table 的位址是在 0x00419000,那么下一个 Directory 就在 0x00419048resource table + OffsetToData)位置上。


5.2.2 给出 Data 数据

OffsetToData 的 Bit31 为 0,它指向一个 IMAGE_RESOURCE_DATA_ENTRY 结构,从树的解度来看,它给出一个叶子。下面是个例子:

// Entry[0]
00419180  09 04 00 00                    // ID = 0x409
00419184  98 03 00 00                    // ****** IMAGE_RESOURCE_DATA_ENTRY: 0x00000398

此时 OffsetToData 提供的是 Data (IMAGE_RESOURCE_DATA_ENTRY) 位置,同样这个 Offset 也是基于 resource table 的地址。

那么这个 Data 数据区域在:0x00419398


5.3 节点图

Entry 紧跟着 Directory 存放,它们构成一个节点,Directory 的 NumberOfIdEntries 给出 Entry 的个数 7,那么紧跟着的 Entry 就有 7 个。 每个 Entry 是一个 IMAGE_RESOURCE_DIRECTORY_ENTRY 结构。

那么该节点大小就有 1IMAGE_RESOURCE_DIRECTORY 结构和 7IMAGE_RESOURCE_DIRECTORY_ENTRY 结构,每个节点的大小可能是不相同。


5.4 root 节点

root(根)节点是 resource table 的第 1 个节点,root 就在 resource table 位置上。

helloworld.exe 为例,它的 resource table 在 0x00419000(ImageBase + VirtualAddress),下面是它的 root 节点:

// Driectory: (root)
00419000  00 00 00 00
00419004  00 00 00 00
00419008  00 00
0041900A  00 00
0041900C  00 00            // NumberOfNameEntries
0041900E  07 00            // NumberOfIdEntries

// entry[0]
00419010  03 00 00 00     // ID = 3 (ICON)
00419014  48 00 00 80     // OffsetToData = 0x80000048

// entry[1]
00419018  04 00 00 00     // ID = 4 (MENU)
0041901C  D8 00 00 80     // OffsetToData = 0x800000D8

// entry[2]
00419020  05 00 00 00     // ID = 5 (DIALOG)
00419024  F0 00 00 80     // OffsetToData = 0x800000F0

// entry[3]
00419028  06 00 00 00     // ID = 6 (STRING)
0041902C  08 01 00 80     // OffsetToData = 0x80000180


// entry[4]
00419030  09 00 00 00     // ID = 9 (ACCELERATOR)
00419034  20 01 00 80     // OffsetToData = 0x80000120

// entry[5]
00419038  0E 00 00 00     // ID = 0E (GROUP_ICON)
0041903C  38 01 00 80     // OffsetToData = 0x80000138


// entry[6]
00419040  18 00 00 00     // ID = 0x18 (MAINFEST)
00419044  58 01 00 80     // OffsetToData = 0x80000158

它有 7 个 Entry,每个 Entry 代表一个资源,由 Name(ID 值) 域得到,每个资源伸延出各自的资源树,这些 ID 值代表一个资源,也就是前面的 WinUser.h 文件定义的常量值,每个 Entry 的 OffsetToData 值都指向各自的下一个 Directory

 

6. 叶子(Data/String)

资源树最终都要落在未端的叶子上,叶子两类结构表示:DataString,它们由 Entry 引出。


6.1 Data Entry

Data 数据区域Data Entry 指出,这个 Data Entry 结构在 WinNT.h 定义为:

typedef struct _IMAGE_RESOURCE_DATA_ENTRY {
    DWORD   OffsetToData;
    DWORD   Size;
    DWORD   CodePage;
    DWORD   Reserved;
} IMAGE_RESOURCE_DATA_ENTRY, *PIMAGE_RESOURCE_DATA_ENTRY;

Data Entry 的职责是指出最终的 resource table 中的数据,由 OffsetToData 指出,这个 OffsetToData 是个 RVA 值,基于 ImageBase。数据区的大小由 Size 得出

在资源树的未端 Resource Directory Entry 给出 Data Entry,再由 Data Entry 得到 Data 区域。


6.2 Resource Directory String

Resource Directory 的名字包含在 String 结构里,这个结构在 WinNT.h 定义为:

typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING {
    WORD    Length;
    CHAR    NameString[ 1 ];
} IMAGE_RESOURCE_DIRECTORY_STRING, *PIMAGE_RESOURCE_DIRECTORY_STRING;


typedef struct _IMAGE_RESOURCE_DIR_STRING_U {
    WORD    Length;
    WCHAR   NameString[ 1 ];
} IMAGE_RESOURCE_DIR_STRING_U, *PIMAGE_RESOURCE_DIR_STRING_U;

Directory String 里包含的是 Unicode 码,因此,Directory Entry 始终指向 IMAGE_RESOURCE_DIR_STRING_U 结构, 它和 IMAGE_RESOURCE_DIRECTORY_STRING 的区别是一个是 ASCII,一个是 Unicode

NameString 是不定长的,用来表示 Directory 的名字,如:ICON 资源 Directory


6.3 两种分枝

Data 与 String 不可能共同在同一个 Directory 树中:

  • Data 树由 Directory Entry 中 OffsetToData 指出
  • String 树由 Directory Entry 中 Name 指出

这种分枝的策略是区别是:

  • 一个用 ID 来标识资源
  • 一个用 String 名字来标资源

6.3.1 Data 树

root 节点的 Entry 中,当 OffsetToData 的 Bit31 为 1 时,由该 Entry 伸出的是 Data 树,此时由该 Entry 指向树分枝中的所有 Entry 的 Name 都是 ID 值,

再回过头来看一看 hellworld.exeroot 节点 :

// Driectory: (root)
00419000  00 00 00 00
00419004  00 00 00 00
00419008  00 00
0041900A  00 00
0041900C  00 00            // NumberOfNameEntries
0041900E  07 00            // NumberOfIdEntries

// entry[0]
00419010  03 00 00 00     // ID = 3 (ICON)
00419014  48 00 00 80     // OffsetToData = 0x80000048

// entry[1]
00419018  04 00 00 00     // ID = 4 (MENU)
0041901C  D8 00 00 80     // OffsetToData = 0x800000D8

// entry[2]
00419020  05 00 00 00     // ID = 5 (DIALOG)
00419024  F0 00 00 80     // OffsetToData = 0x800000F0

// entry[3]
00419028  06 00 00 00     // ID = 6 (STRING)
0041902C  08 01 00 80     // OffsetToData = 0x80000180


// entry[4]
00419030  09 00 00 00     // ID = 9 (ACCELERATOR)
00419034  20 01 00 80     // OffsetToData = 0x80000120

// entry[5]
00419038  0E 00 00 00     // ID = 0E (GROUP_ICON)
0041903C  38 01 00 80     // OffsetToData = 0x80000138


// entry[6]
00419040  18 00 00 00     // ID = 0x18 (MAINFEST)
00419044  58 01 00 80     // OffsetToData = 0x80000158

上面的 root 节点长出 7 个分枝,每个分枝都由 Entry 指出,7 个分枝的 Entry 的 Name 都是 ID 值

因此 helloworld.exe 资源树中所有分枝都是 Data 树,它不存在 String 树


6.3.2 String 树

当 root 节点的 Entry 中 Name 域 Bit31 为 1 时,Name 指向 String,这个 String 标识整个分枝,由这个 Entry 长出来的树枝都是 String 树

事实上,对一个 windows 典型资源几乎都是用 ID 来标识,而不是用 String 来标识。

 

7. 追踪 helloworld.exe 的资源树中的一条分枝

现在我们从 root 节点开始到末端的叶子,来看一看 helloworld.exe 的一条分枝情况:

(1)root 节点

// Driectory: (root)
00419000  00 00 00 00
00419004  00 00 00 00
00419008  00 00
0041900A  00 00
0041900C  00 00            // NumberOfNameEntries
0041900E  07 00            // NumberOfIdEntries

// entry[0]
00419010  03 00 00 00     // ID = 3 (ICON)
00419014  48 00 00 80     // OffsetToData = 0x80000048

它的第 1 个分枝是 Data 分枝,ID = 3 它是一个 ICON 资源分枝树,下一个节点在 0x00419048 (0x00419000 + 0x00000048)

(2)下一个节点


// Directory
00419048  00 00 00 00
0041904C  00 00 00 00
00419050  00 00
00419052  00 00
00419054  00 00            // NumberOfNameEntries
00419056  10 00            // NumberOfIdEntries


// Entry[0]
00419058  01 00 00 00      // ID = 01
0041905C  70 01 00 80      // OffsetToData = 0x80000170

00419060  02 00 00 00      // ID = 02
00419064  88 01 00 80      // OffsetToData = 0x80000188

00419068  03 00 00 00      // ID = 03
0041906C  A0 01 00 80      // OffsetToData = 0x800001A0

00419070  04 00 00 00
00419074  B8 01 00 80

00419078  05 00 00 00
0041907C  D0 01 00 80

00419080  06 00 00 00
00419084  E8 01 00 80

00419088  07 00 00 00
0041908C  00 02 00 80

00419090  08 00 00 00
00419094  18 02 00 80

00419098  09 00 00 00
0041909C  30 02 00 80

004190A0  0A 00 00 00
004190A4  48 02 00 80

004190A8  0B 00 00 00
004190AC  60 02 00 80

004190B0  0C 00 00 00
004190B4  78 02 00 80

004190B8  0D 00 00 00
004190BC  90 02 00 80

004190C0  0E 00 00 00
004190C4  A8 02 00 80

004190C8  0F 00 00 00
004190CC  C0 02 00 80

// Entry[15]
004190D0  10 00 00 00
004190D4  D8 02 00 80

在这个节点中,有 16 个 Entry,也一个庞大的分枝。我们只看第 1 个分枝情况:

  • ID = 01
  • OffsetToData = 0x80000170

说明再下一个节点在 0x00419170 位置上,它的 ID 值为 1,这些 Entry 的排列顺序是以 ID 值升序排列的。在子树里的 ID 值并没什么意义,只有在 root 节点里的 ID 里才代表着资源类型。

(3)再下一个节点

// Directory
00419170  00 00 00 00
00419174  00 00 00 00
00419178  00 00
0041917A  00 00
0041917C  00 00
0041917E  01 00

// Entry[0]
00419180  09 04 00 00                    // ID = 0x409
00419184  98 03 00 00                    // ****** IMAGE_RESOURCE_DATA_ENTRY: 0x00000398

这个节点里只有 1 个 Entry,这个 Entry 的 OffsetToData 值是 0x00000398,那么它指向 Data Entry 而不是下一个节点。它个 Data Entry 位置在 0x00419398

(4)它的 Data Entry

// IMAGE_RESOURCE_DATA_ENTRY
00419398  A8 98 01 00           // OffsetToData = 0x000198A8
0041939C  E8 02 00 00           // Size = 0x02E8
004193A0  00 00 00 00           // Codepage
004193AC  00 00 00 00           // Reserved

最终的 Data 数据区在 0x000198A8,注意这个值是基于 ImageBase 的,而不是基于 resource table,因此 Data 数据区在映像的 0x004198A8ImageBase + OffsetToData

(5)Data 数据区

下面摘取一部分数据:

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

004198A0                          28 00 00 00 20 00 00 00         .(... ...
004198B0  40 00 00 00 01 00 04 00 00 00 00 00 00 00 00 00  @...............
004198C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
004198D0  00 00 00 00 00 00 80 00 00 80 00 00 00 80 80 00  ......€..€...€€.
004198E0  80 00 00 00 80 00 80 00 80 80 00 00 80 80 80 00  €...€.€.€€..€€€.
004198F0  C0 C0 C0 00 00 00 FF 00 00 FF 00 00 00 FF FF 00  ààà...?..?...??.
00419900  FF 00 00 00 FF 00 FF 00 FF FF 00 00 FF FF FF 00  ?...?.?.??..???.
00419910  AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA  aaaaaaaaaaaaaaaa
00419920  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00419930  77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 70  wwwwwwwwwwwwwwwp
00419940  78 88 88 88 88 88 88 88 88 88 88 88 88 88 88 70  x??????????????p
00419950  78 7F FF FF FF FF FF FF FF FF FF FF FF FF F8 70  x.?????????????p
00419960  78 7F FF FF FF FF FF FF FF FF FF FF FF FF F8 70  x.?????????????p
00419970  78 7F FF FF FF FF FF FF FF FF FF FF FF FF F8 70  x.?????????????p
00419980  78 7F FF FF FF FF FF FF FF FF FF FF FF FF F8 70  x.?????????????p
00419990  78 7F FF FF FF FF FF FF FF FF FF FF FF FF F8 70  x.?????????????p
004199A0  78 7F FF FF FF FF FF FF FF FF FF FF FF FF F8 70  x.?????????????p
004199B0  78 7F FF FF FF FF FF FF FF FF FF FF FF FF F8 70  x.?????????????p
004199C0  78 7F FF FF FF FF FF FF FF FF FF FF FF FF F8 70  x.?????????????p
004199D0  78 7F FF FF FF FF FF FF FF FF FF FF FF FF F8 70  x.?????????????p
004199E0  78 7F FF FF FF FF FF FF FF FF FF FF FF FF F8 70  x.?????????????p
004199F0  78 7F FF FF FF FF FF FF FF FF FF FF FF FF F8 70  x.?????????????p
00419A00  78 7F FF FF FF FF FF FF FF FF FF FF FF FF F8 70  x.?????????????p
00419A10  78 7F FF FF FF FF FF FF FF FF FF FF FF FF F8 70  x.?????????????p
00419A20  78 7F FF FF FF FF FF FF FF FF FF FF FF FF F8 70  x.?????????????p
00419A30  78 7F FF FF FF FF FF FF FF FF FF FF FF FF F8 70  x.?????????????p
00419A40  78 7F FF FF FF FF FF FF FF FF FF FF FF FF F8 70  x.?????????????p
00419A50  78 7F FF FF FF FF FF FF FF FF FF FF FF FF F8 70  x.?????????????p
00419A60  78 7F FF FF FF FF FF FF FF FF FF FF FF FF F8 70  x.?????????????p
00419A70  78 77 77 77 77 77 77 77 77 77 77 77 77 77 78 70  xwwwwwwwwwwwwwxp
00419A80  78 88 88 88 88 88 88 88 88 88 88 88 88 88 88 70  x??????????????p
00419A90  78 44 44 44 44 44 44 44 44 44 40 00 00 00 00 70  xDDDDDDDDD@....p
00419AA0  78 44 44 44 44 44 44 44 44 44 48 80 88 08 80 70  xDDDDDDDDDH€?.€p
00419AB0  78 44 44 44 44 44 44 44 44 44 48 80 88 08 80 70  xDDDDDDDDDH€?.€p
00419AC0  78 44 44 44 44 44 44 44 44 44 44 44 44 44 44 70  xDDDDDDDDDDDDDDp
00419AD0  78 88 88 88 88 88 88 88 88 88 88 88 88 88 88 70  x??????????????p
00419AE0  77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 70  wwwwwwwwwwwwwwwp
00419AF0  AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA  aaaaaaaaaaaaaaaa

这个数据组成特定的数据格式。:)

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
在 Windows PE 文件中,资源文件以资源段的形式存储,通常被称为“资源”。资源包含了多个资源,每个资源都有一个独一无二的标识符,可以用来在程序中访问这些资源。 下面介绍一种解析 Windows PE 资源文件的方法: 1. 使用 PE 解析器打开 Windows PE 文件,找到资源的偏移量和大小。通常资源的名称是`.rsrc`,其在表中的偏移量可以通过解析 PE文件中的表结构体得到。 2. 根据偏移量和大小,将资源PE 文件中读取出来,并解析为资源目录表。资源目录表包含了资源的分类信息,比如图标、位图、字符串、对话框等等。 3. 在资源目录表中查找你需要的资源类型,比如图标或位图。资源类型用一个标识符来表示,比如`RT_ICON`和`RT_BITMAP`。 4. 在对应的资源类型目录中查找需要的资源。每个资源类型目录包含了多个资源项,每个资源项都有一个独一无二的标识符和偏移量。可以通过标识符来查找需要的资源项,然后通过偏移量读取出相应的资源数据。 5. 对读取的资源数据进行解析,并进行相应的处理。比如,如果读取的是一个图标文件,可以将其转换为位图或者其他格式,然后在程序中使用。 需要注意的是,不同的资源类型有不同的解析方法,需要根据具体的情况进行处理。此外,也可以使用一些工具来帮助解析 Windows PE 资源文件,比如 Resource Hacker 和 PE Explorer 等工具。这些工具可以提供更方便的资源管理和解析功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值