Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 12 ноября!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | 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 >>>


Комментарии к статье: Восстановление импорта в AsProtect 2.XX

Бродяга 02.11.2005 01:09:08
Руль.
Даешь такой же обзор аспровой VM !
---
Pavel_ 27.05.2006 19:46:52
:) Картинки переп3утаны :) долго смотрел на стек и думал где в нем конец секции памяти :)))
---

Материалы находятся на сайте https://exelab.ru



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS