Смещение | Длина поля | Название поля | Описание поля |
---|---|---|---|
00h | 08h | Object Name | Имя объекта, остаток заполнен нулями. Если имя объекта имеет длину 8
символов, то заключительного 0 нет. Вот несколько возможных
имен:.text - исполняемый код общего
назначения.CODE - исполняемый код, помещаемый компоновщиками
фирмы BORLAND..icode - переходники (jump'ы), помещаемые сюда
старой версией TLINK32..data - инициализированные данные,
помещаются компоновщиком фирмы Microsoft.DATA -
инициализированные данные, помещаемые сюда компоновщиком
TLINK32..bss - неинициализированные глобальные и статические
переменные..CRT - еще одна секция для хранения
инициализированных данных..rsrc - секция для хранения
ресурсов..idata - секция импорта..edata -
секция экспорта..reloc - секция настроек. Данная информация
может понадобиться загрузчику, если он не сможет загрузить модуль по базовому
адресу..tls - данные для запуска
цепочек..rdata - данная секция в основном содержит отладочную
информацию..debug$s и .debug$t - данные секции
есть только в COFF-объектных файлах. Они содержат информацию о символах Code
View и их типах..drective - в данной секции содержится текст
программ для компоновки. Данная секция есть только в объектных файлах. Секции,
содержащие символ $ . Такие секции обрабатываются особым образом.
Компоновщик объединяет все секции, имеющие одинаковые символы в имени до символа
$ . Именем получившейся секции считается то, что стоит перед
указанным символом. |
08h | DWORD | Virtual Size | Виртуальный размер секции - именно столько памяти будет отведено под секцию.
Если Virtual Size превышает Physical Size , то разница заполняется
нулями, так определяются секции неинициализированных данных (Physical Size
= 0 ). |
0Ch | DWORD | Section RVA | Размещение секции в памяти, ее виртуальный адрес относительно Image
Base . Позиция каждой секции выровнена на границу Object
align (степень 2 от 512 до 256М включительно, по умолчанию 64К), секции
упакованы вплотную друг к другу, впрочем, можно это не соблюдать. Для объектных
файлов поле не имеет смысла. |
10h | DWORD | Physical Size | Размер секции (ее инициализированной части) в файле кратно полю File
align в заголовке РЕ Header, должно быть меньше или равно Virtual
Size . Для объектных файлов это поле содержит точный размер секции,
сгенерированный компилятором или ассемблером. Другими словами, для объектных
файлов оно эквивалентно полю Virtual Size . |
14h | DWORD | Physical Offset | Физическое смещение относительно начала ЕХЕ-файла, выровнено на границу
File align поля заголовка РЕ Header. Смещение используется
загрузчиком для поиска. |
18h | DWORD | Pointer to Linenumber | Файловое смещение таблицы номеров строк. Используется для объектных файлов. |
1Ch | WORD | Number of Relocations | Количество перемещений в таблице поправок. Используется только для объектных файлов. |
1Eh | WORD | Number of Linenumbers | Количество номеров строк в таблице номеров строк для данной секции. Используется для объектных файлов. |
20h | 08h | Reserved | Зарезервировано для объектных файлов. |
28h | DWORD | Object Flags | Битовые флаги секции:00000004h - используется для кода с
16-битными смещениями.00000020h - секция
кода.00000040h - секция инициализированных
данных.00000080h - секция неинициализированных
данных.00000200h - комментарии или любой другой тип
информации.00000400h - оверлейная
секция.00000800h - не будет являться частью образа
программы.00001000h - общие данные.00500000h -
выравнивание по умолчанию, если не указано иное.02000000h -
может быть выгружен из памяти.04000000h - не
кэшируется.08000000h - не подвергается страничному
преобразованию.10000000h -
разделяемый.20000000h - выполнимый.40000000h -
можно читать.80000000h - можно
писать. |
Страницы образов секций. Здесь мы изучим некоторые секции.
Секция экспорта (.edata
). Общая структура
1 | Таблица собственно экспорта | Export Directory Table |
2 | Адресная таблица | Export Address Table |
3 | Таблица указателей на имена | Export Name Table Pointers |
4 | Таблица номеров | Export Ordinal Table |
5 | Таблица самих имен | Export Name Table |
1. Таблица экспорта
Смещение | Длина поля | Название поля | Описание поля |
---|---|---|---|
00h | DWORD | Flags | Зарезервировано, должно быть равно нулю. |
04h | DWORD | Time/Date Stamp | Время и дата создания экспортных данных. |
08h | WORD | Major Version | Старший номер версии таблицы экспорта. Не используется. |
0Ah | DWORD | Minor Version | Младший номер версии таблицы экспорта, также не используется. |
0Ch | DWORD | Name RVA | Относительный адрес строки, указывающей на имя нашей библиотеки. |
10h | DWORD | Ordinal Base | Начальный номер экспорта, для функций, экспортируемых данным модулем. |
14h | DWORD | Num of Functions | Количество функций экспортируемых данным модулем, является числом элементов массива Address Table (см.ниже). |
18h | DWORD | Num of Name Pointers | Число указателей на имена, обычно равно числу функций, но это не так, если у нас есть функции, экспортируемые только по номеру. |
1Ch | DWORD | Address Table RVA | Указатель на таблицу относительных адресов экспортируемых функций. |
20h | DWORD | Name Pointers RVA | Указатель на таблицу указателей на имена экспортируемых функций данного модуля. |
24h | DWORD | Ordinal Table RVA | Указатель на таблицу номеров экспорта, данный массив по индексам параллелен Name Pointers, элементами являются слова. |
2. Таблица адресов экспорта. Эта структура данных содержит адреса
экспортируемых функций (их точки входа) в формате DWORD
(по 4 байта
на элемент). Для доступа к данным используется номер функции с коррекцией на
базу номеров (Ordinal Base
).
3. Таблица указателей на имена. Данная структура содержит указатели на имена экспортируемых функций, указатели отсортированы в лексическом порядке для обеспечения возможности бинарного поиска. Каждый указатель занимает 4 байта. Имена функций обычно лежат в секции экспорта.
4. Таблица номеров. Данная структура совместно с Name Table
Pointers
формирует два параллельных массива, разделенных для облегчения к
ним доступа индексированием на родные для процессора данные (слова, двойные
слова, но не сложные структуры). Данный массив содержит номера экспорта, которые
в общем случае являются индексами в Address Table
экспорта (за
вычетом базы Ordinal Base
). Элементами данного массива являются
слова (2 байта).
5. Таблица имен экспорта. Эта таблица содержит необязательные (по
мнению Microsoft) имена экспортируемых функций. Данный массив используется
совместно с Name Table Pointers
и Ordinal Table
для
обеспечения связывания загрузчиком импорта/экспорта по имени. Механизм
описывался выше. Каждый элемент являет собой ASCIIZ строку с именем
экспортируемой функции. Никто не говорит, что они должны в файле идти друг за
другом последовательно, хотя так построено большинство файлов. Надо отметить,
что имена экспорта чувствительны к регистру. Отметим особенность загрузчика -
при связывании, если адрес функции находится в секции экспорта, на самом деле по
указанному адресу лежит строка, переадресующая к другой библиотеке,
экспортирующей данную функцию (с указанием библиотеки и самой функции). Это
называется - передача экспорта.
Секция импорта (.idata
)
Схема вызова импортируемых функций из РЕ-модуля изображена на Рис. 4.1.4,
который с некоторыми изменениями взят из книги [2]. Смысл данного рисунка
заключается в следующем. При компоновке все вызовы API-функций преобразуются к
вызову типа CALL Адрес1
. При этом адрес, также как и вызов,
находится в секции кода (.text
). По адресу же стоит команда
JMP DWORD PTR [Адрес2]
. [Адрес2]
находится в секции
.idata
(импорта) и содержит двойное слово — адрес функции в
динамической библиотеке. Современные компиляторы содержат директивы, позволяющие
вместо двух вызовов (CALL
и JMP
) генерировать один
CALL [Адрес2]
.
Таблица директория импорта
Каталог импорта | Import Directory Table |
Таблица ссылок на имена | LookUp Table |
Таблица имен | Hint-Name Table |
Таблица адресов импорта | Import Address Table |
Формат входа в каталог импорта
Смещение | Длина поля | Название поля | Описание поля |
---|---|---|---|
00h | DWORD | Import LookUp | Содержит ссылку на таблицу относительных адресов (относительно базового адреса), указывающих на соответствующие имена импортируемой функции, или непосредственно номер импортируемого входа. |
04h | DWORD | Time/Date Stamp | Отметка о времени создания, часто содержит ноль. |
08h | DWORD | Forward Chain | Связано с возможностью передачи экспорта в другие библиотеки. Обычно равно
0FFFFFFFFh . |
0Ch | DWORD | Name RVA | Ссылка на библиотеку импорта в виде ASCII строки с нулем на конце. Например, KERNEL32.DLL или USER32.DLL. |
10h | DWORD | Addres Table RVA | Ссылка на таблицу адресов импорта, заполняется системой при связывании. |
Таблица просмотра импорта или таблица имен сервисов. Ссылка из поля
Import LookUp
на массив, содержащий ссылки на таблицу просмотра
импорта. При импортировании по номеру старший бит элемента массива равен
1
.
Тип | Содержимое |
---|---|
Word | Номер функции |
Hint | ASCII имя функции |
Таблица адресов импорта. Данная таблица принимает в себя информацию после связывания загрузчиком импорта из внешних библиотек, она завершается нулевым элементом.
Локальная область данных цепочек (потоков)
Локальная область данных цепочек, это специальный, протяженный блок данных. Каждая цепочка получит собственный блок при создании.
Таблица разделов цепочек | TLS Directory Table |
Данные цепочек | TLS Data |
Индексные переменные | Index Variables |
Адреса обратных вызовов | CallBack |
Таблица разделов потоков
Смещение | Длина поля | Название поля | Описание поля |
---|---|---|---|
00h | DWORD | Start Data Block VA | Виртуальный адрес начала блока данных цепочки. |
04h | DWORD | End Data Block VA | Виртуальный адрес конца блока данных цепочки. |
08h | DWORD | Index VA | Виртуальный адрес индексной переменной, используемой для доступа к локальному блоку данных цепочки. |
0Ch | DWORD | CallBack Table VA | Виртуальный адрес таблицы обратных вызовов. Локальные обратные вызовы - массив виртуальных адресов функций, которые будут вызваны загрузчиком после создания цепочки (нити) и после ее завершения. Последний вход имеет нулевое значение и указывает на конец таблицы. |
Секция ресурсов (.rdata
)
Ресурсы представляют собой многоуровневое двоичное дерево. Их структура
позволяет содержать до 2^31 уровней, однако реально используется только 3: самый
верхний есть Type
, затем Nam
и затем
Language
(тип, имя, язык). Перемещения по иерархии каталогов
ресурсов похожи на перемещения по каталогам жесткого диска. Типичное
представление ресурсного участка в файлах:
Каталог ресурсов | Resources Directory Table |
Данные ресурсов | Resources Data |
Каталог ресурсов (Resource Directory Table)
Смещение | Длина поля | Название поля | Описание поля |
---|---|---|---|
00h | DWORD | Flags | Пока не используются, должны быть сброшены в ноль. |
04h | DWORD | Time/Date Stamp | Дата и время создания ресурсов от ресурсного компилятора. |
08h | WORD | Major Version | Старшая часть версии ресурсов. Обычно равно нулю. |
0Ah | WORD | Minor Version | Младшая часть версии ресурсов. Обычно равно нулю. |
0Ch | WORD | Name Entry | Количество входов в таблицу имен (элементов массива) ресурсов. Таблица располагается в самом начале массива входов и содержит строковые имена, ассоциируемые с ресурсами. |
0Eh | WORD | ID_Num Entry | Количество элементов массива, использующих целые ID. |
За каталогом ресурсов сразу следует массив переменной длины, содержащий
ресурсные входы. Name Entry
содержит число ресурсных входов,
имеющих имена (связанные с каждым входом). Имена нечувствительны к регистру и
расположены в порядке возрастания. ID_Num Entry
определяет число
входов имеющих в качестве имени 32-битовый идентификатор. Эти входы так же
отсортированы по возрастанию. Данная структура позволяет получать быстрый доступ
к ресурсам по имени или по идентификатору, но для отдельно взятого ресурса
поддерживается только одна из форм поиска. Что согласуется с синтаксисом
.RC
и .RES
файлов. Каждый вход в таблицу ресурсов
имеет следующий формат.