PE-формат. Часть 2 — Немного практики: выводим информацию о секциях исполняемого файла

Тем, кто мало знаком с PE-форматом, или совсем с ним не знаком, наверное, было непросто понять то море информации, которое было излито в моей предыдущей статье, поэтому я решил пока немного отложить изучение экспортов, импортов и прочих служебных таблиц в PE-файлах. В этой статье мы займемся практикой: напишем программку, которая выведет список секций произвольного исполняемого файла и некоторую информацию о них. Впоследствии, когда дойдет дело до написания упаковщика, этим кодом мы воспользуемся, ведь упаковывать мы будем как раз данные секций.

Писать будем на C++. Никаких извратов не будет, поэтому код должен быть понятен, тем более, я его досконально прокомментирую.
Начнем с инклюдов:

Далее — несколько макросов, которые предоставил Крис Касперски в своей статье про формат PE. Мы будем чаще всего использовать ALIGN_UP — макрос для выравнивания числа на заданную границу.

Итак, тело главной функции. В качестве единственного аргумента нашей программе будет передаваться путь к исполняемому файлу для анализа.

Теперь пришла пора открыть файл, имя которого нам передали через консоль.

Как я писал в предыдущей статье, в самом начале файла должна лежать структура IMAGE_DOS_HEADER. Считаем ее и немного проверим.

Теперь необходимо считать структуру IMAGE_NT_HEADERS. Я программу писал исключительно под PE32, хотя сделать ее для PE64 или вообще универсальной труда никакого не составляет. Читать будем, соответственно, структуру IMAGE_NT_HEADERS32 (это 32-разрядная версия IMAGE_NT_HEADERS, они все определены в глубине Windows.h). Сейчас я пропускаю множество необходимых проверок полей заголовка PE-файла (например, не проверяю выравнивания), потому что они сейчас не являются критичными.

Теперь нам необходимо переместиться к таблице секций, которую мы и будем читать, чтобы получить информацию о секциях исполняемого файла. Можно было бы воспользоваться макросом IMAGE_FIRST_SECTION, но я сделал это руками, чтобы было понятнее:

Немного подготовим консоль для удобного вывода информации. Выставим выравнивание текста по левому краю и вывод чисел в 16-ричной системе счисления. std::showbase добавит перед 16-разрядными числами «0x» автоматически.

Теперь начнем читать таблицу секций. Количество секций лежит в IMAGE_NT_HEADERS.FileHeader.NumberOfSections.

Дальше я добавил всевозможные проверки корректности таблицы секций. Разберем их.

Если вам сейчас трудно вспомнить, что это всё такое — виртуальный размер, реальный адрес, выравнивание, то советую вернуться к первой статье и всё повторить.

Пришло время вывести информацию о секции — раз уж она прошла все проверки 🙂

Вот и все, наша программа готова, и ей можно через консоль скормить любой исполняемый файл (PE32), чтобы получить информацию о его секциях. На первом скриншоте как раз показан вывод этой программы при анализе самой себя, собранной в Visual Studio 2010 в отладочной версии.

Полная версия кода (без комментариев): скачать (txt).

Оставьте первый комментарий

Оставить комментарий

Ваш электронный адрес не будет опубликован.


*