Пишем собственный упаковщик. Шаг 12 — Работа над ошибками

pack

Благодаря одному товарищу из комментариев в предыдущих постах касательно упаковщика выявился один занятный баг в коде, который я поспешил исправить. Комментатор, не разобравшись в деталях работы пакера, утверждал, что код, запакованный им, окажется неспособным работать с SEH при условии, что DEP включен. При таких условиях код работал хорошо (так как весь распакованный код в памяти находится в пределах одной-единственной секции PE-файла, помеченной как исполняемая. UPX имеет такую же логику работы.). Но случайно была обнаружена следующая ошибка: если программа собрана в MSVC++, использует SEH и имеет релокации, при первом же возникшем исключении она упадет с некоторой долей вероятности (точнее, если файл загрузился не по своему базовому адресу). DEP тут, конечно же, не при чем. Все дело оказалось в злополучной директории IMAGE_LOAD_CONFIG_DIRECTORY. Она создается линкером Visual Studio. Из полезной информации она содержит таблицу адресов (RVA) SE-обработчиков и указатель на внутреннюю переменную crt __security_cookie. Как выяснилось, эта директория нужна не только для внутренностей CRT (хотя она, кажется, как раз хотела плевать на эту структуру), но и системному загрузчику (по крайней мере, в Win7. WinXP, похоже, тоже плевал на эту директорию). Упаковщик, который я описываю, перемещает эту директорию в другую секцию (см. здесь). Поэтому исправить ошибку можно, добавив в таблицу релокаций, создаваемую упаковщиком, несколько записей, которые будут править адреса, указывающие на security cookie и таблицу обработчиков SEH, чтобы он мог считать интересующую его информацию из этой директории на этапе загрузки.

Помимо правки этой ошибки я обновил код упаковщика, чтобы он собирался с использованием последней на данный момент версией библиотеки для работы с PE-файлами (PE Bliss). Ее всегда можно скачать отсюда.

Кстати, насчет библиотеки PE Bliss. Сейчас в свободное время я допиливаю новую версию, в которой появятся следующие дополнительные возможности (список примерный и может измениться):
- высокоуровневая работа с дополнительными типами ресурсов PE-файлов;
- детальный разбор .NET-бинарников (метаданные, сигнатуры, ресурсы);
- обертка над библиотекой на C++/CLI, которая позволит .NET-разработчикам удобно использовать функционал библиотеки в софте на C# или Visual Basic .NET.

Скачать исходники упаковщика: packer source
Скачать собранный вариант: packer binary

UPDATE 24.05.2016: доработки генерации таблиц релокации. В некоторых случаях (например, когда TLS-данных слишком много и присутствует директория load config, адреса в таблице релокации могли переполняться, и файл после упаковки не работал).

Библиотека для работы с PE-файлами (C++)

Выкладываю более-менее завершенную библиотеку для работы с Portable Executable (PE) файлами - PE Bliss.

Основные фичи библиотеки:
[+] Чтение 32-разрядных и 64-разрядных PE-файлов (PE, PE+) для Windows, возможность единообразной работы с обоими форматами
[+] Создание PE/PE+ образов с чистого листа
[+] Пересборка 32-разрядных и 64-разрядных PE-файлов
[+] Работа с директориями и заголовками
[+] Конвертирование адресов
[+] Чтение и редактирование секций PE-файла
[+] Чтение и редактирование таблицы импортов
[+] Чтение и редактирование таблицы экспортов
[+] Чтение и редактирование таблиц релокаций
[+] Чтение и редактирование ресурсов
[+] Чтение и редактирование TLS
[+] Чтение конфигурации образа (image config)
[+] Чтение базовой информации .NET
[+] Чтение информации о привязанном импорте
[+] Чтение директории исключений (только PE+)
[+] Чтение отладочной директории с расширенной информацией
[+] Вычисление энтропии
[+] Изменение файлового выравнивания
[+] Изменение базового адреса загрузки
[+] Работа с DOS Stub'ом и Rich overlay
[+] Высокоуровневое чтение ресурсов: картинки, иконки, курсоры, информация о версии, строковые таблицы, таблицы сообщений
[+] Высокоуровневое редактирование ресурсов: картинки, иконки, курсоры, информация о версии

Словом, все, что вы хотели сделать с PE, но боялись спросить, как. Весь код библиотеки снабжен обильными комментариями на английском языке. В проект включено 25 примеров работы с библиотекой, которые показывают, как работать с той или иной частью библиотеки (комментарии на русском языке). Имеются солюшены для MSVC++ 2008 и 2010. Справочной информации пока нет, возможно, соберусь ее как-нибудь написать.

Библиотека не использует WinAPI или другие библиотеки, только STL.

Библиотека и примеры собираются под Windows x86 и x64, но для того, чтобы работать с PE+, собирать под x64 необязательно. Библиотека не исполняет считываемые файлы, не маппит их в память, поэтому с ее помощью можно спокойно открывать подозрительные исполняемые файлы и работать с ними. Теперь собирается еще и под Linux.

Проект залит на code.google.com на случай возможных правок и улучшений, так как сейчас библиотека в стадии альфа-версии.

Репозиторий: http://code.google.com/p/portable-executable-library/
Скачать архив с сорсами версии 0.1.11 (годятся для сборки упаковщика по ману, который тут в блоге есть): ZIP
Скачать архив с последними сорсами (1.0.0): ZIP