Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #57, АВГУСТ 2005 г.

Анатомия файла

Иван Скляров

Спецвыпуск: Хакер, номер #057, стр. 057-026-7


WORD NumberOfIdEntries;

// IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];

} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;

Здесь интересны только два поля: NumberOfNamedEntries и NumberOfIdEntries, которые показывают число ресурсов, идентифицируемых по имени, и число ресурсов, идентифицируемых по номеру. Сразу за оглавлением расположена таблица ресурсов, каждая строка которой представлена структурой:

typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {

union {

struct {

DWORD NameOffset:31;

DWORD NameIsString:1;

};

DWORD Name;

WORD Id;

};

union {

DWORD OffsetToData;

struct {

DWORD OffsetToDirectory:31;

DWORD DataIsDirectory:1;

};

};

} IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;

Видно, что каждая строка таблицы состоит из двух объединений. Первое из них определяет, как идентифицируется ресурс: по имени или по номеру. Если старший бит первого объединения установлен в единицу, то ресурс идентифицируется по имени. Если в 0 - то по ID. Поле OffsetToData всегда используется для указания на потомка либо в ветви дерева, либо в конечном узле. Если первый бит второго объединения установлен в единицу, то OffsetToData указывает на потомка в ветви дерева. Если в 0, то на конечный узел. Конечные узлы - это низшие узлы в дереве ресурсов, которые определяют размер и местоположение непосредственно данных ресурса. Каждый конечный узел представляет собой структуру IMAGE_RESOURCE_DATA_ENTRY:

typedef struct _IMAGE_RESOURCE_DATA_ENTRY {

ULONG OffsetToData;

ULONG Size;

ULONG CodePage;

ULONG Reserved;

} IMAGE_RESOURCE_DATA_ENTRY, *PIMAGE_RESOURCE_DATA_ENTRY;

OffsetToData и Size указывают местоположение и размер непосредственно данных ресурса. CodePage - номер кодовой страницы, которая должна использоваться при декодировании данных. Последнее поле в структуре зарезервировано.

На рисунке можно увидеть примерную иерархию ресурсов в файле, а за рассматриванием рисунка нужно запомнить, что данные каждого отдельного ресурса (меню, диалоги, иконки, кнопки и т.д.), на которые указывает OffsetToData конечного узла, также могут иметь собственную особую структуру.

Стандартные идентификаторы ресурсов можно найти в заголовочном файле winuser.h:

/*

* Предопределенные типы ресурсов

*/

#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)

Резюме

Я рассказал не обо всех существующих полях PE-формата, но даже моя статья демонстрирует громоздкую структуру имеет этот формат. Если кто-то возьмется описывать форматы всех известных ресурсов, то, вполне может быть, посвятит этому целую книгу!

Назад на стр. 057-026-6  Содержание  Вперед на стр. 057-026-8