[CRACKING] [MISC.] [DOWNLOADS] [LINKS] [CONTACTS]

Взлом и защита программного обеспечения

 

 Самый простой KeyGen

OllyDbg v1.10 [1087 KB-ZIP] http://biocyborg.narod.ru/soft/OllyDbg110.zip 
mp3towave     [630  KB-ZIP] http://biocyborg.narod.ru/soft/mp3cinst.zip 

   Часто начинающие крэкеры задают вопрос, можно ли взломать программу без знания ассемблера. Действительно, существуют простейшие защиты, которые можно преодолеть вообще не имея понятия о командах ассемблера (что показано в  статье про взлом с помощью OgreGUI - примечание редактора от 12.12.2004).
   Регистрационные ключи также можно вытащить с помощью отладчика, бездумно трассируя процедуру проверки регистрационных данных в поисках последовательностей символов, похожих на рег. номер. 
   Но, как показывает практика, в большинстве случаев авторы программ не такие уж и простофили и поэтому при взломе более или менее серьезной защиты одним лишь методом тыка по функциональным клавишам в отладчике не обойтись. Необходимо знать хотя бы основы ассемблера. Все вышесказанное подтверждается при исследовании защиты программы mp3TOwave.
   Откроем исполнимый файл в OllyDbg, запустим программу (F9), и отправимся регистрироваться. В поле "Name" введём любое имя, а поле "Enter Code" - 123456. Возвращаемся в отладчик.
   Жмём комбинацию Ctrl+N и в появившемся окне с заголовком "Names in mp3towave" устанавливаем точку останова на GetDlgItemTextA (подсвечиваем строку с именем функции, затем клик на ней правой кнопкой->Set breakpoint on every reference).
   Теперь в окне программы жмём "Register!". Отладчик прервёт выполнение программы здесь:

00407D8D  8B1D 2C124100     MOV EBX,DWORD PTR DS:[<& USER32.GetDlgItemTextA >]
00407D93  8D8C24 1002000>   LEA ECX,DWORD PTR SS:[ESP+210]
00407D9A  68 00040000       PUSH 400 
00407D9F  51                PUSH ECX 
00407DA0  68 F8030000       PUSH 3F8 
00407DA5  56                PUSH ESI 
00407DA6  C68424 2002000>   MOV BYTE PTR SS:[ESP+220],0 
00407DAE  FFD3              CALL EBX
00407DB0  8D5424 10         LEA EDX,DWORD PTR SS:[ESP+10]
00407DB4  68 00020000       PUSH 200
00407DB9  52                PUSH EDX 
00407DBA  68 3A040000       PUSH 43A
00407DBF  56                PUSH ESI
00407DC0  8BE8              MOV EBP,EAX
00407DC2  FFD3              CALL EBX    ; в ЕАХ - число символов из Name 
00407DC4  83F8 02           CMP EAX,2   ;сравнивает длину имени с 2
00407DC7  73 1D             JNB SHORT mp3towav.00407DE6 ; 
00407DC9  56                PUSH ESI
00407DCA  68 4C594100       PUSH mp3towav.0041594C ;ASCII "Please enter your name in step 3"
00407DCF  E8 7C0C0000       CALL mp3towav.00408A50
00407DD4  83C4 08           ADD ESP,8
00407DD7  33C0              XOR EAX,EAX
00407DD9  5F                POP EDI
00407DDA  5E                POP ESI
00407DDB  5D                POP EBP
00407DDC  5B                POP EBX
00407DDD  81C4 000A0000     ADD ESP,0A00
00407DE3  C2 1000           RETN 10
00407DE6  85ED              TEST EBP,EBP
00407DE8  76 21             JBE SHORT mp3towav.00407E0B
00407DEA  8D8424 1002000>   LEA EAX,DWORD PTR SS:[ESP+210]
00407DF1  50                PUSH EAX
00407DF2  E8 331E0000       CALL mp3towav.00409C2A
00407DF7  83C4 04           ADD ESP,4
00407DFA  8D4C24 10         LEA ECX,DWORD PTR SS:[ESP+10] ; помещает имя в ЕСХ
00407DFE  51                PUSH ECX                      ; заталкивает в стек имя
00407DFF  50                PUSH EAX                      ; помещает в стек рег. код
00407E00  8BCF              MOV ECX,EDI
00407E02  E8 E9FCFFFF       CALL mp3towav.00407AF0        ; посмотрим, что там внутри
00407E07  85C0              TEST EAX,EAX
00407E09  75 1D             JNZ SHORT mp3towav.00407E28
00407E0B  56                PUSH ESI
00407E0C  68                F8584100 PUSH mp3towav.004158F8 ;с стек помещ. строку
 ; ASCII "That registration code is not valid.Double check the number you are typing in."
00407E11  E8 3A0C0000       CALL mp3towav.00408A50
00407E16  83C4 08           ADD ESP,8


   Как видно из приведённого листинга, программа сначала считывает имя и рег. код, затем считает число символов имени и, если оно меньше 2 просит ввести имя ещё раз. Далее проверяется, введен ли регистрационный код (инструкция TEST EBP,EBP по адресу .00407DE6).
   А вот по адресу .00407E07 проверяется значение ЕАХ на равность нулю, в зависимости от результатов которой нам могут сообщить "That registration code is not valid. Double check the number you are typing in." или поблагодарить за поддержку продукта.
   Поэтому особое внимание стоит обратить на процедуру CALL mp3towav.00407AF0, вызываемую по адресу 00407E0C. Зайдём в неё при трассировке (F7):

00407AF0  53             PUSH EBX                      ;USER32.GetDlgItemTextA
00407AF1  56             PUSH ESI
00407AF2  57             PUSH EDI
00407AF3  8B7C24 10      MOV EDI,DWORD PTR SS:[ESP+10] ; помещаем в EDI рег. код
00407AF7  81FF 40420F00  CMP EDI,0F4240                ; 0F424016 =100000010
00407AFD  8BF1           MOV ESI,ECX
00407AFF  76 54          JBE SHORT mp3towav.00407B55 ;если больше или равно-переходим к
                                                     ;следующей проверке
00407B01  8BC7           MOV EAX,EDI                 ;помещаем рег. код из EDI в ЕАХ
00407B03  33D2           XOR EDX,EDX                 ;обнуляем EDX
00407B05  B9 7FDF0000    MOV ECX,0DF7F         ;помещаем в ЕСХ двойное слово DF7F16=5721510
00407B0A  F7F1           DIV ECX                     ;делим ЕАХ на ЕСХ (частное идёт в ЕАХ,
                                                     ;остаток в EDX)
00407B0C  85D2           TEST EDX,EDX                ;остаток равен нулю?
00407B0E  75 45          JNZ SHORT mp3towav.00407B55 ;EDX<>0 - регистрация не удалась
00407B10  8B06           MOV EAX,DWORD PTR DS:[ESI]
00407B12  BB 01000000    MOV EBX,1
00407B17  3BF8           CMP EDI,EAX
00407B19  0F84 8B000000  JE mp3towav.00407BAA
00407B1F  8B5424 14      MOV EDX,DWORD PTR SS:[ESP+14]
00407B23  8D86 100C0000  LEA EAX,DWORD PTR DS:[ESI+C10]
00407B29  52             PUSH EDX  
00407B2A  50             PUSH EAX

   В этом маленьком кусочке кода и заключается  вся защита, суть которой в следующем: регистрационный номер должен быть целым числом, большим 1000000 (в шестнадцатеричном формате-F4240) и делящимся без остатка на 57215 (в шестнадцатеричном формате - DF7F).

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

   Думаю, выкладывать исходники генератора паролей не имеет смысла, но процедуру генерации на всякий случай приведу:

procedure TForm1.Button1Click(Sender: PObj);
var
i,k: integer;
begin
  randomize;
  k:=random(1000);     
{генерируем множитель для числа 57215. Ограничимся интервалом от 0 до 1000}
  k:=k+18;             
{чтобы получить число-ключ больше 1000000 множитель должен быть не менее 18}
  i:=57215*k;          
{получаем регистрационный номер}
  editbox1.Text:=int2str(i); 
{выводим рег. код. Для VCL используйте функцию intTOstr(i)}
end;

Информация приведена исключительно для ознакомления. Применение данной информации в незаконных целях категорически запрещается.
© BioCyborG, 2003

 © BioCyborG
www.biocyborg.narod.ru

Hosted by uCoz