R0 CREW

Neffarion :: 0xl1 :: Unpacking - ASProtect 1.23 RC4 - 1.3.08.24 (Перевод: Prosper-H)

0xl1 :: Unpacking - ASProtect 1.23 RC4 - 1.3.08.24

Введение

ASProtect – это один из самых сложных упаковщиков для среднего реверсера, поэтому я выбрал именно его, для нашего первого урока ручной распаковки. В дополнение вы узнаете, как восстановить IAT (Import Address Table), как вернуть украденные байты и как пользоваться журналом трассировки.

Информация о цели

Имя… iconmaker.exe [ download ]
Разработчики… King Lee, Fred Xu, Steven Bai
Инструменты… OllyDbg, ImportREC + ASProtect Plugin [ download ], LordPE [ download ]

Adficio

Когда вы применяете ASProtect, с программой происходят следующие вещи:

  • OEP (Original Entry Point, Оригинальная точка входа) искажается, EP (Entry Point, Точка входа) устанавливается ASProtect’ом.
  • Вызовы функций заменяются на джампы.
  • ASProtect берет определенное количество байтов из оригинальной программы и перемещает их.

Итак, что бы распаковать нашу цель, мы должны решить следующие задачи:

  • Найти OEP;
  • Восстановить IAT;
  • Вернуть украденные байты (если такие есть, потому как ASProtect не всегда их ворует).

Но прежде чем приступать к их решению, нам нужно немного перенастроить наш отладчик.

1 - a. Откройте OllyDbg b. Перейдите в "Options => Debugging options > Exceptions" c. Настройте этот диалоговое окно как тут:

Рисунок 1. Отладочные опции OllyDbg

2 - a. Перезапустите OllyDbg b. Пройдите в "File => Open" и загрузите iconmaker.exe c. Нажмите No в окне сообщения

Рисунок 2. Отказ от анализа кода

Нашим первым шагом будет поиск OEP, но для того, что бы найти его, нам нужно пройти через некоторую защиту упаковщика, которая будет всячески пытаться мешать нам. По этой причине, мы должны были перенастроить наш отладчик (Рис. 1). Суть данной перенастройки заключается в том, что бы проигнорировать множество различных исключений, которые “специально” генерирует ASProtect, тем самым пытаясь запутать реверсера. Каждая программа, защищенная ASProtect, проходит через несколько таких исключений (иногда до 30), перед непосредственным выполнением собственного кода. Нам же (для того, что бы выйти на OEP) нужно точно определить, как много исключений мы должны пройти, прежде чем начнется выполняться код программы. После чего нам нужно: перезапустить программу; пройти все исключения и остановиться на последнем, после которого начинается выполнение кода программы :slight_smile:

3 - a. Нажмите [SHIFT] + [F9] (приблизительно 27 раз) пока вы не дойдете до этого блока:

Рисунок 3. Завершающее исключение до выполнения кода программы

4 - a. Поставьте BP (Break Point, бряк) на первом RETN по адресу 0xA33A29 b. Нажмите Yes в окне сообщения

Рисунок 4. Подозрительный бряк

5 - a. Нажмите [SHIFT] + [F9] для остановки на нашем BP

Рисунок 5. Успешная остановка BP

Мы установили бряк на первый RETN последнего исключения, после прохождения которого начнется выполнение кода программы. Таким образом, мы загрузили все инструкции, которые ASProtect выполнял до сих пор в памяти. Другими словами мы пропустили все исключения, которые генерировал ASProtect до распаковки инструкций (кода) программы.

Заметка: данный прием, с установкой бряка на последнее исключение, может быть использован практически во всех, ваших будущих, подходах распаковки.

6 - a. Нажмите [ALT] + [M] b. Клацните правой кнопкой мыши по адресу 0x401000 и выберите "Set memory breakpoint on access"

Рисунок 6. Установка бряка на секцию .code (кода)

Установив еще один бряк (на этот раз в начале секции кода) мы можем точно определить то, что это точка входа нашей программы (Entry Point), потому что секция кода содержит собственно сам код программы, следовательно, очевидно, что первая инструкция это есть ничто иное как начало основной программы.

7 - a. Нажмите [F9]

Рисунок 7. Entry Point

Сейчас мы находимся в EP (но не OEP), которая была установлена ASProtect’ом. “set_app_type” это стандартная импортируемая функция, компилятора Microsoft Visual C++ 6.0, которая определяет тип приложения, т.е. “консольное” или “графическое” оно. Часто не важно, какое значение вернет эта функция. Нам достаточно уже самого присутствия, что бы мы знали, что:

  • EP нашей программы 0x43608F

Что бы определить, действительно ли у программы есть какие-либо украденные байты, нужно просто прокрутить вверх, на несколько строк выше от EP. Если они были украдены, то над EP вы увидите пустое поле, содержащее нулевые байты. Такое поведение характерно для всех версий ASProtect :slight_smile:

8 - a. Прокрутите вверх до адреса 0x43605C b. Нажмите [CTRL] + [A]

Рисунок 8. Украденные байты

В выше упомянутом поле мы имеем, в общем, 44 украденных байта, так что давайте вернем их обратно :slight_smile:

9 - a. Нажмите [CTRL] + [F2] b. Нажмите Yes в первом окне сообщения c. Нажмите No во втором окне сообщения d. Повторите шаги 4 – 6

Рисунок 9. Шаг 6

Теперь, когда мы установили наш бряк на секцию кода – запустим трассировку с условием.

10 - a. Нажмите [CTRL] + [T] b. Настройте диалоговое окно как тут и нажмите OK:

Рисунок 10. Настройка трассировки с условием

11 - a. Нажмите [CTRL] + [F11] и ждите около ~40 сек пока не дойдете до:

Рисунок 11. Бинго

Эти 5 инструкций характерная черта, иначе говоря, сигнатура, данной версии ASProtect, поэтому, дойдя до этой точки, мы успешно завершили трассировку в обозначенном нами участке (От переводчика: он имеете ввиду участок, который начинается с последнего бряка 0xA33A29 и заканчивается в EP 0x43608F).

12 - a. Пройдите в "View => Run Trace" b. Клацните правой кнопкой мыши в любом месте и убедитесь что "Highlight register => EBP" выбран

Рисунок 12. Подсветка регистра EBP

13 - a. Прокрутите в самый низ нашего трассировочного лога

Рисунок 13. Украденные байты

По поводу нашей трассировки: мы использовали трассировку с условием, что бы зафиксировать, в наш лог, тот момент, когда ASProtect начинает ‘распаковку’ программы в память.

Прокрутив в низ, трассировочного лога, мы найдем украденные байты, которые начинаются с адреса 0xA856C3 и заканчиваются адресом 0xA856FE (Рис. 13). Нам остается только почистить их от мусорных инструкций, которые добавил ASProtect. Не беспокойтесь, это делается элементарно, поскольку все мусорные инструкции JMP SHORT :wink:

Каждый раз, когда ASProtect, крадет байты из программы, в их начале всегда находится OEP (в данном случае по адресу 0x436062).

14 - a. Записываем каждую инструкцию, начинающуюся с 0xA856C3 по 0xA856FE, в блокнот, при этом игнорируя инструкции JMP SHORT

Рисунок 14. Украденные байты

Посмотрите на несколько линий ниже этой части (в 0xA85708), где вы увидите вызов, который помещает наш текущий EP (0x43608F) в стек. Наши украденные байты начинаются с 0x436062 (От переводчика: это он определил по рис. 8), а наш EP находится в 0x43608F. Давайте сначала изменим этот адрес на наш OEP (который начинается с начла украденных байт).

15 - a. Выделите 0xA85708 в журнале трассировки и нажмите [ENTER] b. Двойным щелчком выберите инструкцию по адресу 0xA85708 и assemble:

Рисунок 15. Восстановление OEP

Даже, несмотря на то, что мы определили наши украденные байты и восстановили OEP, мы еще не готовы восстановить украденные байты. Вначале нам нужно восстановить IAT, до того как мы сможем восстановить украденные байты, потому что плагин ImpREC ASProtect не может функционировать, если мы вначале восстановим украденные байты, а затем позже восстановим IAT (спасибо dqtln который указал на это!). Поэтому, сейчас нам нужно сделать дамп iconmaker.exe.

16 - a. Повторите шаг 9 b. Повторите шаг 7 и 8 c. Клацните правой кнопкой мыши на 0x436062 и выберите "New origin here"

Рисунок 16. Восстановление OEP

17 - a. Пройдите в “Plugins => OllyDump => Dump debugged process”
b. Настройте диалоговое окно как тут (затем нажмите Dump и сохраните файл как “dump.exe”):

Рисунок 17. Сохраняем дамп

18 - a. Сверните OllyDbg, откройте ImpREC и выберите нашу цель из выпадающего списка
b. В поле “OEP” установите “00036062”
c. Нажмите AutoSearch
d. Нажмите OK в окне сообщения

Рисунок 18. Подготовка imprec

19 - a. В поле “Size” установите “00001000”
b. Нажмите Get Imports

Рисунок 19. Загрузка импорта

20 - a. Нажмите Show Invalid
b. Клацните правой кнопкой мыши на одном из выделенных элементов и выберите “Trace Level1 (Disasm)”

Рисунок 20. Восстановление импорта (Level1)

21 - a. Нажмите Show Invalid (снова)
b. Клацните правой кнопкой мыши на одном из выделенных элементов и выберите “Plugin Tracers => ASProtect 1.23 RC4”

Рисунок 21. Авто-трассировка с помощью плагина

В логе вы увидите множество ошибок и только несколько успешных результатов, но не беспокойтесь: так и должно быть :slight_smile: Остальные “FThunks” из файла можно безопасно удалить, потому что они обычный мусор, который ASProtect добавил к программе.

22 - a. Нажмите Show Invalid (еще раз) b. Клацните правой кнопкой мыши на одном из выделенных элементов и выберите "Delete thunk(s)"

Рисунок 22. Удаление мусора

23 - a. Нажмите Fix Dump
b. Выберите dump.exe и нажмите Open

Рисунок 23. Сохранение нового дампа

ImpREC сохранил наш новый дамп как “dump_.exe”. Теперь нам нужно добавить украденные байты, в только что созданный “dump_.exe”, и вернуть работоспособность программе.

24- a. Закройте OllyDbg и откройте "dump_.exe" в новом экземпляре OllyDbg b. Выделите все инструкции из интервала 0x4360620x43608C, клацнув правой кнопкой мыши и выбрав "Assemble" c. Восстанавливайте каждую инструкцию, по отдельности, пока все инструкции не будут восстановлены d. Нажмите [CTRL] + [A]

Рисунок 24. Восстановление украденных байтов

25 - a. Клацните правой кнопкой мыши в любом месте и выберите “Copy to executable => All modifications”
b. Нажмите Copy All
c. Нажмите на “x” (От переводчика: т.е. нажать крестик или другими словами закрыть появившиеся окно) и затем нажмите Yes
d. Выберите “dump_.exe” и нажмите Save

Рисунок 25. Сохранение распакованной программы

26 - a. Откройте LordPE и нажмите Rebuild PE
b. Выберите “dump_.exe” и нажмите Open
c. Нажмите OK

Рисунок 26. Сохранение распакованной программы

Теперь, когда вы загрузите, программу в детектор упаковщиков, вы увидите, что все отлично восстановлено :slight_smile:

+Neffarion
http://www.0xNeff.eu

© Translated by Prosper-H from r0 Crew