Уроки Iczelion'а

Файловый заголовок


В этом туториале мы изучим файловый заголовок PE.

Давайте кратко повторим то, что мы уже изучили:

  • DOS MZ-заголовок называется IMAGE_DOS_HEADER. Только два из его члена важны для нас: e_magic, который содержит строку "MZ" и e_lfanew, которая содержит файловое смещение PE-заголовка.
  • Мы используем значение в e_magic, чтобы убедиться, что файл имеет правильный DOS заголовок, сравнивая его со значение IMAGE_DOS_SIGNATURE. Если оба значения совпадают, мы можем быть уверены, что файл имеет правильный DOS-заголовок.
  • Чтобы перейти к PE-заголовку, мы должны передвинут файловый указатель на смещение, указанное значением в e_lfanew.
  • Первое слово PE-заголовка должно содержать строку "PE", за которым следуют два нуля. Мы сравниваем значение в этом двойном слове со значением IMAGE_NET_SIGNATURE. Если они оба совпадают, мы можем допустить, что PE-заголовок верен.

Мы изучим больше о PE-заголовке в этом туториале. Официальное название PE-заголовка - это IMAGE_NT_HEADERS. Чтобы освежить вашу память, я покажу ее ниже.

IMAGE_NT_HEADERS STRUCT Signature dd ? FileHeader IMAGE_FILE_HEADER <> OptionalHeader IMAGE_OPTIONAL_HEADER32 <> IMAGE_NT_HEADERS ENDS

Signature - это PE-сигнатура, "PE" следуемое за двумя нулями. Вы уже знаете и используете это параметр.

FileHeader - это структура, которая содержит информацию о физическом составе/свойствах PE-файла вообще.

OрtionalHeader - это также структура, которая содержит информацию о логическом составе PE-файла.

Самая интересная часть - это OрtionalHeader. Тем не менее, некоторые поля в FileHeader также важны. Мы изучим FileHeader в этом туториале, так что мы можем перейти к изучению OрtionalHeader'а в следующих туториалах.

IMAGE_FILE_HEADER STRUCT Machine WORD ? NumberOfSections WORD ? TimeDateStamp dd ? PointerToSymbolTable dd ? NumberOfSymbols dd ? SizeOfOptionalHeader WORD ? Characteristics WORD ? IMAGE_FILE_HEADER ENDS



Имя поляЗначение

Machine CPU платформа, для которой предназначен этот файл. Для платформы Intel это значение равно IMAGE_FILE_MACHINE_I386. Я попытался использовать 14Dh и 14Eh, упоминающиеся в pe.txt от LUEVELSMEYER, но Windows отказалась запустить ее. Это поле едва ли представляет для нас какой-либо интерес, кроме быстрого пути не дать программе быть запущенной.
NumberOfSection Количество секций в файле. Hам понадобится изменять данный параметр, если мы захотим добавить или убрать секцию из файла.
TimeDataStamp Дата и время, когда был создан файл. Бесполезен для нас.
PointerToSymbolTable используется для отладки.
NumberOfSymbols используется для отладки.
SizeOfOptionalHeader Размер параметра OрtionalHeader'а, который следует непосредственно за этой структурой. Должен быть установлен в правильное значение.
Charactericstics Содержит флаги для файла, например является ли этот файл exe или dll.
<
Вкратце. Только три параметра, более менее, полезны для нас: Machine, NumberOfSections и Characteristics. Как правило, вы не должны изменять значения Machine и Characteristics, но вы должны использовать это значение NumberOfSections, когда переходите к таблице секций.

Я опережаю события, но для того, чтобы проиллюстрировать использование NumberOfSections, я должен немного отвлечься на таблицу секций.
Таблица секций - это массив структур. Каждая структура содержит информацию о секции. То есть, если файл содержит три секции, будет 3 члена в этом массиве. Вам нужно значение параметра NumberOfSections, чтобы вы знали как много членов в этом массиве. За этим массивом следует pяд нулей, и Windows, по-моему мнению, использует этот факт, чтобы определять конец данного массива структур. Попробуйте установить значение NumberOfSections выше, чем на самом деле - Windows по-прежнему будет способен работать с файлом. Почему же мы не можем ингнорировать данный параметр? Существует несколько причин. Спецификация PE не указывает, что таблица секций должна кончаться структурой, состоящей из нулей. Может случиться ситуация, когда последний член массива вплотную прилегает к первой секции, без всякого свободного места. Другой причиной являются импорты. При компоновке в новом стиле информация следует непосредственно за последним членом таблицы секций. Вот почему вам нужен NumberOfSections.
[C] Iczelion, пер. Aquila.

Содержание раздела