![]() |
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс |
Новичку | Ссылки | Программирование | Интервью | Архив | Связь |
Восстановление импорта в AsProtect 2.XXОбсудить статью на форумеМассу крэкерских инструментов, видеоуроков и статей вы сможете найти на видеокурсе от нашего сайта. Подробнее здесь. Автор: BiT-H@ck <bit-hack@mail.ru> Здравствуйте, дорогие читатели, сегодня мы будем распаковывать AlterWind Log Analyzer Professional 3.0 (http://www.alterwind.ru/). А упакован он... Догадайтесь сами – AsProtect 2.ХХ. Данная программа написана на Visual C++ 7.0. Для нас это хорошо, т.к. нет VM (как определить, смотрите далее) и не надо восстанавливать таблицу инициализации (её нет в прогах на VC, только BCB, Delphi), но есть фишка с заменой call [IAT] на call aspr_proc. Вот это и будет целью нашей статьи.Инструментарий. OllyDbg 1.10 OllyScript 0.92 OllyScript Editor 1.0 beta 3 PeTools 1.5.656.2005 RC5 ImpRec 1.6 План наших действий: 1. Лирическое отступление. 2. Поиск ОЕР. 3. Узнаём, как отличить call`ы (испорченные аспром) 4. Находим способ определения реального адреса call`а. 5. Пишем скрипт для восстановления кода. Лирическое отступление. Стремление Солодовникова сделать так, чтобы код программы нельзя было получить “просто так” понятно. Он старается как можно сильнее его привязать к самой защите, чтобы без него код был не полноценен или просто не работоспособен. За последние пару лет он сделал много шагов к осложнению восстановления кода программы: применил VM, применил процедуру динамического получения адресов импорта, при этом патчится код, etc. Ну а людям, желающим всё же получить работоспособный код программы, приходится ломать головы, над автоматизацией восстановления кода. Именно этому и посвящена данная статья. Поиск ОЕР. Грузим программу в OllyDbg и используем скрипт для поиска ОЕР. Мы на ОЕР. ОЕР=004D7011, скрипт вывел, что VM нет, этот способ определения присутствия VM один из многих, приведу ещё один: доходим до ОЕР (неважно каким способом) и смотрим, где мы сейчас находимся (в какой странице памяти), если это динамическая память, то на 50% это вм, чтобы убедиться на все 101% нужно слегка разобраться, что да как в коде, на который мы попали. Узнаём, как отличить call`ы. Берём первый же испорченный call (его можно найти после дампа и восстановления импорта, просто запустите программу и где она упадёт, там и будет call): 004E037C E8 7FFCA500 CALL 00F40000 Сразу видно, что он ведёт в динамическую память. Определить это просто, взгляните на карту памяти и посмотрите, где заканчиваются секции файла: ![]() Т.е. call можно идентифицировать по адресу, на который он переходит. Сейчас надо только понять, как формируется адрес перехода. Смотрим на первый байт инструкции. Смотрим на следующий DWORD. Ага, всё понятно – это относительный call. Вот схема относительного call`а: Байт инструкции call (относительный) Смещение от следующей за call`ом инструкции E8 XXXXXXXX Пример (кусок кода из программы): ![]() Первой строкой показан относительный call. Он отталкивается от адреса первого байта следующей инструкции, которая у нас XOR. Т.е. отсчёт ведётся от XOR. Сколько байт отсчитывается? Смотря на байты call`а видно, какие байты отвечают за кол-во байт для прыжка, у нас 00A5FC7F (байты в памяти хранятся в перевернутом по байту состоянии). Для получения адреса, на который ведёт call, достаточно добавить смещение (получено из байт call`а) к адресу команды, следующей за call`ом. Если полученный адрес выходит за пределы файла в памяти – это call aspr. На этом можно закончить про то, как можно отличить call`ы. Находим способ определения реального адреса call`а. Берём оригинальный файл, грузим в OllyDbg, доходим до ОЕР. Идём к call aspr. Делаем New Origin Here. А теперь трейсите до тех пор, пока не поймёте, где виден реальный адрес функции. А я ничего не стал искать, перевёл eip на call aspr_code,поставил бряк на VirtualAllocEx, F9 и стал просматривать стек. В стеке я встретил такие строки: ![]() Т.е. по адресу esp+5C лежит реальный адрес, т.е. VirtualAllocEx вызывается после получения реального адреса функции. На самом деле этот способ придумал не я, а какой-то чел с форума кряклаба, кажись nice. Пишем скрипт для восстановления кода. А сейчас то, на что я потратил пол ночи. Скрипт для восстановления call`ов. Я его приложил к статье, дабы её не захламлять. Это всё. Вот только мне интересно, почему стандартный поисковик в OllyScript не хочет работать? Ну не хочет – как хочет, напишем свой, из-за него скрипт не сильно начинает тормозить. После отработки скрипта дампим программу заново и восстанавливаем импорт, будет одна неопознанная функция, вот её код: 00D16D84 push ebp 00D16D85 mov ebp,esp 00D16D87 mov edx,[ebp+C] 00D16D8A mov eax,[ebp+8] 00D16D8D cmp eax,[D28458] // DWORD value: FFFFFFFF 00D16D93 jnz short 00D16D9E 00D16D95 mov eax,[edx*4+D28458] // DWORD value: FFFFFFFF 00D16D9C jmp short 00D16DA5 00D16D9E push edx 00D16D9F push eax 00D16DA0 call 00D0577C // = kernel32.dll/0198/GetProcAddress 00D16DA5 pop ebp 00D16DA6 retn 8 Изучив код функции понятно, что если передаваемый параметр не равен 0FFFFFFFF, тогда будет выполнена GetProcAddress. Ещё аспр иногда юзает функции подобного вида для получения имени пользователя. Запускаем дамп с восстановленной табличкой и он опять падает:( Грузим программу в олю, смотрим что к чему. Падает здесь: 0040F631 MOV EBX, DWORD PTR DS:[EAX+4] 0040F634 MOV EAX, DWORD PTR DS:[62848C] 0040F639 LEA EDX, DWORD PTR DS:[EAX+1] 0040F63C LEA ESP, DWORD PTR SS:[ESP] 0040F640 MOV CL, BYTE PTR DS:[EAX] ;Тут падает eax=00D03A29 0040F642 INC EAX 0040F643 TEST CL, CL 0040F645 JNZ SHORT 0040F640 Прога пытается обратиться к бывшему коду аспра:( Смотрим, что было в оригинале, там по адресу 00D03A29: ![]() Очень смахивает на попытку чтения имени пользователя, если его длина равна 0, программа не зарегистрирована. Смотрим, откуда берётся адрес в eax, он берётся из 62848C. Теперь находим в проге пустое место (0000000) и вписываем туда свое имя, а по адресу 62848C вписываем адрес своего имени. Сохраняем, запускаем, идём в about, надпись trial version пропала, но имени как не было, так и нет %( Проверим скрипт на другой проге. Я взял AsMonitor. Она тоже защищена аспром. И тоже (кажись) написана на Visual C. Тут используется другой метод порчи кода, call`ы исправляется не прямо в коде, а исправляются переходники типа 004071E4 FF25 84F35200 JMP DWORD PTR DS:[52F384] Стал: 004071EC E8 0F8EAE00 CALL 00EF0000 Т.е. сначала call из программы ведёт на jmp, а jmp на нужную ячейку в IAT. Аспр как всегда всё испортил. Раз тут другой метод, восстанавливать надо не call`ы, а jmp`ы, то и скрипт надо другой. Ещё одна особенность: если найти адрес, на который должен бы переходить call (оригинальный адрес функции) и поискать его в IAT, то его там нет, придётся дописывать. Ещё один скрипт приложен в статье. За сим разрешите откланяться. Свою задачу я выполнил. Если есть вопросы/предложения, мыльте на bit-hack@mail.ru. Scripts: calltocall.osc calltojmp.osc OEPFinder.osc Скачать: asimprec_scripts.rar Приветы to: -= ALEX =-, Ara, sanniassin (именно три этих пипла - -= ALEX =-, Ara, sanniassin помогали мне в написании статьи, скажите им спасибо), NUCLEuS, Mario555, nice, dragon_gor, WELL, всем форумчанам кряклаба, помогавшим в написании статьи. Комментарии к статье: Восстановление импорта в AsProtect 2.XX Бродяга 02.11.2005 01:09:08 Руль. Даешь такой же обзор аспровой VM ! --- Pavel_ 27.05.2006 19:46:52 :) Картинки переп3утаны :) долго смотрел на стек и думал где в нем конец секции памяти :))) --- Материалы находятся на сайте https://exelab.ru ![]() |
Вы находитесь на EXELAB.rU |
![]() |