Когда вы сталкиваетесь с упакованным PE-файлом (исполняемым файлом для Windows), первая мысль часто бывает проста: «Нужно разархивировать этот exe, как zip-архив». Это фундаментальная ошибка. Если бы всё было так просто, антивирусы и защита от реверс-инжиниринга перестали бы существовать за один день. Упаковщики (UPX, Themida, VMProtect) используют сжатие и шифрование, но главное — они меняют структуру файла, чтобы скрыть оригинальный код.
Ваша задача — вернуть файл к его исходному состоянию (Original Entry Point, OEP), сохранив при этом все секции, таблицы импорта и структуру заголовков. Если вы просто запустите стандартный депакер, вы часто получите «битый» файл, который не запускается, или файл, у которого сломана таблица импорта (IAT). Статья ниже — это руководство для тех, кто хочет не просто «убрать упаковку», а получить чистый, работающий и структурно целостный файл для дальнейшего анализа.
- Почему стандартные методы часто проваливаются
- Инструментарий: что нужно иметь под рукой
- Шаг 1: Анализ и поиск точки входа (OEP)
- Шаг 2: Дамп файла из памяти
- Шаг 3: Восстановление таблицы импорта (IAT)
- Шаг 4: Финальная коррекция заголовков (Fixing the Header)
- Сравнение методов: как выбрать инструмент
- Частые ошибки, которые ломают файл
- Сценарии выбора стратегии
- Рекомендации по сохранению структуры
- Итог
Почему стандартные методы часто проваливаются
Большинство новичков используют автоматические депакеры из набора x64dbg или простую команду upx -d. В 80% случаев это работает. Но как только вы сталкиваетесь с самописными упаковщиками, полиморфным кодом или сложной анти-отладкой, автоматика сдаётся.
Главная проблема потери структуры кроется в механизме работы упаковщика. Он делает следующее:
- Взрезает оригинальный код (Original Import Address Table — OIAT) и прячет его.
- Создаёт новый, временный код, который при запуске распаковывает оригинал в память.
- Переписывает заголовок файла, меняя точку входа (Entry Point) на свой код.
- После распаковки в памяти оригинальный код уже не совпадает с тем, что записан на диске.
Если вы просто сохраните дамп памяти (скриптом или вручную), вы получите код в памяти, но без правильных заголовков, без корректных адресов импорта функций и без описания секций. Такой файл не запустится. Чтобы сохранить структуру, нужно не просто «вытащить код», а восстановить связи между сегментами файла и памятью.
Инструментарий: что нужно иметь под рукой
Вам не нужен набор из 50 программ. Вам нужен качественный арсенал, который покрывает разные сценарии. Вот база, которую реально используют на практике:
- x64dbg (или x32dbg). Это основной боевой инструмент. Отладчик, в котором вы будете искать точку входа, смотреть на регистры и делать дампы.
- Scylla (или ScyllaHide). Это критически важный инструмент. Именно Scylla отвечает за восстановление структуры импорта (IAT) после того, как вы выгрузите файл из памяти. Без неё файл будет существовать, но не будет знать, какие функции Windows ему нужны.
- ImportREC (Import Address Table Reconstruction). Старая классика. Если Scylla не справляется (что бывает с очень старыми или специфическими упаковщиками), ImportREC часто вытягивает ситуацию.
- PE-bear или CFF Explorer. Для визуального контроля заголовков. Вы должны видеть, что секции находятся на своих местах, а точка входа (AddressOfEntryPoint) указывает на начало кода программы, а не на код распаковщика.
- UPX (последняя версия). Даже если файл не упакован UPX, утилита полезна для тестирования и иногда имеет встроенные скрипты для снятия простых обёрток.
Шаг 1: Анализ и поиск точки входа (OEP)
Прежде чем запускать депакинг, нужно понять, что перед вами. Запустите файл в x64dbg. Если он сразу падает с ошибкой или вылетает, скорее всего, там стоит защита (анти-отладка). В этом случае вам нужно будет подключить плагин ScyllaHide (для x64dbg) или настроить его как DLL, чтобы скрыть факт отладки от программы.
Как найти Original Entry Point (OEP)? Это адрес первой инструкции оригинального кода. Есть два пути:
Способ А: Автоматический (через плагины)
В x64dbg есть плагин Find OEP. Он работает по алгоритму поиска «стек-дженерала» (ESP Hack). Суть в том, что упаковщик часто использует команду PUSHAD в начале, а затем, когда код распакован, должен восстановить стек, используя POPAD. Плагин следит за регистром ESP. Как только значение ESP становится таким же, как и сразу после старта — это сигнал, что вы достигли OEP. Установите брейкпоинт и ждите.
Способ Б: Ручной (для сложных случаев)
Возьмите файл и откройте его в PE-viewer (например, PE-bear). Сравните размер файла на диске и размер в памяти. Упаковщики часто оставляют секцию .text или .upx0 с нулевыми данными, чтобы туда «ложилась» распаковка. Если вы видите огромную пустую секцию, которая начинается с заголовка, и код в отладчике прыгает туда — вы близко к цели.
Ищите переходы JMP, которые ведут к началу кода. Часто упаковщик делает цикл распаковки, а в конце делает JMP на точку входа оригинала. Как только вы видите, что отладчик перешёл на код, который выглядит как логика вашей программы (а не как мусорные байты сжатия), а не просто прыгает, ставьте брейкпоинт.
Шаг 2: Дамп файла из памяти
Это самый ответственный момент. Вы нашли OEP, код оригинала полностью распакован в память, но на диске файл всё ещё сжат. Теперь нужно скопировать этот «живой» кусок кода из памяти программы в новый файл.
Здесь возникает главная ловушка. Если вы просто сохраните память, вы сохраните и «мусорные» участки, которые упаковщик использовал для распаковки, и, возможно, часть кода распаковщика, которая больше не нужна. Но самое страшное — вы сохраните файл без правильных заголовков.
Используйте плагин Scylla для дампа:
- В x64dbg откройте окно Scylla.
- В поле «Process» выберите ваш процесс.
- В поле «ImageBase» введите адрес, который вы видите в отладчике (обычно это 00400000 или 00000000, если ASLR включен, но Scylla подставит сам).
- Нажмите Get Info. Scylla просканирует память и попытается найти все секции и заголовки.
- Если Scylla определила секции (вы увидите список .text, .data и т.д.) и IAT (таблицу импорта), значит, структура сохранена корректно.
- Если вы видите, что IAT пустой или там странные адреса, значит, вы еще не на OEP или упаковка сложная.
Важно: если Scylla нашла IAT, но она выглядит неверно (например, одна функция повторяется 100 раз), значит, вы не дождались полной инициализации программы. Иногда программа инициализирует импорты не сразу при входе, а через несколько секунд. В x64dbg можно нажать Run и дать программе поработать пару секунд, а потом снова поставить на паузу и дернуть Scylla.
Шаг 3: Восстановление таблицы импорта (IAT)
Даже если вы сделали дамп, файл может не запускаться. Почему? Потому что на диске нет информации о том, какие функции Windows (например, MessageBoxA, OpenFile) использует программа. Упаковщик скрывал эти имена, чтобы усложнить анализ. Когда программа распаковывается в памяти, она загружает эти имена динамически.
Ваша задача — записать эти имена обратно в файл.
Процесс восстановления:
- В окне Scylla (после того, как вы нажали Get Info) перейдите на вкладку IAT.
- Если Scylla нашла IAT, она покажет адрес начала таблицы и размер. Нажмите Find OEP (если нужно) или просто Get Imports.
- Если список импортов пуст, попробуйте использовать функцию Auto Search или Find IAT. Scylla попытается просканировать память на наличие строк, похожих на имена DLL-функций.
- Важный момент: Если вы видите, что найдено 1000 функций, но 900 из них — это системные функции, а нужных вам мало, возможно, программа использует динамическую загрузку (GetProcAddress). Это частый случай для игр и защит. В таком случае вам придется вручную искать строки в памяти, которые содержат имена DLL, и добавлять их в список.
- После того как список импортов выглядит валидным (вы видите понятные имена:
kernel32.dll,user32.dll), нажмите Dump. - Scylla предложит сохранить файл. Сохраните его как
dumped.exe.
Теперь у вас есть файл, который физически существует на диске. Но он всё ещё «неправильный», потому что заголовки PE (Portable Executable) могут быть повреждены или не соответствовать памяти.
Шаг 4: Финальная коррекция заголовков (Fixing the Header)
Это то, что делает Scylla или ImportREC «под капотом», но иногда нужно сделать это вручную. После дампа файл часто имеет неверную длину секций или смещения. Если вы запустите такой файл, он может вылететь с ошибкой доступа.
Используйте утилиту PE-bear или CFF Explorer:
- Откройте
dumped.exe. - Проверьте секции. Убедитесь, что
SizeOfImageсоответствует реальной памяти. ЕслиSizeOfImageслишком мал, файл обрежет свой код. - Проверьте
AddressOfEntryPoint. Он должен указывать на начало секции.text(или аналогичной кодовой секции). Если он указывает на адрес, которого нет в секциях — файл сломан. - Если вы используете Scylla, сделайте это через её вкладку Fix Header. Она автоматически подправит заголовки под параметры дампа.
Сравнение методов: как выбрать инструмент
Не все упаковщики одинаковы. Выбор инструмента зависит от того, с чем вы столкнулись.
| Ситуация / Тип защиты | Рекомендуемый инструмент | Риски и нюансы |
|---|---|---|
| UPX (стандартный) Самый простой упаковщик. |
Утилита upx -d или Scylla. |
Низкий риск. Автоматика работает идеально. Ошибаться негде. |
| Сжатие без защиты (ASPack, PECompact) Файл просто сжат, нет анти-отладки. |
x64dbg + Scylla. | Средний риск. Важно поймать OEP сразу после распаковки. Если опоздаете, код может быть перезаписан. |
| Сложная упаковка (Themida, VMProtect) Имеет анти-отладку, виртуализацию кода. |
x64dbg + ScyllaHide + ручной поиск OEP. | Высокий риск. ScyllaHide обязателен. Часто требует ручного восстановления IAT, так как автоматика не видит скрытые вызовы. |
| Самописные упаковщики Случайный байт-код, нет стандартных сигнатур. |
Только ручной дамп (Manual Dump) + ImportREC. | Требует глубокого понимания ассемблера. Нужно писать скрипты для восстановления структуры. |
Частые ошибки, которые ломают файл
Даже опытные аналитики иногда теряют структуру файла из-за банальных ошибок. Вот список того, чего делать нельзя:
- Дамп в момент работы анти-отладки. Если программа поймала отладчик, она может начать подменять данные в памяти. Вы сохраните «лживый» код. Всегда проверяйте, работает ли анти-отладка (используйте ScyllaHide).
- Ранний дамп. Вы остановились на OEP, но программа еще не загрузила нужные DLL. Таблица импорта будет пустой или неполной. Дайте программе запуститься хотя бы до момента, когда она начнет открывать окна или файлы.
- Игнорирование секций. Некоторые упаковщики создают секцию
.rsrc(ресурсы) с ложными данными, а оригинальные ресурсы прячут в.text. Если вы просто удалите.rsrcили не восстановите её, файл потеряет иконки, меню, строки. - Неправильное выравнивание (Alignment). В заголовках PE есть параметры
FileAlignment(выравнивание на диске) иSectionAlignment(выравнивание в памяти). Если вы сохраните файл с неправильным выравниванием, загрузка Windows будет сбиваться. Scylla обычно сама подставляет правильные значения, но если вы правите заголовки вручную — будьте осторожны. - Использование старых депакеров. Инструменты, которые работали 5 лет назад, сейчас часто не справляются с современными упаковщиками из-за изменений в архитектуре Windows 10/11 (ASLR, DEP, CFG).
Сценарии выбора стратегии
В зависимости от вашей цели, подход к распаковке может меняться. Вот как действовать в разных ситуациях:
Сценарий 1: «Мне нужно просто запустить программу»
Вам не нужна идеальная структура. Вам нужно, чтобы файл работал.
Решение: Используйте автоматические депакеры (например, UPX -d или PEiD с депакерами). Если автоматика не помогает — используйте Scylla, чтобы сделать дамп и восстановить IAT. Не тратьте время на идеальное соответствие заголовков. Главное — работоспособность.
Сценарий 2: «Мне нужен исходный код для анализа»
Здесь важна структура. Вы планируете дизассемблировать файл в IDA Pro или Ghidra. Если структура сломана, IDA не сможет найти функции и ссылки.
Решение: Тщательный ручной дамп. Используйте Scylla, чтобы восстановить IAT. Затем откройте результат в PE-bear и проверьте каждый заголовок. Если Scylla не нашла IAT, используйте ImportREC с режимом «Search IAT» и вручную добавляйте проблемные функции. Только идеально восстановленный файл даст корректный дизассемблированный код.
Сценарий 3: «Файл не запускается после дампа»
Вы сделали дамп, сохранили, но файл вылетает.
Решение: Скорее всего, проблема в Relocations (релокациях) или IAT.
1. Проверьте, включена ли поддержка ASLR. Если файл был собран без ASLR, а вы запустили его на системе с ASLR, адреса могут не совпадать.
2. Попробуйте запустить файл в режиме совместимости.
3. Если ничего не помогает — дамп был сделан слишком рано. Вернитесь в отладчик, дайте программе прогрузиться еще 5-10 секунд и сделайте дамп снова.
Рекомендации по сохранению структуры
Чтобы гарантировать, что структура файла не потеряется, следуйте этому алгоритму:
- Всегда делайте бэкап оригинала. Перед любыми действиями скопируйте
file.exeвfile_original.exe. - Используйте Scylla для дампа и восстановления. Это золотой стандарт. Он берет на себя 90% рутинной работы по заголовкам.
- Проверяйте IAT. Откройте файл в IDA Pro или Ghidra. Если вы видите, что функции импорта называются
sub_401000вместоCreateFile, значит, структура импорта не восстановлена. Файл работает, но его структура потеряна. - Следите за размером секций. Размер секции
.textв заголовке должен совпадать с её размером в памяти (или быть кратным размеру страницы). - Не удаляйте секции. Если вы видите секцию
.relocили.rdata, не удаляйте их, даже если они кажутся лишними. Они могут быть нужны для работы динамической загрузки.
Итог
Распаковка PE-файла без потери структуры — это не просто «переименование файла». Это процесс восстановления связей между заголовком, секциями и таблицей импорта. Если вы просто удалите упаковщик, вы получите «мертвый» файл. Если вы восстановите структуру через Scylla и проверите заголовки, вы получите рабочий инструмент для анализа.
Ваш главный ориентир — таблица импорта (IAT). Если в вашем файле функции названы понятными именами, а заголовки都说 (говорят) правду о размерах секций, значит, задача выполнена. Если вы видите мусорные имена или несовпадение размеров — возвращайтесь в отладчик и ищите ошибку на этапе дампа.
Помните: лучшая защита — это не сложность упаковки, а отсутствие ошибок в её реализации. Но ваша работа как практика — найти эти ошибки и вернуть файлу его первоначальный вид.
