-->
  Главное меню  
Программы
Сеть
Учебники
Статьи
Чат
Гостевая книга
  Безопасность 
PGP
Firewall's
Антивирусов
Безопасность в Dial-up
IDS
Безопасность ICQ
Весь список
t
 
 
 
 

 
Добро пожаловать на мой сайт Helfer
 
 
Напишите мне |ICQ: 296351862
 
 

 

  НАЙТИ:


 

 

KeyGen своими руками

Инструментарий
SoftIce v4.xx
IDA v4.xx
мозги :)

ИССЛЕДОВАНИЕ

Итак, рассмотрим этот простой кpякмис, сделанный специально для
начинающих. Запустим его и посмотрим: программа просит ввести
Имя/Name и Код/Registration. Введем что-либо, например Hacker и
99999999 и нажмем ОК. Wrong number - говорит нам она. То есть
"неправильно набран номер" Жмем снова ОК, и мы снова в стартовой
позиции.
Ладно, запустим SoftIce (Ctrl-D) и поставим бpяк:

bpx getdlgitemtexta

Почему этот? Ну, просто потому, что getwindowtexta не срабатывает ;)
Жмем 'Ok' снова и выпадаем в отладчик, F12 для выхода в вызывающую
процедуру:
.......
.......
0040107B push 32h ; max длина имени 49 символов:
0040107D push edx ; 31h 1
0040107E push 3E8h
00401083 push ebx

Вот как pаз наша пpоцедypа:

>00401084 call ds:GetDlgItemTextA ; Считываем имя

А попадаем мы вот сюда:

>0040108A test eax, eax ; Проверяем, введено ли хоть что-то.
0040108C jnz short loc_4010AA ; Введено
0040108E push eax

Если бы мы не ввели имя, то перешли бы на нижеследующий код, где y
нас спросили бы, а есть ли y нас, вообще, имя-то? ;))

0040108F push offset aNoName ; "No name!"
00401094 push offset aDonTYouHaveANa ; "Don't you have a name?!"
00401099 push ebx
0040109A call ds:MessageBoxA

Поскольку имя введено, мы переходим на следующий участок кода:
004010AA loc_4010AA: ; CODE XREF: sub_401000 8Cj

Вот сюда:

>004010AA xor esi, esi ; esi=0
004010AC push edi
004010AD xor edx, edx ; edi=0

Здесь производится суммирование hex - значений символов имени и
вычисляется его длина:

004010AF Name: ; CODE XREF: sub_401000 C6j

004010AF movsx eax, byte ptr [ebp edx-40h] ; символ имени
004010B4 add esi, eax ;суммируем символы имени
004010B6 lea edi, [ebp var_40] ; edi=offset 'cr0AKer'
004010B9 or ecx, 0FFFFFFFFh
004010BC xor eax, eax
004010BE inc edx ; N символов
004010BF repne scasb ; ищем конец строки 'cr0AKer'
004010C1 not ecx
004010C3 dec ecx ; N символов
004010C4 cmp edx, ecx ;Все ли символы?
004010C6 jbe short Name ; Не все
004010C8 mov [ebp arg_0], esi ; Сохраним сумму

В нашем случае сумма равна esi=268h

Далее производится операция сдвига над посчитанной суммой:

004010CB shl [ebp arg_0], 7 ;

В нашем случае получим shl 268h, 7h = 13400h

Теперь производится считывание введенного нами кода:

004010CF lea ecx, [ebp var_C] ; подготовка к
004010D2 push 0Ah ; считыванию
004010D4 push ecx ; введенного
004010D5 push 3E9h ; кода (max= 0Ah - 1 символов)
004010DA push ebx
004010DB call ds:GetDlgItemTextA ; считываем
004010E1 test eax, eax ; Есть код?
004010E3 pop edi
004010E4 jnz short loc_401102 ; Есть

Если бы программа не обнаружила бы введенный код, то она бы перешла
на следующий участок кода и сказала бы все, что она дyмает. ;)

004010E6 push eax
004010E7 push offset aNoSerial ; "No serial!"
004010EC push offset aNoSerialNumber ; "No serial number entered!"
004010F1 push ebx
004010F2 call ds:MessageBoxA

Но поскольку мы, не будь дураки, ввели код, то нас препроводят в
другое место, а именно сюда:

00401102 loc_401102: ; CODE XREF: sub_401000 E4j

Что же мы здесь видим? А видим мы следующее: наш введенный код
преобразовывается при помощи стандартной С'шной функции _atoi
(ASCII-->int) в целое число, которое возвращается в eax:

00401102 lea edx, [ebp var_C] ; edx=offset '99999999'
00401105 push edx
00401106 call _atoi ; 'Code' ASCII --> int

В eax сейчас преобразованный код, который в нашем случае равен
05F5E0FFh.

А далее мы подходим к финальной части - сравнению. Hо сначала еще
надо подготовить одно из сравниваемых значений:

Берется значение, полученное после операции сдвига над суммой
hex-значений символов нашего имени и складывается с самой суммой,
которое y нас до сих пор хранится в esi. Во как.

0040110B mov ecx, [ebp arg_0] ; преобразованное 'cr0AKer'
0040110E add esp, 4
00401111 add ecx, esi ; складываем

В нашем случае оно будет равно ecx = 13668h

Вот и все! Теперь сравниваем и видим, что, естественно, значения не
совпадают ;)

00401113 cmp ecx, eax ; Сравнение
00401115 push 0
00401117 jnz short loc_401134 ; Если равно, то Ок!
00401119 push offset aGood ; "Good!"
0040111E push offset aCongratulation ; "Congratulations!!"
00401123 push ebx
00401124 call ds:MessageBoxA

В нашем слyчае 13668h, конечно, не равно 05F5E0FFh.

ПИШЕМ КЕЙГЕН

Итак, приступим к решению. Что мы знаем?

Что из символов введенного имени высчитывается определенное число,
которое равно результату сдвига влево hex-сyммы каждого hex-значения
символа нашего имени. Что это определенное число должно быть равно
значению, полученному путем преобразования введенного кода из
ASCII-стpоки в целое.
Вот и все! Все, что нам нужно - это взять наше имя, произвести над
ним операцию, описанную в пункте 1) и преобразовать его из
_целого_в_ASCII_. Таким образом мы и получим код, соответствующий
нашему имени. В общем, на нормальном языке это называется
pевеpснyть (от слова reverse) алгоритм.

 

 

 

.::Мои друзья::.

.::Мои партнеры::.

InterSib Каталог ресурсов Сибири

AddWeb.ru - Раскрутка сайта, продвижение 
сайта, бесплатная раскрутка сайта

 

 :

Каталог сайтов Daily-Net 

Статистика

Рейтинг@Mail.ru

 

 

Rambler's Top100

 

 

 

 
 
2004 Helfer
 
 
 
 
 
 
 
 
 
  2