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

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


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


Обсуждение статьи: Исследование CPU Indicator 1.1 >>>


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



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


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