Когда человек открывает исполняемый файл Windows с расширением .exe или библиотеку .dll, внутри находится не просто набор машинных команд. В начале такого файла расположен специальный блок данных — заголовок PE-файла (Portable Executable). Именно он сообщает операционной системе, как правильно загрузить файл в память, какие части нужно подготовить к работе и какие дополнительные данные использовать.
Знание структуры PE-заголовка нужно не только разработчикам операционных систем. Оно помогает при анализе программ, поиске вредоносного кода, отладке приложений, изучении работы загрузчика Windows и проверке подозрительных файлов. Главная задача заголовка — дать Windows понятную инструкцию: «что это за файл и как с ним обращаться».
Зачем вообще нужен заголовок PE-файла
Обычный пользователь редко задумывается о том, что происходит после двойного щелчка по программе. Но Windows не запускает файл вслепую. Перед выполнением она читает служебную информацию, которая находится в начале PE-структуры.
В заголовках содержатся данные о:
- типе файла и его архитектуре;
- размере и расположении различных частей программы;
- точке входа, с которой начинается выполнение кода;
- таблицах импорта и экспорта функций;
- требованиях к памяти;
- ресурсах программы;
- информации для отладки и защиты.
Если эта информация повреждена или заполнена неправильно, Windows может отказаться запускать файл или программа будет работать с ошибками.
Как устроен PE-файл изнутри
PE-файл состоит из нескольких последовательных областей. Заголовок занимает только начало файла, но он связан практически со всеми остальными частями.
Упрощённо структура выглядит так:
- DOS-заголовок — старый совместимый блок, который сохранился ещё со времён MS-DOS.
- PE-заголовок — основной идентификатор формата Portable Executable.
- COFF-заголовок — общая информация о файле и количестве секций.
- Optional Header — параметры загрузки программы.
- Таблица секций — описание областей с кодом, данными и ресурсами.
- Сами секции — исполняемый код, переменные, ресурсы и другие данные.
Несмотря на название, Optional Header не является необязательным для обычного исполняемого файла Windows. Это одна из самых важных частей PE-заголовка.
DOS-заголовок: зачем он остался в современных программах
Первый блок PE-файла начинается с DOS-заголовка. Он появился ради обратной совместимости. В старых системах MS-DOS Windows могла показать специальное сообщение вместо попытки выполнить неизвестный формат.
Главное поле, которое используют современные программы анализа, — это:
- MZ-сигнатура в первых двух байтах файла;
- e_lfanew — смещение, по которому находится настоящий PE-заголовок.
То есть Windows сначала смотрит начало файла, находит указатель дальше по структуре и уже потом переходит к PE-информации.
PE-сигнатура и COFF-заголовок
После DOS-части находится основная подпись формата — последовательность байтов PE\0\0. Она говорит загрузчику: перед ним действительно файл Portable Executable.
Следом идёт COFF-заголовок. Он содержит базовую информацию:
- тип архитектуры процессора;
- количество секций;
- время создания файла;
- размер дополнительного заголовка;
- характеристики файла.
Например, по данным архитектуры можно определить, рассчитан ли файл на x86, x64 или другую платформу. Это важно, потому что 32-битная и 64-битная программы используют разные правила загрузки.
Главная часть — Optional Header
Именно здесь хранится большая часть информации, необходимой Windows при запуске программы. Несмотря на название, этот раздел фактически является обязательным для PE-файлов приложений.
В нём находятся следующие важные поля:
| Поле | Что хранит | Зачем нужно |
|---|---|---|
| AddressOfEntryPoint | Адрес точки входа | Показывает, с какой инструкции начинается выполнение программы |
| ImageBase | Предпочтительный адрес загрузки | Используется при размещении файла в виртуальной памяти |
| SectionAlignment | Выравнивание секций в памяти | Помогает правильно расположить части программы |
| SizeOfImage | Общий размер образа в памяти | Определяет, сколько места нужно выделить при загрузке |
| Subsystem | Тип приложения | Определяет режим запуска, например консольный или графический |
| DataDirectory | Адреса специальных таблиц | Позволяет найти импорты, ресурсы, сертификаты и другие данные |
Таблицы данных внутри PE-заголовка
Особенность PE-формата в том, что заголовок не хранит всё напрямую. Многие важные сведения находятся в отдельных таблицах, а заголовок содержит ссылки на них.
Наиболее часто используются:
Таблица импорта
Она показывает, какие функции программа получает из внешних библиотек. Например, приложение может использовать функции Windows API из системных DLL.
По таблице импорта можно понять:
- какие библиотеки нужны программе;
- какие системные возможности она использует;
- есть ли подозрительные зависимости.
Таблица экспорта
Она описывает функции, которые файл предоставляет другим программам. Особенно важна для DLL-библиотек.
Таблица ресурсов
Здесь находятся данные, которые не являются кодом:
- иконки;
- диалоги;
- строки интерфейса;
- версии программы;
- дополнительные файлы.
Таблица релокаций
Она нужна, когда программа не может быть загружена по своему предпочтительному адресу в памяти. В таком случае Windows корректирует адреса, используя информацию из этой таблицы.
Какие отличия есть у PE32 и PE32+
При анализе файла часто возникает вопрос: это обычный 32-битный PE или 64-битный вариант?
| Характеристика | PE32 | PE32+ |
|---|---|---|
| Архитектура | 32-битные системы x86 | 64-битные системы x64 |
| Размер адресов | 32 бита | 64 бита |
| Типичные файлы | Старые приложения и часть современных программ | Большинство современных Windows-приложений |
| Раздел Optional Header | Имеет поля для 32-битных адресов | Использует расширенные 64-битные значения |
Как посмотреть заголовок PE-файла на практике
Если нужно проверить структуру файла, не обязательно вручную искать байты в шестнадцатеричном редакторе. Есть специальные инструменты анализа.
Обычно порядок действий такой:
- Открыть файл в PE-анализаторе.
- Проверить сигнатуру MZ и PE.
- Посмотреть архитектуру и тип файла.
- Изучить точку входа.
- Проверить импортируемые библиотеки.
- Посмотреть секции и их характеристики.
Для таких задач часто используют инструменты вроде PE-bear, CFF Explorer, Detect It Easy или встроенные возможности отладчиков. Главное — смотреть не одно поле, а всю картину целиком.
Частые ошибки при анализе PE-заголовка
Ошибочно делать вывод о назначении программы только по одному параметру из PE-заголовка. Отдельное поле редко даёт полную картину — анализ нужно проводить комплексно.
- Считать дату создания в заголовке настоящей датой разработки. Поле времени может изменяться при сборке, упаковке или модификации файла.
- Искать вирус только по названию секций. Злоумышленники могут менять имена, а обычные программы иногда имеют нестандартную структуру.
- Считать подозрительной любую нестандартную запись. Некоторые защитные технологии и упаковщики специально изменяют структуру файла.
- Игнорировать таблицу импорта. Именно она часто даёт больше полезной информации о назначении программы.
- Путать размер файла и размер в памяти. PE использует отдельные значения для хранения на диске и загрузки в оперативную память.
Как правильно подходить к изучению PE-заголовка
Если задача — разобраться, что делает неизвестный файл, лучше идти по порядку:
- Определить тип файла и архитектуру.
- Проверить цифровую подпись и источник получения.
- Посмотреть импортируемые библиотеки.
- Изучить секции: их размеры, права доступа и содержимое.
- Проверить ресурсы и дополнительные данные.
- При необходимости перейти к динамическому анализу во время запуска.
Такой подход быстрее приводит к результату, чем попытка сразу разбирать все поля заголовка.
Что выбрать в зависимости от задачи
| Ситуация | На что смотреть в первую очередь |
|---|---|
| Нужно понять, запустится ли программа | Архитектура, подсистема, точка входа, зависимости |
| Нужно изучить неизвестный файл | Импорты, секции, ресурсы, подпись |
| Нужно исследовать DLL | Экспорты, зависимости, точки входа функций |
| Нужно отлаживать собственное приложение | Entry Point, секции, таблицы загрузки |
| Нужно искать признаки упаковки или защиты | Размеры секций, энтропия данных, нестандартная структура |
Практические рекомендации
- Не ограничивайтесь просмотром первых байтов файла — важны связи между всеми разделами PE.
- Для обучения лучше начать с изучения простых EXE-файлов без упаковки и защиты.
- Всегда сравнивайте подозрительный файл с обычными программами того же типа.
- При анализе вредоносных образцов не запускайте неизвестный файл на основной системе.
- Изучайте не только заголовок, но и секции, потому что именно там находится основной код и данные.
Главное, что нужно запомнить
Заголовок PE-файла — это инструкция для Windows о том, что находится внутри программы и как её загрузить. В нём хранятся сведения об архитектуре, точке запуска, расположении частей файла, необходимых библиотеках, ресурсах и дополнительных таблицах.
Если нужно быстро разобраться с программой, не обязательно знать каждое поле формата PE. Достаточно понимать логику: сначала определить тип файла, затем посмотреть, куда он запускается, какие библиотеки использует и какие данные содержит.
Именно такой подход позволяет использовать PE-заголовок как практический инструмент — для разработки, отладки и анализа программ, а не просто как набор непонятных технических полей.
