Автор: vins. Дата публикации: 21.10.2004
Цель:
ALEXPROT v1.0 beta 2
Инструменты:
OllyDbg
ImpRec
В принципе, там ничего сложного нету. Я так понял там главное неудобство  это команда RDTSC.
Команда RDTSC выполняет чтение счетчика меток реального времени (TSC –Time Stamp Counter) содержимое которого инкрементируется с каждым тактом процессорного ядра. Поэтому ее можно использовать для получения количественной оценки работы программы, или участка кода.
Вот кусок кода без jmp’ов:
чтоб пройти этот код нужно просто по jmp’ам добрать до TEST EDX,EDX( выделяем jmp нажимаем Enter, тоже самое с call’ами), поставить туда бряк F2 и запустить прогу.
Начнем
Запускаем программу, в Options->Debugging Options->Exceptions снимаем галки с Ignore following exceptions. Запускаем прогу. Она останавливается несколько раз на:
пропускаем это по Shift+F9.
Потом будет:
нажимаем 1 раз Shift+F9 и смотрим что твориться в секции Code. Если код расшифровался, то ищем там что то похожее на:
это по идее должны быть jmp’ы на Api функции.
Теперь ставим на этот код бряк на запись (Memory, on write), пропускаем экспетишены по Shift+F9
И останавливаемся на:
Тут происходит запись переходников. В ecx адрес куда пишем, eax адрес переходника.
Теперь ищем место где в eax записывается это адрес. Идем по F8 до:
это место нам пригодиться для восстановления импорта. Запоминаем адрес.
Идем дальше и доходим до:
тут идет получение адресов Api.
Дальше доходим до:
В этом Call’е реальные адреса меняются на переходники.
Так, теперь мы знаем важные места:
1) 007C14C2 тут создаются переходники
2) 007C0C05 тут они вписываются
3) 007C09C0 меняется библиотека
Перезапускаем прогу и останавливаемся на 1 месте.
В eax и ecx как раз то что о чем я уже говорил, адрес api и адрес jmp [xxxx]. В конце этой процедуры
в eax уже адрес переходника, а так как он нам не нужен, мы туда напишем свой код:
Ставим бряк на второй адрес и запускаем.
Тормозим:
занопить так как мы уже туда
записали то что нужно.
Пониже будет:
Ставим бряк на 3 адрес.
Останавливаемся. У нас уже есть нормальные адреса в импорте, но нужно еще добавить разделение между разными либами. Тут вызывает LoadLibrary , и нам надо добавить сюда свой код. Смотрим куда мы придем по джампам и запоминаем. Теперь пишем :
Почти все. Теперь снимаем все бряки и ставим бряк на 007C0D06, это то куда мы прыгнем на выходе. Запускаем, тормозим на:
заходим в этот call. Ставим бряк сразу на
запускаем, пропускаем экспетишены. После JMP EBX попадаем на кучу rdtsc. Прокручиваем в низ и ищем что ни будь похожее на выход:
ставим бряк на JMP EAX запускаем.
После этого jmp оказываемся в месте где идет выполнение спертых байт. Так как там почти все команды повторяются, можно найти левые, это и будут спертые. Чтоб быстрее, можно сделать трейс: открываем Command line, пишем tc eip== адрес последней инструкции, у нас это:
007E0C5E -E9 A45EC2FF JMP alexprot.00406B07
значит tc eip==007e0c5e. Когда брякнется жмем много раз на “–“ смотрим на регистры и на стек, на той команде где будет меняться это и будет спертая команда, в нашем случае это
007E07EF 6A 00 PUSH 0
Жмем F8 и мы на OEP теперь восстанавливаем спертые байты, дампим и прикручиваем импорт.
Может, можно было и по другому, но это первое что пришло мне в голову
Усе
Распаковка 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 Да, все отлично |
Добавление комментария |