Розпаковуємо Perl-скрипти, оброблені PerlApp - Misc

perlapp

розпаковуємо

Отже визначаємо, що з стиснення використовується бібліотека zlib, причому досить стара версія - 1.1.4. Звичайно, можна почати шукати, де саме у файлі зберігаються стислі дані, але мені захотілося піти іншим шляхом. Отже, нам знадобиться якийсь дизассемблер, наприклад, IDA або OllyDbg, а також пара піддослідних exe-файлів, бажано упакованих різними версіями PerlApp, щоб однозначно визначити сигнатуру функції розпакування. Функція розпакування елементарно шукається, якщо орієнтуватися по рядку з версією (1.1.4), але, очевидно, функції досить можуть відрізнятися від версії до версії:

розпаковуємо

perlapp

Однак, якщо звернути увагу на хвіст функції, то ми побачимо, що там зустрічається стійка послідовність байтів, яка також є унікальною для файлу в цілому. Це досить зручно, та й нас цікавить вказівник на буфер з розпакованими даними, який вона повертає.

Як видно зі скріншотів, вона може трохи відрізнятися (всього 2 байти), але це не проблема, тому що ніхто не заважає реалізувати пошук по масці. Тепер нам треба якось перехопити дані, які розміщуються в EAX в кінці функції, щоб потім записати їх у файл. Один із варіантів - організувати в кінці функції JMP у тіло своєї функції, в ній виконати затерті стрибком інструкції, записати вміст буфера, куди треба і повернутися назад, але знову ж таки мені захотілося піти трохи іншим шляхом. Замість створення "трампліну" я просто переписую інструкцію RETN інструкцією INT3, яка передає управління в VEH, в ньому вміст буфера записується у файл, змінюються регістри EIP та ESP (через структуру PEXCEPTION_POINTERS) і програма продовжує працювати далі,ніби нічого не сталося і замість INT3 було виконано інструкцію RETN.

Тепер наведу код, який реалізує те, що я описав вище. В результаті вийде DLL, яку потрібно прописати в імпорти exe-файлу зі скриптом, або підвантажити її іншим способом. Для початку позначимо інклюди, пару констант і створимо порожню функцію, що експортується: