Крякинг — это просто Степан Ильин 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) и вводим в текстовые поля произвольные значения. Программа остановится на первом вызове этой функции: |