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

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


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

Исследование ключа USB Guardant

Обсудить статью на форуме

Хорошая подборка видеоуроков, инструментов крэкера, книг и статей - здесь.

Автор: Canakau <dumpBack@mail.ru>

Пару недель назад принесли мне прогу, защищенную USB ключиком, с надписью
Guardant. Начал искать по нему информацию, ее оказалось очень мало.
Качать SDK много и дорого. Нашел интересную статью от Hex’а, но она освещала
лишь вопросы реализации АПИ. Из какой-то еще статьи узнал, что драйвер
открывается не через OpenFile, а через _lopen. Решил пройти с нуля. Что и
получилось. Вот, теперь хочу поделиться методой. Понятно, что это далеко не
идеал и универсализма здесь нет, но может кому-то это поможет.
Et sic.
Дано - Программа "Цифровая Фотограмметрическая Система" от ЦНИИГАиК
на www.vingeo.com вы можете ее скачать. программа запускается без ключа
в ДЕМО режиме.
В комплексе у меня было 3 защищенных программы, везде метода была абсолютно
одинакова. В данном примере рассматривается модуль triada.exe. Адреса
у меня и у вас могут отличаться, т.к. даже в моем дистрибутиве каждой прог-
раммы было не менее 2-х версий.
Все запаковано Aspack’ом 2.12. С этим проблем не возникло - AspackDie все
снял.
Для начала в айсе ставим бряк на _lopen. После того, как нас выбросило,
жмем F11 и оказываемся в теле АПИ. Убираем бряку на всякий случай.
И идем до момента, когда код ,разбавленный jmp, прекратится. в данном случае я
прошел 8 RET’ов и вышел сюда - 4F6C68
Грузим IDA и переходим на найденный адрес
Видим следующее:

 CODE:004F6C58 call sub_402D9C
 CODE:004F6C5D mov eax, ds:dword_59E120
 CODE:004F6C62 add eax, 8566783h
 CODE:004F6C67 push eax
 CODE:004F6C68 call sub_4FF7BC
 ^^^^^
 CODE:004F6C6D mov ds:word_5A3940, ax
 CODE:004F6C73 mov eax, ds:dword_5A00EC
 CODE:004F6C78 mov byte ptr [eax], 0
 CODE:004F6C7B cmp ds:word_5A3940, 0
 
Итак, мы видим, что процедуре передается всего один параметр - число.
по адресу, на который она ссылается находится:

 CODE:004FF7BC sub_4FF7BC proc near ; CODE XREF: sub_4F6250+F1p
 CODE:004FF7BC ; sub_4F6BD0+98p ...
 CODE:004FF7BC jmp loc_4FEF02
 CODE:004FF7BC sub_4FF7BC endp
и затем, попадаем в код, щедро разбавленный jmp’ами. Делаем предположение, что
попали в АПИ. Поскольку изучение его внутренностей не есть первоочередная задача,
возвращаемся назад, к первому Call.
Делаем еще одно смелое предположение - передаваемое число - есть пароль ключа.
Попробуем проверить это. Видим, что число 8566783h складывается с числом
по адресу 59E120h

 DATA:0059E120 dword_59E120 dd 0D961FCD8h ; DATA XREF: sub_4F6250+E6r
 ^^^^^^
 DATA:0059E120 ; sub_4F6BD0+8Dr ...
 DATA:0059E124 dword_59E124 dd 0C1734F1Bh ; DATA XREF: sub_4F7564+E4r
 DATA:0059E124 ; sub_4F7564+140r
 
Складываем, получаем 11B8645Bh запоминаем.
Ищем получившееся число, и не находим его. Ищем число 8566783h и находим
8 вхождений. Все они перед вызовами ф-ций. Похоже, что предположение оказалось верным.
Смотрим, куда ведут эти ф-ции. Оказывается, они ведут в один блок JMP’ов.
Уверенность в правильности предположения о пароле и об АПИ крепнет.
смотрим, что мы нашли

 1)
 CODE:004F6336 mov eax, ds:dword_59E120
 CODE:004F633B add eax, 8566783h
 CODE:004F6340 push eax
 CODE:004F6341 call sub_4FF7BC
 2)
 CODE:004F6CE7 push esi
 CODE:004F6CE8 push 2
 CODE:004F6CEA push 22h
 CODE:004F6CEC mov eax, ds:dword_59E120
 CODE:004F6CF1 add eax, 8566783h
 CODE:004F6CF6 push eax
 CODE:004F6CF7 call sub_4FF7CB
 3)
 CODE:004F6D50 mov eax, ds:dword_5A02A8
 CODE:004F6D55 push eax
 CODE:004F6D56 push 1
 CODE:004F6D58 push 1Fh
 CODE:004F6D5A mov eax, ds:dword_59E120
 CODE:004F6D5F add eax, 8566783h
 CODE:004F6D64 push eax
 CODE:004F6D65 call sub_4FF7CB
 4)
 CODE:004F6D70 mov eax, ds:dword_59FF94
 CODE:004F6D75 push eax
 CODE:004F6D76 push 4
 CODE:004F6D78 push 16h
 CODE:004F6D7A mov eax, ds:dword_59E120
 CODE:004F6D7F add eax, 8566783h
 CODE:004F6D84 push eax
 CODE:004F6D85 call sub_4FF7CB
итак, одна процедура с 1-м параметром, вероятно с паролем, является проверкой наличия
ключа. С ключем все процедуры возвращают eax=0, без оного - eax=1. И 2-я процедура,
с одним и тем же кол-вом и типом передаваемых параметров и всегда
сопровождающаяся найденным числом. 2-я ф-ция очень сильно напоминает чтение
памяти - адрес, куда читать, сколько прочитать и откуда, затем пароль.
с 2-мя параметрами (сколько и откуда) проанализировав пары 2-22 1-1F 4-16
предполагаем следующий порядок параметров - ReadMem(Password: DWORD; Addr:WORD;
Count:WORD; Dest:Pointer); В описании ключа сказано, что память у ключа - 256 байт.
При наличии ключа можно прочитать его память следующим образом -
в айсе делаем бряку на любой из подходящих процедур. Точнее на первом push’е.
Например на
CODE:004F6D75 push eax
жмем F10, пишем d eax. правим eip опять на 004F6D75h, в eax пишем 0. F10. eip=004F6D75h
eax=0FFh, F10. параметры длины и начала внесли, теперь eip=004F6D7A. и жмем F10
до выполнения процедуры. Поймали содержимое памяти ключа.
Теперь осталось дело за малым. Заставить программу работать. Скажу сразу - в моем
случае было достаточно ненулевых значений и eax=0 при выходе из АПИ. значения можно
подогнать такие, какие хочешь (по дате истечения лицензии, кол-ву включенных модулей
и серийник ключа).
Для того, что бы программа заработала, необходимо дать ей то, что она хочет. Для
этого надо во первых написать небольшую программку, подклеить к ней дамп памяти ключа,
вставить ее в тело программы и перенаправить вызовы от реального АПИ к вашему.
рисуем эмулятор. Говорю сразу - за АСМ не пинать. пианист играет, как умеет.
первая ф-ция совсем проста.

 popravka equ XXXXXXXh ; поправка на адреса.
 IsKey:
 pop eax
 mov dword ptr [retadr+popravka],eax
 pop eax
 mov eax,dword ptr [retadr+popravka]
 push eax
 xor eax,eax
 ret
 ;Вторая немногим сложнее
 ReadMem:
 pop eax
 mov dword ptr [retadr+popravka],eax
 
 pop eax ; skip password
 pop eax ; address
 mov byte ptr [addr+popravka],al
 pop eax
 mov byte ptr [len+popravka],al
 pop eax
 mov dword ptr [buf+popravka],eax
 mov eax,dword ptr [retadr+popravka]
 push eax
 ;----------------------------------- variables are defined
 pusha
 pushf
 movsx ebx,byte ptr [addr+popravka]
 lea esi,dump+ebx+popravka
 mov edi,dword ptr [buf+popravka]
 movsx ecx,byte ptr [len+popravka]
 cld
 rep movsb
 popf
 popa
 xor eax,eax
 ret
 retadr: dd 0
 addr: db 0
 len: db 0
 buf: dd 0
 dump: 
 ;---------------------------------------------------------
 
скомпилировав это, или вбив вручную в hiew’е к этому надо подклеить дамп.
после берем или LordPE или ProcDump, открываем препарируемую прогу, находим
секцию .Code и находим в самом конце секции кучу нулей. и
вставляем туда эмулятор (предварительно внеся поправку на адреса) и
перенаправляем jump’ы АПИ на свои процедуры. Все. Программа готова к запуску.
В заключение могу сказать, что этот случай был очень легким, а мог бы быть
много-много тяжелее...

С уважением
Canakau
dumpBack@mail.ru


Обсуждение статьи: Исследование ключа USB Guardant >>>


Комментарии к статье: Исследование ключа USB Guardant

Andron 20.12.2004 18:30:52
Молодец, рулишь.
---
геодез 28.02.2005 14:53:30
Прога не от ЦНИИГАиК - разработчики : НПП “Геосистема” и ООО “Аналитика”

---

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



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


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