Как распаковать упакованный PE-файл без потери оригинальной структуры
Ты работаешь с исполняемыми файлами — может, анализируешь вредоносный код, восстанавливаешь утерянный бинарник, или просто хочешь понять, как работает защищённое приложение. Ты нашёл PE-файл, который явно упакован: размер подозрительно мал, секции с непонятными именами, импорты сбиты, а IDA Pro показывает кучу jmp и мусорных инструкций. Ты знаешь: если просто снять обфускацию — потеряешь структуру. А без неё — никакой аналитики, никакого дебаггинга, никакого восстановления. Нужно распаковать, но сохранить всё: секции, импорты, ресурсы, таблицы, хэши, подписи. И не превратить файл в кашу.
Это не про «найти и нажать кнопку». Это про понимание, как устроен PE-загрузчик, как работает упаковщик, и как аккуратно отмотать его слои, не повредив оригинал. Я покажу, как это делается на практике — без магии, без «вот тут вставь скрипт и всё заработает». Только проверенные шаги, реальные ловушки и то, что работает в бою.
Что значит «без потери структуры»?
Упаковщик — это не просто сжатие. Он:
- перемещает код и данные в новую секцию (обычно
.textили.pack); - переписывает адреса импорта (IAT — Import Address Table);
- меняет заголовок PE: размеры секций, точки входа, характеристики;
- может шифровать ресурсы, таблицы импортов, даже секции
.rsrc; - иногда добавляет анти-дебаггинг и анти-анализ.
Если ты просто смотришь в памяти после распаковки и копируешь «дамп» — ты получишь файл, который запустится, но не будет работать везде. Почему? Потому что:
- импорты сбиты — приложение падает при запуске на другой системе;
- рекомпилированные секции не имеют правильных атрибутов — антивирус ругается;
- таблица импортов не восстановлена — не работает
GetProcAddress; - подпись цифровая — если ты изменил байты, она сломается, и Windows не запустит файл.
Тебе нужен не дамп. Тебе нужен восстановленный PE-файл — такой же, как был до упаковки, только без обфускации.
Как это делается: пошагово
Это не одноразовая операция. Это цикл: анализ → запуск → отслеживание → восстановление → проверка. Повторяй, пока не будет идеально.
- Определи упаковщик. Используй
PEiD,Detect It EasyилиExeinfo PE. Не полагайся только на них — они ошибаются. Смотри на секции: если есть.UPX— это UPX. Если.mpack— значит, майнеры. Если.textс нулевыми правами — это почти всегда кастомный упаковщик. Запомни: упаковщик — это не просто «UPX», а алгоритм. У каждого свой способ восстановления. - Запусти в отладчике. Используй x64dbg или OllyDbg. Установи точку останова на
kernel32!ExitProcessи наGetModuleHandleA. Запусти. Когда программа начнёт выполнять «распаковщик» — ты увидишь, как он копирует код в память, перезаписывает IAT, меняет точку входа. Смотри, где он делаетjmpна распакованный код — это и есть настоящая точка входа (OEP). - Запомни OEP. Когда ты видишь, что код стал читаемым — значит, распаковка завершена. Остановись. В x64dbg: кликни по адресу в регистре EIP, скопируй его. Это — оригинальная точка входа. Не запоминай адрес в памяти — запоминай смещение относительно базы образа. Потом это понадобится.
- Сделай дамп памяти. В x64dbg:
Right-click → Dump modified modules. Выбери процесс, нажми «Dump». Ты получишь файл в памяти — но он ещё не PE. Он просто кусок памяти. Нужно превратить его в настоящий PE-файл. - Восстанови заголовок PE. Используй
Scylla(илиScyllaHideдля защиты от анти-дебага). Загрузи дамп в Scylla. Укажи:- адрес OEP — тот, что запомнил;
- адрес IAT — найди его в памяти: после распаковки импорты становятся нормальными, ищешь массив адресов функций в секции
.idata; - выбери «Rebuild PE» — это ключевое действие. Scylla перестроит заголовок, восстановит таблицы импортов, вычислит хэши, поправит размеры секций.
- Сохрани файл. Нажми «Fix Dump». Получишь новый PE-файл. Проверь его в
PE-bearилиPE Explorer: секции должны совпадать с оригиналом по именам и размерам, импорты — полные, ресурсы — на месте. - Проверь. Запусти новый файл. Если он работает — хорошо. Но проверь ещё:
- размер файла — должен быть ближе к оригиналу, а не в 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 — это исключение. Он имеет собственный декомпрессор. Иногда проще использовать официальный инструмент, чем отлаживать дамп.
Как сделать идеально: лучшие практики
Вот что я делаю всегда — чтобы не потерять структуру:
- Сначала делаю бэкап оригинала. Без него — ты не вернёшься назад.
- Использую Scylla + x64dbg — это мой стандартный набор. Он работает в 90% случаев.
- Проверяю размеры секций в восстановленном файле. Они должны быть точно такими же, как в оригинале. Если секция
.textбыла 0x1000 — в восстановленном файле она не может быть 0x2000. Это признак, что ты не восстановил всё. - Сравниваю импорты с оригиналом. Если в оригинале было 15 импортов — в восстановленном тоже должно быть 15. Если меньше — Scylla не смог найти все адреса. Придётся вручную искать IAT в памяти.
- Проверяю подпись — если она была, я отмечаю, что её потерял. Это не ошибка — это норма. Если я восстанавливаю для анализа — мне не нужна подпись.
- После восстановления запускаю файл в анализаторе санитайзера — например,
PE-sieveилиProcess Hacker. Они покажут, не осталось ли мусора в памяти, не скрыты ли секции.
Если ты сделал всё правильно — файл работает как оригинал, но без упаковки. Ты можешь его открыть в IDA, увидеть все функции, найти вызовы, понять логику. Без этого — ты просто смотришь на мусор.
Что делать дальше
Ты распаковал файл. Теперь у тебя есть чистый PE. Но это только начало. Теперь:
- Открой его в IDA Pro — и начни анализировать. Ты увидишь настоящий код, а не обфускацию.
- Если это вредоносное ПО — ищи ключевые вызовы: сетевые, файловые, реестровые.
- Если это легальное приложение — проверь, не осталось ли анти-анализа в коде. Иногда упаковщик оставляет «хвосты».
- Сохрани восстановленный файл с понятным именем:
original_app_unpacked.exe. Не называй егоdump.exe— ты потеряешь контекст.
Распаковка — это не конец. Это вход в настоящий анализ. Без неё ты не поймёшь, что происходит в файле. С ней — ты получаешь контроль.
Информация в этой статье предназначена только для образовательных и аналитических целей. Распаковка защищённых файлов может нарушать лицензионные соглашения или законы об авторском праве. Всегда действуй в рамках закона и с разрешения владельца ПО. Для юридически значимых задач — проконсультируйся с квалифицированным специалистом.
