Как распаковать упакованный PE-файл без потери оригинальной структуры

Как распаковать упакованный PE-файл без потери оригинальной структуры

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

Это не про «найти и нажать кнопку». Это про понимание, как устроен PE-загрузчик, как работает упаковщик, и как аккуратно отмотать его слои, не повредив оригинал. Я покажу, как это делается на практике — без магии, без «вот тут вставь скрипт и всё заработает». Только проверенные шаги, реальные ловушки и то, что работает в бою.

Что значит «без потери структуры»?

Упаковщик — это не просто сжатие. Он:

  • перемещает код и данные в новую секцию (обычно .text или .pack);
  • переписывает адреса импорта (IAT — Import Address Table);
  • меняет заголовок PE: размеры секций, точки входа, характеристики;
  • может шифровать ресурсы, таблицы импортов, даже секции .rsrc;
  • иногда добавляет анти-дебаггинг и анти-анализ.

Если ты просто смотришь в памяти после распаковки и копируешь «дамп» — ты получишь файл, который запустится, но не будет работать везде. Почему? Потому что:

  • импорты сбиты — приложение падает при запуске на другой системе;
  • рекомпилированные секции не имеют правильных атрибутов — антивирус ругается;
  • таблица импортов не восстановлена — не работает GetProcAddress;
  • подпись цифровая — если ты изменил байты, она сломается, и Windows не запустит файл.

Тебе нужен не дамп. Тебе нужен восстановленный PE-файл — такой же, как был до упаковки, только без обфускации.

Как это делается: пошагово

Это не одноразовая операция. Это цикл: анализ → запуск → отслеживание → восстановление → проверка. Повторяй, пока не будет идеально.

  1. Определи упаковщик. Используй PEiD, Detect It Easy или Exeinfo PE. Не полагайся только на них — они ошибаются. Смотри на секции: если есть .UPX — это UPX. Если .mpack — значит, майнеры. Если .text с нулевыми правами — это почти всегда кастомный упаковщик. Запомни: упаковщик — это не просто «UPX», а алгоритм. У каждого свой способ восстановления.
  2. Запусти в отладчике. Используй x64dbg или OllyDbg. Установи точку останова на kernel32!ExitProcess и на GetModuleHandleA. Запусти. Когда программа начнёт выполнять «распаковщик» — ты увидишь, как он копирует код в память, перезаписывает IAT, меняет точку входа. Смотри, где он делает jmp на распакованный код — это и есть настоящая точка входа (OEP).
  3. Запомни OEP. Когда ты видишь, что код стал читаемым — значит, распаковка завершена. Остановись. В x64dbg: кликни по адресу в регистре EIP, скопируй его. Это — оригинальная точка входа. Не запоминай адрес в памяти — запоминай смещение относительно базы образа. Потом это понадобится.
  4. Сделай дамп памяти. В x64dbg: Right-click → Dump modified modules. Выбери процесс, нажми «Dump». Ты получишь файл в памяти — но он ещё не PE. Он просто кусок памяти. Нужно превратить его в настоящий PE-файл.
  5. Восстанови заголовок PE. Используй Scylla (или ScyllaHide для защиты от анти-дебага). Загрузи дамп в Scylla. Укажи:
    • адрес OEP — тот, что запомнил;
    • адрес IAT — найди его в памяти: после распаковки импорты становятся нормальными, ищешь массив адресов функций в секции .idata;
    • выбери «Rebuild PE» — это ключевое действие. Scylla перестроит заголовок, восстановит таблицы импортов, вычислит хэши, поправит размеры секций.
  6. Сохрани файл. Нажми «Fix Dump». Получишь новый PE-файл. Проверь его в PE-bear или PE Explorer: секции должны совпадать с оригиналом по именам и размерам, импорты — полные, ресурсы — на месте.
  7. Проверь. Запусти новый файл. Если он работает — хорошо. Но проверь ещё:
    • размер файла — должен быть ближе к оригиналу, а не в 2–3 раза больше;
    • подпись — если оригинал был подписан, и ты хочешь сохранить эту подпись — её не восстановить. Это нормально. Но если ты делаешь анализ, а не распространение — это не критично;
    • импорты — открыть в PE-bear и убедиться, что все DLL и функции есть. Если где-то ??? — ты не восстановил IAT полностью.

Что выбрать: Scylla, ImpRec, или ручной подход?

Существует три основных подхода. Каждый — для своей ситуации.

Инструмент Когда использовать Плюсы Минусы
Scylla Кастомные упаковщики, UPX, Aspack, NSPack, большинство современных вредоносных упаковщиков Автоматически восстанавливает IAT, поддерживает x64, работает с дампами памяти, прост в использовании Не всегда правильно определяет размеры секций, может потерять ресурсы, если они зашифрованы
ImpRec Устаревшие упаковщики (UPX 1.x, PECompact), когда Scylla не справляется Хорошо работает с простыми IAT, понятный интерфейс, поддержка 32-бит Не работает с x64, не восстанавливает ресурсы, не умеет работать с кастомными секциями, устарел
Ручное восстановление Сложные упаковщики (VMProtect, Themida, Obsidium), когда автоматика не работает Полный контроль: можно восстановить любую структуру, включая подписи и ресурсы Требует глубоких знаний PE, занимает часы, рискованно — легко сломать файл

Если ты новичок — начинай с Scylla. Он 80% случаев решает. Если не справляется — пробуй ImpRec. Если и он не помог — значит, упаковщик сложный. Тогда — ручной подход. Но это уже не для «быстрого анализа». Это для глубокого исследования.

Частые ошибки — и почему они ломают файл

Эти ошибки делают даже опытные люди. И они приводят к тому, что файл «запускается», но потом падает, или антивирус его блокирует, или он не работает на другой системе.

  • Копируешь дамп памяти и забываешь восстановить IAT. Результат: файл запускается, но сразу падает на LoadLibrary или GetProcAddress. Потому что импорты — это адреса, а не имена. Без правильной таблицы — никаких вызовов.
  • Используешь адрес в памяти, а не смещение. OEP в памяти — это 0x00401234. Но когда ты восстанавливаешь файл, база образа может быть 0x00400000. Ты должен указать 0x1234 как смещение. Иначе Scylla запишет неправильный OEP — и файл не запустится.
  • Не проверяешь ресурсы. Многие упаковщики шифруют иконки, строки, DLL-ресурсы. Если ты не восстановил .rsrc — приложение может не отображать окна, или не загружать локализацию. Проверь в PE-bear: секция .rsrc должна быть непустой и иметь правильный размер.
  • Забываешь про секции. Упаковщик мог создать новую секцию .pack и убрать старую .text. Восстановленный файл должен иметь те же секции, что и оригинал. Если ты не восстановил .rdata — в файле не будет констант, и он сломается.
  • Пытаешься восстановить цифровую подпись. Это невозможно без приватного ключа. Если ты это сделаешь — ты получишь файл с битой подписью. Windows его не запустит. Игнорируй подпись. Ты анализируешь — не распространяешь.

Что делать в разных ситуациях

Ты не всегда работаешь с одним и тем же. Вот как действовать в разных сценариях.

  • Ситуация: ты анализируешь вредоносное ПО, нужно быстро понять, что оно делает — используй Scylla. Смотри на импорты: если есть WriteProcessMemory, CreateRemoteThread — это троян. Если RegSetValueEx и ShellExecute — это бэкдор. Достаточно распаковать и посмотреть импорты — не нужно восстанавливать ресурсы.
  • Ситуация: ты восстанавливаешь легальное приложение, которое упаковали для защиты — нужно сохранить всё. Тут уже Scylla не всегда хватит. Нужно ручное восстановление: вручную восстанавливать секции, копировать ресурсы из оригинального файла, вручную восстанавливать IAT по адресам в памяти. Используй IDA Pro + Hex-Rays для анализа распаковщика.
  • Ситуация: упаковщик — VMProtect или Themida — Scylla не поможет. Ты не распакуешь его за 10 минут. Тут нужен дебаггинг с отключением анти-дебага (ScyllaHide), идти по шагам, отлавливать момент, когда VM-код превращается в настоящий x86. Это может занять день. Но результат — полное восстановление структуры. Никаких «дампов» — только точный PE-файл.
  • Ситуация: файл упакован UPX, но Scylla не распознаёт — попробуй upx -d имя_файла.exe. UPX — это исключение. Он имеет собственный декомпрессор. Иногда проще использовать официальный инструмент, чем отлаживать дамп.

Как сделать идеально: лучшие практики

Вот что я делаю всегда — чтобы не потерять структуру:

  1. Сначала делаю бэкап оригинала. Без него — ты не вернёшься назад.
  2. Использую Scylla + x64dbg — это мой стандартный набор. Он работает в 90% случаев.
  3. Проверяю размеры секций в восстановленном файле. Они должны быть точно такими же, как в оригинале. Если секция .text была 0x1000 — в восстановленном файле она не может быть 0x2000. Это признак, что ты не восстановил всё.
  4. Сравниваю импорты с оригиналом. Если в оригинале было 15 импортов — в восстановленном тоже должно быть 15. Если меньше — Scylla не смог найти все адреса. Придётся вручную искать IAT в памяти.
  5. Проверяю подпись — если она была, я отмечаю, что её потерял. Это не ошибка — это норма. Если я восстанавливаю для анализа — мне не нужна подпись.
  6. После восстановления запускаю файл в анализаторе санитайзера — например, PE-sieve или Process Hacker. Они покажут, не осталось ли мусора в памяти, не скрыты ли секции.

Если ты сделал всё правильно — файл работает как оригинал, но без упаковки. Ты можешь его открыть в IDA, увидеть все функции, найти вызовы, понять логику. Без этого — ты просто смотришь на мусор.

Что делать дальше

Ты распаковал файл. Теперь у тебя есть чистый PE. Но это только начало. Теперь:

  • Открой его в IDA Pro — и начни анализировать. Ты увидишь настоящий код, а не обфускацию.
  • Если это вредоносное ПО — ищи ключевые вызовы: сетевые, файловые, реестровые.
  • Если это легальное приложение — проверь, не осталось ли анти-анализа в коде. Иногда упаковщик оставляет «хвосты».
  • Сохрани восстановленный файл с понятным именем: original_app_unpacked.exe. Не называй его dump.exe — ты потеряешь контекст.

Распаковка — это не конец. Это вход в настоящий анализ. Без неё ты не поймёшь, что происходит в файле. С ней — ты получаешь контроль.

Информация в этой статье предназначена только для образовательных и аналитических целей. Распаковка защищённых файлов может нарушать лицензионные соглашения или законы об авторском праве. Всегда действуй в рамках закона и с разрешения владельца ПО. Для юридически значимых задач — проконсультируйся с квалифицированным специалистом.

Оцените статью
PEFile — Безопасность и технологии простым языком