Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #80, АВГУСТ 2005 г.

Крякинг — это просто

Степан Ильин aka Step

Хакер, номер #080, стр. 080-070-6


Все изменения можно вручную внести через HEX-редактор, с помощью которого байты по нужным адресам перезаписать числом 90. Или же автоматически записать все изменения с помощью самого OllyDBG: правый клик по исправленному ассемблерному коду, меню Copy to Executable -> All modifications.

[защита: имя-серийник]

Доселе мы рассматривали самую примитивную защиту. FaNt0m's CrackMe #4 представляет собой более сложную задачу. Требуется найти не просто серийник, а регистрационный номер, который зависит от введенного имени пользователя. Другими словами, он генерируется по определенному алгоритму. Такой подход используется в большинстве программ, поэтому особенно актуально будет рассмотреть именно его. Вначале схема стандартна: открываем программу в OllyDBG, устанавливаем бряку на MessageBoxA и запускаем программу клавишей F9. После ввода полей (например, step/123) нажимаем на кнопку Check и попадаем в отладчик. Перед нами уже знакомый код вывода сообщения на экран с текстом «Wrong Serial! Keep trying, you'll get it!». Непорядок! Посмотрим, что было чуть ранее: сначала идет код вывода сообщения об успешной регистрации, а еще выше — инструкция, похожая на вызов процедуры проверки регистрационного номера. Если ты внимательно читал статью с самого начала, то она должна быть тебе уже знакома:

00401236 CALL CRACKME4.004012F9

0040123B CMP EAX,0

0040123E JE SHORT CRACKME4.00401255

По логике вещей в процедуру проверки (а также генерации) регистрационного ключа должны передаваться параметры. Как минимум: введенные пользователем имя пользователя и ключ. Так и есть:

00401205 PUSH

0040120A PUSH CRACKME4.00403084 ;адрес буфера

0040120F PUSH 3E8

00401214 PUSH DWORD PTR SS:[EBP+8]

00401217 CALL <JMP.&USER32.GetDlgItemTextA> ;GetDlgItemTextA

0040121C PUSH 100

00401221 PUSH CRACKME4.00403184 ;адрес буфера

00401226 PUSH 3E9

0040122B PUSH DWORD PTR SS:[EBP+8]

0040122E CALL <JMP.&USER32.GetDlgItemTextA> ;GetDlgItemTextA

Вызванная дважды API-функция GetDlgItemTextA извлекает значения текстовых полей и помещает их значения в буферы, адреса которых передаются в функции в виде параметров. Далее будем действовать по вполне стандартной схеме: поставим брейкпоинт на GetDlgItemText. Программа в этом случае будет остановлена еще ДО генерации и проверки регистрационного кода. А значит, мы сможем проследить за этим процессом и подсмотреть правильно сгенерированный номер с помощью отладчика.

Перезапускаем программу (для этого удобно использовать горячую клавишу — Ctrl+F2), далее с помощью окна Breakpoints удаляем поставленные ранее бряки на MessageBoxA и устанавливаем новую точку останова на GetDlgItemTextA (bpx GetDlgItemTextA). Теперь запускаем (клавиша — F9) и вводим в текстовые поля произвольные значения. Программа остановится на первом вызове этой функции:

Назад на стр. 080-070-5  Содержание  Вперед на стр. 080-070-7