程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 對PE資源的研究

對PE資源的研究

編輯:關於C++

前言:沒什麼好說的,發現這方面的資料全是英文的,於是我一邊研究,一邊翻譯,一邊寫出自己的心得。

希望大家尊重我的勞動成果,轉貼保持完整。

資源一般使用樹來保存,通常包含3層,在NT下,最高層是類型,然後是名字,最後是語言。

一個PE文件是否包含資源文件,通常檢測塊表(Section Table)中是否含有'.rsrc',不過這個方法對有些PE文件無效。

一個類型表結構如下

——————————————————————————

| RESOURCE DIRECTORY |

——————————————————————————

| RESOURCE DATA |

——————————————————————————

資源表1(Resource File Layout)

其中的資源目錄(RESOURCE DIRECTORY)結構如下:

——————————————————————————

| RESOURCE FLAGS |

——————————————————————————

| TIME/DATE STAMP |

——————————————————————————

| MAJOR VERSION |MINOR VERSION |

——————————————————————————

| # NAME ENTRY |# ID ENTRY |

——————————————————————————

| RESOURCE DIR ENTRIES |

——————————————————————————

資源表2(Resource Table Entry)

在DELPHI中的申明

{ Resources }

PIMAGE_RESOURCE_DIRECTORY = ^IMAGE_RESOURCE_DIRECTORY;

IMAGE_RESOURCE_DIRECTORY = packed record

Characteristics : DWORD;

TimeDateStamp : DWORD;

MajorVersion : WORD;

MinorVersion : WORD;

NumberOfNamedEntries : WORD;

NumberOfIdEntries : WORD;

end

其中:

RESOURCE FLAGS

通常設置為0

TIME/DATE STAMP

資源編譯器建立此資源的時間/日期,可能為0

MAJOR/MINOR VERSION

版本信息

# NAME ENTRY

使用名字的資源條目的個數,包含一個使用名字的目錄條目的數組。

# ID ENTRY

使用ID數字的資源條目的個數,包含一個32位的整數ID號,同用名字一樣。

這個目錄緊接著會是一個不定長度的目錄條目,不管用的名字還是ID,都是用升序排列。

這個不定長度的目錄結構如下:

31 0

——————————————————————

| NAME RVA/INTEGER ID |

——————————————————————

| E | DATA ENTRY RVA/SUBDIR RVA |

——————————————————————

資源表3(Resource Directory Entry)

在DELPHI中的申明:

PIMAGE_RESOURCE_DIRECTORY_ENTRY = ^IMAGE_RESOURCE_DIRECTORY_ENTRY;

IMAGE_RESOURCE_DIRECTORY_ENTRY = packed record

Name: DWORD; // Or ID: Word (Union)

OffsetToData: DWORD;

INTEGER ID

包含一個識別資源的整數ID

如果在根目錄,這個ID表示的意義如下

資源類型

1: cursor

2: bitmap

3: icon

4: menu

5: dialog

6: string table

7: font directory

8: font

9: accelerators

10: unformatted resource data

11: message table

12: group cursor

14: group icon

16: version information

NAME RVA

名字的相對實際地址,包含一個31位的相對資源的Image Base的地址。表的形式見表4

E 一位的不可缺少的識別碼(mask 80000000h)

如果這位為0,則為Resource Data Entries,其中DATA RVA = 31位的(mask 7fffffffh) 數據條目的地址。結構見表5

如果這位為1,則表示接另一個子目錄(Subdirectory Entry)。

{ 此函數檢驗 offset 是一個字符串名還是一個目錄 }

{ IMAGE_RESOURCE_NAME_IS_STRING

= IMAGE_RESOURCE_DATA_IS_DIRECTORY

= $80000000 }

function HighBitSet(L: Longint): Boolean;

begin

Result := (L and IMAGE_RESOURCE_DATA_IS_DIRECTORY) <> 0;

end;

{ 下面兩個函數用於去掉E位剩下的值或者指針 }

{IMAGE_OFFSET_STRIP_HIGH = $7FFFFFFF;}

function StripHighBit(L: Longint): Longint;

begin

Result := L and IMAGE_OFFSET_STRIP_HIGH;

end;

function StripHighPtr(L: Longint): Pointer;

begin

Result := Pointer(L and IMAGE_OFFSET_STRIP_HIGH);

end;

每一個資源目錄名為如下格式

——————————————————————

| LENGTH | UNICODE STRING |

——————————————————————

| LENGTH | UNICODE STRING |

——————————————————————

表4(Resource Directory String Entry)

在DELPHI中的申明

PIMAGE_RESOURCE_DIR_STRING_U = ^IMAGE_RESOURCE_DIR_STRING_U;

IMAGE_RESOURCE_DIR_STRING_U = packed record

Length : WORD;

NameString : array [0..0] of WCHAR;

end;

LENGTH

就是字符串的長度

UNICODE STRING

Unicode的字符串.

資源數據表結構:

—————————————

| DATA RVA |

—————————————

| SIZE |

—————————————

| CODEPAGE |

—————————————

| RESERVED |

—————————————

表5(Resource Data Entry)

在DELPHI中的申明

PIMAGE_RESOURCE_DATA_ENTRY = ^IMAGE_RESOURCE_DATA_ENTRY;

IMAGE_RESOURCE_DATA_ENTRY = packed record

OffsetToData : DWORD;

Size : DWORD;

CodePage : DWORD;

Reserved : DWORD;

end;

DATA RVA

資源的相對實際地址,包含一個32位相對於資源Image Base的地址。

SIZE

資源的大小。

CODEPAGE

沒什麼說的,好像為譯碼方面設置的。

RESERVED

一定為0

好了,差不多資源這部分分析玩了,其它部分我還在研究:)

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved