Главная » Статьи » Распаковка |
Распаковка. Общий подход
Содержание: 1. Вступление 2. Нам понадобится 3. Ликбез Стек4. Приступим к распаковке В поисках OEP5. Ссылки 1. Вступление Попав внутрь запакованной программы, начинающий cracker начинает волноваться и паникивать, ведь там так одиноко без WinAPI, а кругом вражески настроенные опкоды. И вроде незачто зацепиться, однако это не так, и распокавать программу на самом деле очень просто. Сегодня я расскажу о том как это делается. 2. Нам понадобится а) Отладчик OllyDbg и плагины к нему (CommandBar, OllyDump, OllyScript). б) Редактор PE-файлов - LordPE в) Программа для восстановления импорта - ImpRec 3. Ликбез а) Стек Чего я не знаю о стеке? - спросит читатель. Push - pop и все дела, ан нет, им можно пользоваться и более умело. В регистре esp храниться адрес вершины стека, тоесть параметра помещённого в стек последним. К примеру: Код:
А как обратится к 5 через esp? Опятьтаки спросит читатель. Для начала мы сохраним esp в ebp, но так как ebp используем не мы одни, то нужно сохранить его. Код:
Также необходимо понимать, что стек растёт от старших адресов к младшим. Это очень важно!!! Так как 5h было помещено раньше чем все остальное, то и адрес у него будет больше. Также мы знаем, что размер одного кадра стека равен 4h. Следовательно чтобы обратится к пяти надо к ebp прибавить 2h*4h. Код:
А параметры помещенные после сохранения ebp? Просто теперь вычетаем номер желаемого параметра помноженный на размер кадра. mov eax,dword ptr [ebp-1*4h] - первый параметр, запушенный после ebp И во всём этом легко убедится. Напишем простую программу на MASM, где будет следующий код: Код:
Открываем в Olly, убеждаемся в моей правоте, читаем далее. б) Несколько слов о RVA Термины: Entry Point (EP) - точка входа в программуТе самые несколько слов: Очевидно, что OEP не равно EP, иначе вы бы эту статью не читали. Его мы будем искать. Но дело не в этом, нам понадобится RVA OEP. Как вы, думаю, догадались нужно просто из VA OEP вычесть ImageBase. Из полного виртуалного адреса VA вычитаем адрес самого начала (даже не программы) файла, и получется RVA. RVA OEP = VA OEP - ImageBase Ну вот к примеру, мы нашли OEP равный 00402000, а ImageBase равно 00400000, тогда RVA OEP будет равно 2000. Где мы найдём ImageBase - это второстепенный вопрос, о котором я расскажу позже. в) Способы адресации Сейчас я хочу поговорить с вами о том, как передать управление в другую часть кода. Первый способ: Код:
Код:
Третий способ: Код:
Четвёртый способ: Код:
Пятый способ: Код:
Эти примеры могут нам пригодится при нахождении OEP. 4. Приступим к распаковке а) В поисках OEP Общая часть: Резонно будет предположить, что код, распаковывающий прогамму, во время распаковки тоже использует стек, следовательно после его выполнения он будет восстанавливать esp. И неприменно обратится к адресу esp-4, на него мы и ставим break. В OllyDbg это делается так: в CommandBar пишем "hr esp-4" enter. А дальше? А дальше, после восстановления регистров и стека, перейдёт на OEP, который мы подсмотим. Пример с UPX 0.89.6 - 1.02 / 1.05 - 1.24 -> Markus & Laszlo: Запускаем программу по F9. Break срабатывает, и мы видим следующие инструкции: Код:
В этом месте программа восстанавливает все регистры и передаёт управление коду по адресу xxxxxxxx. Скорее всего это и есть переход на OEP. Проверим. Жмем F8 и попадаем сюда. Код:
Явно не код распоковщика, а следовательно распакованной программы. Тоесть jmp - это переход на OEP программы. Обращение к esp-4 может встерчаться много раз в программе, вот для чего я привел способы адресации. Вам придётся нераз трасировать программу (F7), чтобы распознать где заканчивается код распаковщика и начинается код программы. upx_script1.txt Код:
Можно короче(если убрать коменты и cmt, конечно): upx_sript2.txt Код:
Пример с ASPack 2.12 -> Alexey Solodovnikov: Запускаем программу по F9. Break срабатывает, и мы видим следующие инструкции: Код:
Жмём по F8, jnz срабатывает и передаёт управление на push, конструкция push-retn представлена в способах адресации. push xxxxxx retn можно представить так: jmp xxxxxx После перехода на xxxxxx, мы видим стандартный код начала программы на MASM (На C, Delphi посмотрите в отладчике. Меняться будут ток адреса да параметры.): Код:
aspack.txt Код:
Пример с FSG 2.0 -> bart/xt: Запускаем программу по F9. Break срабатывает, на этот раз всё сложнее прога остановилась на каком то mov, явно не конец распаковки, ещё F9 и ещё пока не окажемся здесь: Код:
Мне так кажется, что переход на OEP будет тут (JMP DWORD PTR DS:[EBX+C]). Ставим бряк на этот jump, а старый на esp-4 снимаем, это можно опятьтаки сделать в CommandBar'е. Command: hd esp-4. Жмём F9 и останавливаемся на jump, F8. Да, так оно и есть, и мы на OEP. FSG.txt Код:
Пример с PECompact 2.x -> Jeremy Collake: Запускаем программу по F9. Однако бряк не срабатывает, прога останавливается, возникает исключительная ситуация, возможно это антиотладка( в данной статье нас это не интересует). Смотрим на вершину стека: Код:
Просто прога ставит SEH. Не думаю, что нас что-либо может остановить. Shift-F9, Shift-F9, F9 и т.д, пока не найдём что-нибудь интересное. Меня заинтересовал следующий код: Код:
Трейсим и действительно в eax OEP. Готово!! PECompact.txt Код:
Пример с winupack_029b С ним всё было как то необычно, бряк сробатывал в ненужных местах. Затем прога вылетела. Shift-F9 и я оказался в какой то функции, F9 опять вылетела, далее опять в функцию, я посмотрел на стек и увидел там адрес функции GetCommandLineA. Проделал эти операции ещё раз, там появилась следущая функция, распаковывает или востанавливает (не разбирался) IAT, блеснуло у меня в голове, Жал Shift-F9,F9 пока не дошёл до ExitProcess, далее тассировал более аккуратно и вследствии вышел на OEP. Можно было ещё разобрать пару пакеров, но у меня на компе больше нет. Но идея, думается мне, понятна. Если Вы не поняли как находится OEP, то просто юзайте скрипты для Olly, благо в инете их много, для различных пакеров и протектеров. б) Сбрасываем дамп Итак мы перешли на OEP, что делать дальше? Пока ничего не трогаем. Просто заходим в плагины > OllyDump > dump debugged process. Жмём "Dump". Всё готово!!! Можете пользоваться. в) Восстановление импорта Для восстановления импорта нам нужно узнать ImageBase. Запускаем LordPE, жмём PE Editor и выбираем нашу программу, смотрим ImageBase. Закрываем LordPE. Запускаем нашу программу(всмысле запакованную), открываем ImpRec, выбираем нужный процес. В поле OEP пишем RVA OEP, подсчитаный по формуле представленной выше. Жмём IAT AutoSearch для автоматического поиска таблицы импорта, и видим сообщение, что скорее всего адрес найден. Теперь жмём Get Imports и видим, что в списке появлись используемые dll и функции. Жмём Fix Dump и выбираем наш дамп. Ну вот и всё. Возможные вопросы: Q: Половина функций в библиотеке опознана, а другая нет!! Что делать? A: Выбери неопределённую функцию, и нажми на правую клавишу. Выбери "Disassembly / HexView", выделяй, например "comctl32.dll/002D/ImageList_Destroy", и теперь на обе клавиши. Выберай Get Import. Всё, функция определена, библиотека тоже. Q: А если много таких функций? A: Выбираем все, на правую клавишу, Trace level1 (Disassm). Результат налицо. Q: А если всётаки не хочет определяться? A: Выбираем любую функцию, на правую клавишу, Advanced commands > Get API Call > OK, теперь отсекаем всё не нужное. 5. Ссылки cracklab.ru wasm.ru (Об упаковщиках в последний раз) _____________________________________________ Author: Taha Date: 22.11.2006 | |
Просмотров: 5551 | Рейтинг: 5.0/2 |
Всего комментариев: 0 | |