Современные решения

для защиты Windows приложений

и восстановления исходного кода
Автор: vins. Дата публикации: 21.10.2004

Распаковка ALEXPROT v1.0 beta 2


Цель:
ALEXPROT v1.0 beta 2

Инструменты:
OllyDbg
ImpRec

В принципе, там ничего сложного нету. Я так понял там главное неудобство  это команда RDTSC.
Команда RDTSC выполняет чтение счетчика меток реального времени (TSC –Time Stamp Counter) содержимое которого инкрементируется с каждым тактом процессорного ядра. Поэтому ее можно использовать для получения количественной оценки работы программы, или участка кода.

Вот кусок кода без jmp’ов:

007C0B6E 83C4 04 ADD ESP,4 007C0B71 0F31 RDTSC 007C0B73 8BD8 MOV EBX,EAX 007C0B82 83C4 04 ADD ESP,4 007C0B85 8BCA MOV ECX,EDX 007C0B94 83C4 04 ADD ESP,4 007C0B97 0F31 RDTSC 007C0B99 2BC3 SUB EAX,EBX 007C0BA8 83C4 04 ADD ESP,4 007C0BAB 1BD1 SBB EDX,ECX 007C0BAD 0F31 RDTSC 007C0BAF 03C3 ADD EAX,EBX 007C0BBE 83C4 04 ADD ESP,4 007C0BC1 13D1 ADC EDX,ECX 007C0BC3 0F31 RDTSC 007C0BC5 2BC3 SUB EAX,EBX 007C0BD4 83C4 04 ADD ESP,4 007C0BEB 83C4 04 ADD ESP,4 007C0BEE 1BD1 SBB EDX,ECX 007C0BFD 83C4 04 ADD ESP,4 007C0C00 85D2 TEST EDX,EDX 007C0C02 ^75 D6 JNZ SHORT 007C0BDA ;плохой прыжок


чтоб пройти этот код нужно просто по jmp’ам добрать до TEST EDX,EDX( выделяем jmp нажимаем Enter, тоже самое с call’ами), поставить туда бряк F2 и запустить прогу.

Начнем

Запускаем программу, в Options->Debugging Options->Exceptions снимаем галки с Ignore following exceptions. Запускаем прогу. Она останавливается несколько раз на:

00хххххх FFFF ??? ; Unknown command

пропускаем это по Shift+F9.
Потом будет:

007C13C2 3300 XOR EAX,DWORD PTR DS:[EAX] 007C13C4 83C4 04 ADD ESP,4 007C13C7 FFE3 JMP EBX

нажимаем 1 раз Shift+F9 и смотрим что твориться в секции Code. Если код расшифровался, то ищем там что то похожее на:

004095AC FF25 1E180200 JMP DWORD PTR DS:[2181E] 004095B2 FF25 0CBA1000 JMP DWORD PTR DS:[10BA0C] 004095B8 FF25 321D4F01 JMP DWORD PTR DS:[14F1D32] 004095BE FF25 1C33A700 JMP DWORD PTR DS:[A7331C] 004095C4 FF25 40025700 JMP DWORD PTR DS:[570240] 004095CA FF25 A6983F00 JMP DWORD PTR DS:[3F98A6]

это по идее должны быть jmp’ы на Api функции.
Теперь ставим на этот код бряк на запись (Memory, on write), пропускаем экспетишены по Shift+F9
И останавливаемся на:

007C0C05 8901 MOV DWORD PTR DS:[ECX],EAX 007C0C07 83C7 04 ADD EDI,4 007C0C0A FECB DEC BL 007C0C0C 58 POP EAX

Тут происходит запись переходников. В ecx адрес куда пишем, eax адрес переходника.
Теперь ищем место где в eax записывается это адрес. Идем по F8 до:

007C09C0 83C7 02 ADD EDI,2 007C09C3 57 PUSH EDI 007C09C4 FF95 C8244000 CALL DWORD PTR SS:[EBP+4024C8] 007C09CA 85C0 TEST EAX,EAX 007C09CC 0F85 AC000000 JNZ 007C0A7E

это место нам пригодиться для восстановления импорта. Запоминаем адрес.
Идем дальше и доходим до:

007C0A96 57 PUSH EDI 007C0A97 FFB5 7C244000 PUSH DWORD PTR SS:[EBP+40247C] 007C0A9D FF95 C4244000 CALL DWORD PTR SS:[EBP+4024C4] KERNEL32.GetProcAddress 007C0AA3 33DB XOR EBX,EBX

тут идет получение адресов Api.
Дальше доходим до:

007C0B58 50 PUSH EAX ; shell32.ShellExecuteA 007C0B59 8B0F MOV ECX,DWORD PTR DS:[EDI] 007C0B5B E8 62090000 CALL 007C14C2 007C0B60 60 PUSHAD

В этом Call’е реальные адреса меняются на переходники.
Так, теперь мы знаем важные места:
1) 007C14C2 тут создаются переходники
2) 007C0C05 тут они вписываются
3) 007C09C0 меняется библиотека

Перезапускаем прогу и останавливаемся на 1 месте.
В eax и ecx как раз то что о чем я уже говорил, адрес api и адрес jmp [xxxx]. В конце этой процедуры
в eax уже адрес переходника, а так как он нам не нужен, мы туда напишем свой код:

007C14C2 60 PUSHAD ;оставляем 007C14C3 BA 04B04000 MOV EDX,40B000 ;тут будет наш импорт 007C14C8 66:8305 C4147C00 04 ADD WORD PTR DS:[7C14C4],4 ;это для увеличения 40B000 на 4 чтоб записывать адреса. 007C14D0 8902 MOV DWORD PTR DS:[EDX],EAX ;пишем адрес апи 007C14D2 8BC2 MOV EAX,EDX ;теперь в еах адрес где лежит Api 007C14D4 8901 MOV DWORD PTR DS:[ECX],EAX ;пишем его куда надо 007C14D6 61 POPAD ;все на место 007C14D7 C3 RETN

Ставим бряк на второй адрес и запускаем.
Тормозим:

007C0C04 61 POPAD 007C0C05 8901 MOV DWORD PTR DS:[ECX],EAX ; это надо

занопить так как мы уже туда
записали то что нужно.

007C0C07 83C7 04 ADD EDI,4

Пониже будет:
007C0C22 0F84 DE000000 JE 007C0D06 ;это выход

Ставим бряк на 3 адрес.
Останавливаемся. У нас уже есть нормальные адреса в импорте, но нужно еще добавить разделение между разными либами. Тут вызывает LoadLibrary , и нам надо добавить сюда свой код. Смотрим куда мы придем по джампам и запоминаем. Теперь пишем :

007C09C0 66:8305 C4147C00 04 ADD WORD PTR DS:[7C14C4],4 добавляем пропуск 007C09C8 83C7 02 ADD EDI,2 ;это старый код 007C09CB 57 PUSH EDI 007C09CC FF95 C8244000 CALL DWORD PTR SS:[EBP+4024C8] 007C09D2 85C0 TEST EAX,EAX 007C09D4 0F85 A4000000 JNZ 007C0A7E 007C09DA 60 PUSHAD 007C09DB E9 96000000 JMP 007C0A76 то место куда мы пришли по джампам 007C09E0 90 NOP

Почти все. Теперь снимаем все бряки и ставим бряк на 007C0D06, это то куда мы прыгнем на выходе. Запускаем, тормозим на:

007C0D06 E8 97060000 CALL 007C13A2

заходим в этот call. Ставим бряк сразу на

007C13C4 83C4 04 ADD ESP,4 007C13C7 FFE3 JMP EBX

запускаем, пропускаем экспетишены. После JMP EBX попадаем на кучу rdtsc. Прокручиваем в низ и ищем что ни будь похожее на выход:

007C11DA 8B85 AD234000 MOV EAX,DWORD PTR SS:[EBP+4023AD] 007C11E0 894424 1C MOV DWORD PTR SS:[ESP+1C],EAX 007C11E4 61 POPAD 007C11E5 FFE0 JMP EAX 007C11E7 60 PUSHAD 007C11E8 8BF0 MOV ESI,EAX 007C11EA 8BF9 MOV EDI,ECX 007C11EC FC CLD 007C11ED 33C9 XOR ECX,ECX

ставим бряк на JMP EAX запускаем.
После этого jmp оказываемся в месте где идет выполнение спертых байт. Так как там почти все команды повторяются, можно найти левые, это и будут спертые. Чтоб быстрее, можно сделать трейс: открываем Command line, пишем tc eip== адрес последней инструкции, у нас это:
007E0C5E -E9 A45EC2FF JMP alexprot.00406B07
значит tc eip==007e0c5e. Когда брякнется жмем много раз на “–“ смотрим на регистры и на стек, на той команде где будет меняться это и будет спертая команда, в нашем случае это
007E07EF 6A 00 PUSH 0
Жмем F8 и мы на OEP теперь восстанавливаем спертые байты, дампим и прикручиваем импорт.

Может, можно было и по другому, но это первое что пришло мне в голову
Усе

Комментарии

Добавил: WELL Дата: 21.10.2004

Взяли заломали Лёхин протектор. Редиски =)

Добавил: Anonymous Дата: 21.10.2004

DrGolova автораспаковщик даже написал, а китайцы тутор написали по распаковке

Добавил: vins Дата: 21.10.2004

Понятно хоть написано? :)

Добавил: Anonymous Дата: 22.10.2004

Да, все отлично


Добавление комментария


Ваше имя (на форуме):

Ваш пароль (на форуме):

Комментарии могут добавлять только пользователи,
зарегистрированные на форуме данного сайта. Если Вы не
зарегистрированы, то сначала зарегистрируйтесь тут

Комментарий: