![]() |
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс |
Новичку | Ссылки | Программирование | Интервью | Архив | Связь |
Исследование CPU Indicator 1.1Обсудить статью на форумеМассу крэкерских инструментов, видеоуроков и статей вы сможете найти на видеокурсе от нашего сайта. Подробнее здесь. Привет! Вот для вас еще одно (третье) мое практическое руководство. На этот раз наш пациент - монитор загруженности проца. Неплохая софтина от PY Software. Какая схема защиты? Да все тот же имя/серийник. Честно, когда я устанавливал в SoftIce бряки, чтобы начать исследование этой проги, я думал, что бессонная ночь мне обеспечена. Не представляете, каково было мое разочарование, когда четыре минуты спустя программа на моем компе уже была полностью зарегистрирована и готова к употреблению. Пришлось мне самому обеспечивать себя бессонной ночью и разбираться с алгоритмом генерации ключа, о чем я вам сейчас и расскажу. Итак, готовим стандартный набор инструментов: * SoftIce (как же без него :)) * Пойло (обязательно) * Сигареты (по вкусу) и в путь!!! Как всегда, начинаем с заполнения полей регистрации левыми данными, устанавливаем в SoftIce бряк (breakpoint) на hmemcpy, давим на форме регистрации бутон "Ok"... и вваливаемся в дебаггер... Теперь натискните 7 раз на F12, чтобы войти в код CPU Indicator'а; а потом еще разков пяток, чтобы перейти к этому коду: :004388B8 mov eax, [ebp-0C] ;в EAX идет введенное имя :004388BB lea edx, [ebp-08] :004388BE call 00435A14 ;вызов процедуры генерации серийника :004388C3 mov eax, [ebp-08] ;загружает ПРАВИЛЬНЫЙ серийник в EAX! :004388C6 push eax ;тащит правильный серийник в стек! Все, на этом взлом можно считать проведенным успешно. Установив курсор на строку :004388C6 push eax и введя "d eax <ввод>", вы получите номер регистрации. Но на этот раз не будем останавливаться на достигнутом и напишем-таки свой генератор, предварительно исследовав алгоритм создания ключа. Установив курсор на строку :004388BE call 00435A14 давите F8, чтобы проследовать в процедуру: :00435A14 push ebp :00435A15 mov ebp, esp . . . пропустим все ненужное дерьмо . . . :00435A43 lea eax, [ebp-08] ;тащит в ЕАХ смещение введенного нами имени :00435A46 mov edx, 00435AE0 ;!!! в EDX - строку "CPU Indicator v. 1.1" !!! :00435A4B call 00403B74 ;к имени прибавляем вышеприведенную строку. ;далее я буду называть ее "именной" строкой :00435A50 mov eax, [ebp-08] :00435A53 call 00403B6C ;находим длину "именной" строки... :00435A58 push eax ;...и кидаем ее в стек . . . :00435A61 pop edx :00435A62 call 00431E20 ;* * * Вот оно!!! Процедура вычисления с/н * * * :00435A67 mov [ebp-04], eax ;в ЕАХ - с/н, но записаннй наоборот. ;СЕРИЙНИК - содержимое ЕАХ в hex-виде !!! . . . Дальше идут процедуры "переворачивания" строки и другой не очень интересный кал. Сконцентрируем все наше внимание на вызове "call 00431E20". Туда то мы сейчас и отправимся. Давите F8 и... :00431E20 push ebp :00431E21 mov ebp, esp :00431E23 add esp, -1C :00431E26 mov [ebp-12], dx . . . пропустим неинтересное и перейдем сразу к делу: :00431E49 mov [ebp-1A], ax ;в АХ - длина "именной" строки :00431E4D mov word ptr [ebp-06], 0001 ;начальное значение счетчика (первый символ) ;Внимание! Начало цикла генерации :00431E53 movzx eax, word ptr [ebp-06] ;в ЕАХ пхает порядк. номер текущего символа :00431E57 mov edx, [ebp-10] ;"именную" строку - в EDX :00431E5A mov al, [eax+edx-01] ;в AL - текущий символ :00431E5E mov [ebp-07], al :00431E61 push ax ;сохраняем... :00431E63 push bx :00431E65 push cx ;...регистры :00431E67 push dx :00431E69 mov dx, [ebp-02] ;восстанавливаем DX (в первый раз - нуль) :00431E6D mov bx, [ebp-04] ;восстанавливаем BX (в первый раз - нуль) :00431E71 mov cx, [ebp-06] ;СХ - счетчик, содержит порядк. номер текущего символа :00431E75 xor ax, ax ;обнуляем АХ :00431E78 mov al, [ebp-07] ;в AL - текущий символ :00431E7B xor dx, ax ;производим над ним... :00431E7E mul cl ;...соответствующие логические... :00431E80 add bx, ax ;...и математические операции :00431E83 mov [ebp-02], dx ;сохраняем значение DX для следующего круга :00431E87 mov [ebp-04], bx ;сохраняем значение BX для следующего круга :00431E8B pop dx ;восстанавливаем... :00431E8D pop cx :00431E8F pop bx ;...регистры :00431E91 pop ax :00431E93 inc word ptr [ebp-06] ;увеличиваем счетчик :00431E97 dec word ptr [ebp-1A] ;уменьшаем длину строки :00431E9B jnz 00431E53 ;конец цикла генерации :00431E9D mov ax, [ebp-04] :00431EA1 mov [ebp-0C], ax :00431EA5 mov ax, [ebp-02] :00431EA9 mov [ebp-0A], ax :00431EAD mov eax, [ebp-0C] ;"перевернутый" с/н: старшее слово - последнее значение DX ;после операции MUL CL, а младшее - последнее значение BX ;после операции ADD BX, AX :00431EB0 mov esp, ebp :00431EB2 pop ebp :00431EB3 ret Что ж, давайте подведем итог и сделаем вывод на основе проведенного исследования. 1. Введенное нами имя записывается в верхнем регистре (заглавными буквами) 2. К имени прибавляется строка "CPU Indicator v. 1.1". Так, если вы ввели имя "JOHN", то в итоге получите строку "JOHNCPU Indicator v. 1.1" 3. Производим над каждым символом строки логические (xor) и математические (mul) операции. По окончании цикла, в EAX формируется "перевернутый" серийник: Т. е. содержимое EAX выглядит так: "xx yy zz ww", где в слово "zzww" помещается значение BX, в "xxyy" - DX, таким образом, "xx" постоянно остается нулем. Скажите почему? 4. Серийник выглядит как последовательность байт и вводится в hex-виде. 5. Чтобы получить окончательный с/н, содержимое АХ надо "прочитать" наоборот, т. е. если в ЕАХ у нас число "0035ABEF", то правильный с/н: "EFAB3500" Ну, разжевал как мог. Даже наверное слишком :) Ниже привожу код процедуры генерации ключа, написанный на Delphi. Может он не оптимален, но работает: ----------------- вырезать -------------------------------------- procedure Generate(); const Str='CPU Indicator v. 1.1'; var RegStr, Ost :dword; UsName, NamStr, Serial:string; NamStrLen, i :integer; Sym, C :byte; B, D :word; MemB, MemD :variant; begin for i:=1 to Length(UsName) do UsName[i]:=UpCase(UsName[i]); //меняем буквы имени на заглавные NamStr:=UsName+Str; //к имени приписываем строку "CPU Indicator v. 1.1" NamStrLen:=Length(NamStr); //находим длину полученной строки RegStr:=0; HexVal:=''; MemB:=0; MemD:=0; // начало цикла генерации ключа for C:=1 to NamStrLen do begin Sym:=byte(NamStr[C]); //Берем символ для преобразований D:=MemD; B:=MemB; asm xor ax, ax mov al, Sym xor D, ax mul C add B, ax //в конце цикла в переменной "B" будет сидеть 1-я половина ключа end; MemB:=B; MemD:=D end; //конец цикла генерации ключа //записываем будущий серийник (в десятичном виде) в переменную RegStr: asm mov bx, B // <------+ mov dx, D // |--- меняем местами байты первой половины с/н... mov byte ptr RegStr+3, bl // <------| mov byte ptr RegStr+2, bh // <------| mov byte ptr RegStr+1, dl // ...и дописываем вторую половину end; //а сейчас переведем его в правильный (шестнадцатиричный) формат: while RegStr>0 do begin ost:= RegStr mod 16; RegStr:=RegStr div 16; case ost of 10: Serial:='A'+Serial; 11: Serial:='B'+Serial; 12: Serial:='C'+Serial; 13: Serial:='D'+Serial; 14: Serial:='E'+Serial; 15: Serial:='F'+Serial; else Serial:=IntToStr(Ost)+Serial; end; end; end; ----------------- вырезать -------------------------------------- Все, успехов!!! Надеюсь вам было понятно :) Возникнут вопросы - мыльте. P. S. Да, вашим домашним заданием будет сломать AnySpeed от все тех же PY Software. Она использует похожую схему защиты. Keep on cracking... Date :05.09.2002 Author:Cryo E-mail:cryo@cydem.zp.ua Материалы находятся на сайте https://exelab.ru ![]() |
Вы находитесь на EXELAB.rU |
![]() |