Анатомия файла Иван Скляров Спецвыпуск: Хакер, номер #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-формата, но даже моя статья демонстрирует громоздкую структуру имеет этот формат. Если кто-то возьмется описывать форматы всех известных ресурсов, то, вполне может быть, посвятит этому целую книгу! |