Распаковка исполняемых файлов
Привет, хабровчане. В рамках курса «Reverse-Engineering. Basic» Александр Колесников (специалист по комплексной защите объектов информатизации) подготовил авторскую статью.
Также приглашаем всех желающих на открытый вебинар по теме «Эксплуатация уязвимостей в драйвере. Часть 1». Участники вебинара вместе с экспертом разберут уязвимости переполнения в драйверах и особенности разработки эксплойтов в режиме ядра.
Статья расскажет о подходах к анализу запакованных исполняемых файлов с помощью простых средств для обратной разработки. Будут рассмотрены некоторые пакеры, которые применяются для упаковки исполняемых файлов. Все примеры будут проведены в ОС Windows, однако изучаемые подходы можно легко портировать на любую ОС.
Инструментарий и настройка ОС
Для тестов будем использовать виртуальную машину под управлением ОС Windows. Инструментарий будет содержать следующие приложения:
установленный по умолчанию плагин x64dbg Scylla;
Самый быстрый и простой способ провести распаковку любого исполняемого файла — применить отладчик. Но так как мы будем также рассматривать язык программирования Python, то может понадобится проект:
uncompile6 проект, который позволяет разобрать байткод виртуальной машины Python;
pyinstallerExtractor инструмент для распаковки архива pyInstaller.
Общие методы снятия паковки
Разберемся, что же такое паковка. В большинстве случаев исполняемые файлы современных языков программирования имеют довольно большой размер при минимальном наборе функций. Чтобы оптимизировать данную величину, можно применить паковку или сжатие. Наиболее распространенный на сегодняшний день пакер — UPX. Ниже приведен пример того, как пакер проводит сжатие исполняемого файла.

На картинке может показаться, что файл стал по размеру больше, однако это не всегда так. Большинство файлов за счет такой модификации могут уменьшить свой размер до 1.5 раз от исходного объема.
Что же от этого реверс-инженеру? Почему надо знать и уметь определять, что файл упакован? Приведу наглядный пример. Ниже приведен снимок файла, который не запакован:

И файл, который был пропущен через алгоритм UPX:

Изменения коснулись в этом случае двух основных точек исполняемого файла:
Точка входа — в случае с упакованным файлом это начало алгоритма распаковки, настоящий алгоритм программы будет работать только после того, как будет распакован оригинальный файл;
Код оригинального файла: теперь не найти паттернов, которые можно сразу разбирать как команды.
Итак, чтобы снова анализировать оригинальный файл, нужно найти настоящую или оригинальную точку входа. Для этого нужно разбить алгоритм на основные этапы:
Этап подготовки исполнения файла — загрузчик ОС настраивает окружение, загружает файл в оперативную память;
Сохранение контекста — упаковщик сохраняет контекст исполнения файла (набор значений регистров общего назначения, которые были установлены загрузчиком ОС);
Распаковка оригинального файла;
Передача управления оригинальному файлу.
Все описанные выше этапы можно легко отследить в отладчике. Особенно может выделяться процедура сохранения контекста. Для нее в разных архитектурах могут быть использованы команды pushad/popad или множественное использование команды push . Поэтому всегда приложение трассируют до первого изменения регистра ESP/RSP, и ставят «Hardware Breakpoint» на адрес, который был помещен в регистр в первый раз. Второе обращение этому адресу будет в момент восстановления контекста, который заполнил загрузчик ОС. Без него приложение завершится с ошибкой.
Пример UPX
Попробуем с помощью отладчика найти оригинальную точку входа для приложения. Запечатлим оригинальную точку входа до упаковки UPX:

Как та же точка входа выглядит после упаковки:

Запустим отладчик и попробуем найти место сохранения контекста:

Ждем первого использования ESP — в отладчике при этом значение регистра подсветится красным цветом. Затем устанавливаем точку останова на адрес и просто запускаем приложение:

В результате попадаем на оригинальную точку входа:

Вот так просто, теперь используя плагин Scylla Hide можно сохранить результирующий файл на жесткий диск и продолжить его анализ.
Подобный метод можно применять для любого упаковщика, который сохраняет контекст на стек.
Пример PyInstaller
Не всегда подобный подход работает для приложений, которые используют более сложную структуру исполняемого файла. Рассмотрим файл, который был создан с помощью PyInstaller — пакет, который позволяет преобразовать Python скрипт в исполняемый файл. При генерации исполняемого файла создается архив, который содержит виртуальную машину Python и все необходимые библиотеки. Сам исходный код приложения при этом преобразуется в байт код и его нельзя дезассемблировать.
Попробуем все же получить что-то читаемое. Создадим простое приложение на Python и упакуем с помощью PyInstaller. Исходный код приложения:
Установим пакет pyInstaller и создадим exe файл:
Итак, проведем сбор информации о том, что в итоге получилось. У нас есть архив, который должен запустить виртуальную машину, и код, который мы записали в виде скрипта. Попробуем восстановить исходник и просто его прочесть даже без запуска.
После выполнения команд выше, у вас должна создаться директория ./dist/test.exe . Откроем последовательно файл с помощью pyinstallerextractor и uncompile3 :

Наш скрипт находится в директории, которая создается в результате распаковки. Наименование файла должно соответствовать названию exe файла. В нашем случае это test.pyc . Откроем его в hiew :

Декомпиляция стандартными средствами невозможна, так как инструменты просто не умеют работать с байткодом Python. Применим специализированный инструмент — uncompile6 .
Извлечь ресурсы из EXE-файлов
Redwood Resource Extractor — это бесплатный инструмент разработки, который позволяет просматривать и сохранять ресурсы из EXE, DLL или файла OCX. Используя Redwood, вы можете извлекать значки, курсоры, изображения, таблицы строк, информацию о версии и т. Д. Бесплатное ПО для Windows предназначено только для использования в целях разработки.
Извлечение ресурсов из файлов EXE

Инструмент очень простой и легкий. Для начала вам необходимо открыть EXE-файл Redwood. Как только вы его откроете, появится диалоговое окно с просьбой открыть исполняемый файл, из которого вы хотите извлечь ресурсы. После того, как вы выбрали файл, нажмите кнопку «Открыть», и все готово.
В левом окне дерева ресурсы будут отсортированы по категориям, и вы можете открыть любой узел, чтобы просмотреть ресурсы, лежащие под ним. Редвуд можно использовать для извлечения любых ресурсов, перечисленных в списке ниже:
- Файлы значков
- Таблицы строк
- Информация о версии
- Некоторые двоичные файлы
- Манифест
- Графика изображений ICO
- Диалоговые элементы управления
- Многие другие ресурсы.
Чтобы извлечь ресурс, выберите его в левом окне дерева и нажмите кнопку «Извлечь». Теперь выберите место, где вы хотите сохранить ресурс, и нажмите кнопку «Сохранить». Теперь у вас есть этот ресурс отдельно от EXE-файла. Точно так же вы можете сделать то же самое для файлов OCX, DLL и CPL.
Программа действительно является полезным инструментом для разработчиков. Он выполняет не очень распространенную задачу, но все же отлично справляется с этим. Redwood может очень легко сохранить даже файлы ICO размером 256 × 256. Пользовательский интерфейс приятный и простой в использовании. Автоматические обновления включены по умолчанию, и вы можете отключить их, нажав третью кнопку — это кнопка «Автообновление». Redwood вообще не требует настройки и доступен в портативном формате, поэтому вам не нужно его устанавливать.
Redwood Resource Extractor скачать
Нажмите здесь скачать Redwood. Это просто необходимо для разработчиков.
Некоторые из вас могут также захотеть взглянуть на Resources Hacker.
.
Как извлечь файлы из exe
Автоматические распаковщики инсталляторов
Назначение программ для распаковки инсталляторов понятно. В настоящее время инсталляторы сами представляют собой достаточно сложные программы, вносящие изменения в систему или реестр, создающие ярлыки, записывающие файлы в различные папки. Но иногда инсталляторы выполняют нежелательные действия, например, пытаются без ведома пользователя установить различные тулбары или рекламные модули, отправляют разработчику информацию о факте установки, не дают выполнить установку без ввода пароля или серийного номера, и прочие гадости. В этом случае нам требуется извлечь из дистрибутива все содержащиеся в нем файлы, не запуская сам инсталлятор. Кроме файлов из некоторых инсталляторов можно извлечь так называемые скрипты установки, в которых прописывается последовательность действий, из них можно узнать какие ключи реестра меняются, какие файлы и куда записываются и т.п. Также извлеченные из инсталляторов скрипты можно в дальнейшем использовать для создания перепакованных вариантов программ, например, уже включающие в себя файлы с отломанной регистрацией. Еще некоторые особо одаренные аффтары проверяют целостность ранее установленной программы и не дают устанавливать обновления на модифицированные инсталляции, в основном такие милые приколы встречаются на играх. Так что умение бороться с инсталляторами всегда пригодится.
Самым мощным и удобным инструментом для автоматической распаковки инсталляторов является программа Universal Extractor. Она представляет собой оболочку для других распаковщиков, всего поддерживается несколько десятков различных форматов, в том числе таких популярных, как распаковка Inno Setup, InstallShield, Wise Installer и других. Поддерживается русский язык, интеграция в контекстное меню Проводника Windows, продвинутые пользователи могут сохранить и посмотреть лог работы внешних модулей распаковки. На момент написания статьи хостинг с дистрибутивами и исходниками Universal Extractor недоступен, поэтому выложу Universal Extractor здесь.
Universal Extractor 1.6.1
Многие инсталляторы представляют собой обычный архивный файл, к которому дописан модуль для его распаковки, то есть SFX-архив (Self-extracting архив). Поскольку распространенных алгоритмов компрессии не так много, в некоторых случаях для распаковки инсталляторов можно воспользоваться обычными архиваторами, например, WinRAR или бесплатным 7zip.
Теперь переходим к специализированным распаковщиками, ориентированным на конкретный тип инсталляторов. Наиболее мощный и популярный инструмент для создания инсталляторов — бесплатный Inno Setup, он обладает скриптовым языком, позволяющим делать практически неограниченные по опциям дистрибутивы.
innounp, распаковщик инсталляторов Inno Setup версий от 2.0.8 до 5.3.11. Inno Setup Unpacker — консольная утилита, поэтому для удобства работы сделано несколько графических оболочек, например, IS Unpacker Explorer (русскую версию можно найти на сайте MSILab) или InnoSetup And NSIS Unpacker Shell (требует 7zip и innounp).
InnoSetup And NSIS Unpacker Shell 1.4
Вспомогательная утилита InnoCry предназначена для обхода паролей на инсталляторах, созданных Inno Setup. Запускаете сперва инсталлятор, в котором требуется ввод пароля, параллельно запускаете InnoCry. Затем InnoCry несколькими способами пытается пропатчить в памяти исполняемый код инсталлятора, чтобы он не требовал ввода пароля. В последней версии также появилась опция активации заблокированных кнопок.
InnoCry 1.2.7
InnoExtractor сделан на базе архиватора 7zip. Позволяет просматривать и извлекать содержимое инсталляторов Inno Setup. Большой плюс в том, что InnoExtractor постоянно совершенствуется и поддерживает как старые, так и новейшие версии этого инсталлятора.
InnoExtractor 4.8.0.156
Для распаковки инсталляторов, созданных при помощи Nullsoft Scriptable Install System или сокращенно NSIS, удобнее всего пользоваться бесплатным архиватором 7zip. Он без труда открывает такие инсталляторы для просмотра и позволяет извлекать из них нужные файлы.
E_WISE 2002.03.29 — консольная утилита для извлечения файлов из WISE-инсталляторов. Поддерживаются практически все версии Wise-инсталляторов, в комплекте есть версии распаковщика для DOS, Windows и Linux, а также документация на английском и немецком языках.
E_WISE 2002.03.29
E_WISE 2002.07.01 (Update)
HWUN (Heuristic Wise UNpacker) также предназначен для распаковки инсталляторов WISE, но в отличие от предыдущей программы использует эвристические алгоритмы для поиска необходимых сигнатур и данных, так что есть большая вероятность, что он будет работать и с более новыми версиями инсталляторов.
Setup Factory Unpacker — консольный распаковщик инсталляторов Setup Factory версии 5 и 6. Как признается сам автор, имеют место быть глюки и баги, так что пригодится больше для коллекции.
Setup Factory Unpacker
InstallShield (by one exe-file) Unpacker — автоматический консольный распаковщик двух из трех известных типов инсталляторов, созданных программой InstallShield. Это одиночный cab-файл, упакованный в msi-контейнер, а также набор из установочных файлов и cab-архива, также помещенный внутрь msi-файла (Microsoft Installer). Третий тип, использующий шифрование, этим распаковщиком не поддерживается.
InstallShield (by one exe-file) Unpacker 0.99
Less MSIerables также используется для извлечения файлов из MSI-контейнеров, но имеет графический интерфейс и может встраиваться в Проводник Windows. Кроме извлечения файлов показывает всю дополнительную информацию, содержащуюся в инсталляторе.
Less MSIerables 1.0.8
Orca MSI Editor — одна из составных частей пакета «Windows SDK Components for Windows Installer Developers» от MicroSoft. Скачать его отдельно можно здесь, так как ее разработка официально уже не поддерживается. Профессиональный инструмент, ориентированный больше на модификацию самого инсталлятора. С помощью Orca можно сделать многие интересные вещи, например, сразу прописать серийник в поля ввода, заменить текст лицензии, изменить дефолтные опции установки и так далее.
Orca MSI Editor 3.1.4000.1830
JSWare MSI Unpacker — одна из новых разработок. Позволяет просматривать и извлекать файлы, а также смотреть какие настройки инсталлятор вносит в реестр при установке. Всячески рекомендую к использованию.
JSWare MSI Unpacker
Остался последний вопрос: а как определить, с помощью какой программы был собран тот или иной инсталлятор? Ответить на этот вопрос помогут программы для анализа исполняемых файлов. Например, PEiD четко определяет инсталляторы как «Inno Installer 5.1.2 [Overlay]» или «Nullsoft PiMP Stub [Nullsoft PiMP SFX]», так что проблем с идентификацией и выбором нужного инструментария быть не должно.