Структура EXE-заголовка

В начале каждой EXE-программы идёт DOS-заголовок

Заголовок DOS
Смещение Размер Описание
0 2 Сигнатура 'MZ' - байты 4Dh, 5Ah
2 2 Размер последней неполной страницы
4 2 Размер файла в страницах по 512 байт, включая неполную
6 2 Количество элементов в таблице настроек адресов
8 2 Размер заголовка в параграфах по 16 байт
0Ah 2 Минимум дополнительно требуемой памяти в параграфах
0Ch 2 Максимум дополнительно требуемой памяти в параграфах
0Eh 2 Значение (относительное) регистра SS
10h 2 Значение регистра SP
12h 2 Контрольная сумма
14h 2 Значение регистра IP
16h 2 Значение (относительное) регистра CS
18h 2 Смещение в файле таблицы настроек адресов
1Ah 2 Номер оверлея
1Ch 8 Зарезервировано
24h 2 Идентификатор OEM
26h 2 Информация OEM
28h 20 Зарезервировано
3Ch 4 Смещение в файле PE-заголовка

За этим заголовком следуют таблица настроек адресов (нужна для запуска DOS-программ) и небольшая DOS-программа, выводящая сообщение об ошибке. Нас интересует PE-заголовок, адрес его начала записан по смещению 3Ch.

Заголовок PE
Смещение Размер Описание
0 4 Сигнатура 'PE' - байты 50h, 45h, 0, 0
4 2 Тип процессора - обычно 14Ch (i386)
6 2 Число секций в таблице секций
8 4 Дата и время создания программы
0Ch 4 Указатель на символьную отладочную информацию
10h 4 Число этих отладочных символов
14h 2 Размер PE-заголовка минус 18h (обычно E0h)
16h 2 Флаги
18h 2 Сигнатура 10Bh - нормальный заголовок
1Ah 2 Версия использовавшегося компоновщика
1Ch 4 Размер кода
20h 4 Размер инициализированных данных
24h 4 Размер неинициализированных данных
28h 4 Относительный виртуальный адрес точки входа
2Ch 4 Относительный виртуальный адрес секции кода
30h 4 Относительный виртуальный адрес секции данных
34h 4 Базовый адрес программы
38h 4 Выравнивание секций программы в памяти
3Ch 4 Выравнивание секций в файле
40h 4 Номер версии операционной системы
44h 4 Версия программы
48h 4 Номер версии Windows (обычно 4)
4Ch 4 Зарезервировано
50h 4 Размер всего образа программы
54h 4 Общий размер всех заголовков
58h 4 Контрольная сумма
5Ch 2 Подсистема:
 2 - графическое приложение
 3 - консольное приложение
5Eh 2 Характеристики dll
60h 4 Максимальный размер стека
64h 4 Начальный размер стека
68h 4 Максимальный размер кучи
6Ch 4 Начальный размер кучи
70h 4 Какие-то флаги загрузчика
74h 4 Число виртуальных адресов и размеров, указанных ниже (10h)
78h 4 Виртуальный адрес таблицы экспорта
7Ch 4 Размер таблицы экспорта
80h 4 Виртуальный адрес таблицы импорта
84h 4 Размер таблицы импорта
88h 4 Виртуальный адрес таблицы ресурсов
8Ch 4 Размер таблицы ресурсов
90h 4 Виртуальный адрес таблицы исключений
94h 4 Размер таблицы исключений
98h 4 Виртуальный адрес таблицы безопасности
9Ch 4 Размер таблицы безопасности
A0h 4 Виртуальный адрес таблицы настроек адресов
A4h 4 Размер таблицы настроек адресов
A8h 4 Виртуальный адрес таблицы отладочной информации
ACh 4 Размер таблицы отладочной информации
B0h 4 Виртуальный адрес строки с описанием программы
B4h 4 Размер строки с описанием программы
B8h 4 Виртуальный адрес таблицы с данными для процессора MIPS
BCh 4 Размер таблицы с данными для процессора MIPS
C0h 4 Виртуальный адрес области данных потоков (TLS)
C4h 4 Размер области данных потоков
C8h 4 Виртуальный адрес данных настройки загрузки
CCh 4 Размер данных с настройками загрузки
D0h 4 Виртуальный адрес таблицы привязки к библиотекам
D4h 4 Размер таблицы привязки к библиотекам
D8h 4 Виртуальный адрес списка импортируемых адресов
DCh 4 Размер списка импортируемых адресов
E0h 4*2 * 3 Зарезервировано

Все адреса в заголовке - это относительные виртуальные адреса (RVA) - адреса в памяти относительно базового адреса (он указан по смещению 34h). Если программа загружена по базовому адресу, то действительный адрес будет равен : базовый адрес + относительный адрес.

Сразу за этим заголовком следует таблица секций. Число элементов в ней равно числу секций файла и указано в заголовке.

Формат элемента таблицы секций
Смещение Размер Описание
0 8 Имя секции, дополненное при необходимости нулями
8 4 Виртуальный размер секции
0Ch 4 Относительный виртуальный адрес начала секции
10h 4 Размер секции в файле
14h 4 Смещение секции от начала файла
18h 10h Используется только в объектных файла
28h 4 Флаги секции
 биты 0-3 : зарезервировано
 бит 5 : содержит код
 бит 6 : содержит инициализированные данные
 бит 7 : содержит неинициализированные данные
 бит 28 : разделяемая секция
 бит 29 : доступна для выполнения
 бит 30 : доступна для чтения
 бит 31 : доступна для записи

Таблица импорта

Таблица импорта обычно содержится в секции импорта (rdata). Она содержит имена и адреса импортируемых из библиотек функций. Адрес её начала указан в PE-заголовке.

Элемент таблицы импорта
Смещение Размер Описание
0 4 Адрес таблицы имён процедур
4 4 Время создания библиотеки
8 4 ?
0Ch 4 Адрес имени библиотеки
10h 4 Адрес таблицы адресов процедур

Одному элементу таблицы соответствует одна импортируемая библиотека. В первом её элементе указан RVA адрес списка имён всех импортируемых из библиотеки процедур. Каждый элемент (размером 4 байта) этого списка содержит либо RVA адрес имени процедуры, либо, если установлен старший бит, номер этой процедуры. Элемент указывает не прямо на имя процедуры, а на 2-байтовое число (hint), за которым следует имя. Список заканчивается нулевым элементом. Каждому элементу списка соответствует элемент списка адресов процедур (на него указывает последнее поле). В этот элемент загрузчик помещает адрес соответствующей импортируемой процедуры. Если время создания библиотеки не равно нулю, то было произведено связывание, и в последнем списке уже находятся адреса процедур. В последнем элементе таблицы импорта адрес имени библиотеки установлен в ноль.

Сайт управляется системой uCoz