Совсем простой CrackMe, и как его сломать.
Попросили показать самый простой пример по реверсингу. Ну ладно, сделал простейшую программу, окно где надо ввести пароль:
Ввели правильно, получаем окно одобрямса:
Ввели неверно, программа отправляет на повторный ввод с сообщением об ошибке:
Если нажать Cancel - программа просто завершится.
Сам CrackMe сделан на базе прошлого примера окна типа
InputBox
(копия), не стал даже с закрытием "пароля" "звездочками" заморачиваться, говорю же, очень простой CrackMe, естественно, без всякой упаковки и навесных защит.Вообще, пароль можно подсмотреть, открыв экзешник, например, в просмотровщике Far Manager по F3:
Прямо как в некоторых старых DOS-программах, где защита от копирования была скорее защитой от дурака, или в форках некоторых приставочных игр под DOS, где таким же образом можно было получить код от уровня.
Но мы пойдем другим путем, как завещал великий Ленин! Хотя способ будет не сильно далеким от "подсмотра", чтоб было слегка посложнее и интереснее - не будем пользоваться отладчиком, а воспользуемся дизассемблированием. В отладчике вместо одного шага (простого подсмотра пароля) будет полтора, а так все же веселее.
И задача, естественно, модифицировать программу так, чтобы подходил любой пароль.
Что потребуется:
- Дизассемблер: IDA Pro, я использую довольно старенькую версию 5.0, причем, по привычке, консольную Win32 (она и на Win7 x64 неплохо работает), без новых свистелок и перделок, но тут они и не понадобятся. Скачать можно, например, здесь, ну или поискать версию посвежее. Свою версию дать не могу, иначе придет злой татарин Ильфак и настучит на файл-хранилище.
Сейчас есть версии IDA Free, которые можно скачать с официального сайта, но мне новый графический интерфейс не понравился от слова ужас-ужас.
А вот BAT-файл для быстрого запуска из консоли дать могу:
Меняем путь к
idaw.exe
(или idag.exe
, если хотите версию для графического режима) на свой, сохраняете, например, под именем DIS.BAT
, кидаем его в директорию с виндой (обычно C:\Windows
) или в любой другой каталог из %PATH%,
и дизассемблируете любой EXE
, DLL
и другой поддерживаемый файл командой dis ваш_файл
. В нашем случае:
dis scrackme.exe
- HEX-редактор для окончательного изменения экзешника. Лучшим я до сей поры считаю Hiew:
+ Он консольный
+ Имеет три режима просмотра (просто текст, шестнадцатиричный режим, режим просмотра ассемблерных команд)
+ В последних двух режимах может редактировать файлы
+ Много чего еще, но пока и этого хватит.
Как же без BAT-файла для запуска его из консоли
Скачать HIEW можно здесь
У меня версия 7.21 (не дам), на old-dos вроде есть посвежее, а вообще, программа поддерживается до сих пор, лучше нее в своем классе я, пожалуй, ничего не видел, и при случае куплю себе последнюю версию, хотя бы для "поддержать автора", тем более, там немного, 800 рублей всего, для версии без бесплатных обновлений.
Официальный сайт
Везет же мне на программистов с именем Евгений, вторая лицензионная программа похоже будет (первая была WinRAR, которую тоже Евгений написал)
1. Запускаем дизассемблирование с помощью IDA:
dis scrackme.exe
2. IDA сразу же предлагает нам выбрать опции дизассемблирования, их много, и вообще про IDA книги написаны, но в данном случае, оставим все по умолчанию. Нужно обратить внимание лишь на самую главную опцию - формат исполняемого файла:
В нашем случае, IDA сама определила все правильно -
Portable executable for 386 (PE)
, но на всякий случай, предлагает и другие. Жмем ENTER и ждем окончания процесса. Хотя, если экзешник большой, то доступ к опциям дизассемблера можно получить, пока анализ не завершен, он будет продолжаться в фоне, но лучше дождаться окончания (в правом углу будет надпись READY
):Ну давайте теперь посмотрим, что нам автоматически нашли. Обычно я первым делом проверяю автоматически определенные имена View --> Open subviews -->Names (Shift-F4).
Там обычно все в куче, и функции API, и какие-то автоматически сгенерированные имена внутренних функций программы, и определенные IDA'ой строки, которым приданы осмысленные имена (начинаются со строчной буквы
a
):Встанем, например, на имя
aEnterPassword
(ну нас же просят ввести пароль), нажмем ENTER, нас выкинет в листинг программы, где указана сама строка:А также, все остальные строки, используемые в программе. Чудо! На самом деле нет, но у нас очень простой CrackMe
IDA снабдила каждую строку комментарием (
;
) где после DATA XREF:
указала ссылку, где эти данные используются программой, например, для aEnterPassword
это start+...
, где ...
- смещение, относительно функции start
, но тут нам это даже запоминать не нужно. В IDA реализован удобный механизм переходов - встаем курсором (стрелками с клавиатуры) под интересующий нас start+...
(их может быть несколько, если имя переменной или функции используется в нескольких местах в программе), нажимаем ENTER и сразу перемещаемся в нужное место в листинге кода.Это также срабатывает, если нажать ENTER, встав на адрес в инструкции перехода (
JMP
/JE
/JNE
... /Jxx
) или на адрес в инструкции CALL
. Для возврата на шаг назад надо нажать клавишу ESC. Т.е. перемещаться по участкам кода и смотреть, что там делается, на мой взгляд, очень удобно...Что ж, перемещаемся на строчку:
data:00403191 String2 db 'PA$$w0rD',0 ; DATA XREF: start+2E...
Мы ведь увидели, что в строке
String2
нечто похожее на пароль?Перемещаемся курсором под
start+2E...
и жмем ENTER.Попадаем в листинг, где константа
String2
используется:.text:00401170 push offset String2 ; "PA$$w0rD"
.text:00401175 push offset String1 ; lpString1
.text:0040117A call lstrcmpA
.text:0040117F test eax, eax
.text:00401181 jnz short loc_401198
IDA опять же любовно прикомментила нам, где используется строка
PA$$w0rD
, а после того, как она и некая другая строка String1
, которая на самом деле буфер ввода, они передаются функции WinAPI lstrcmpA
, которая сравнивает строки и возвращает в регистре eax
значение -1
, если строка1 < строка2
, значение 1
, если строка1 > строка2
, 0
- если строки равны.test eax, eax
- стандартный способ проверить, есть ли в регистре 0
. См. здесь.А дальше переход:
jnz short loc_401198
, так что если в регистре eax
не 0
, то jnz
сработает. Посмотрим, куда ведет этот переход - встанем курсором под loc_401198
и нажмем ENTER:А переход ведет вот сюда:
mov dwInitParam, offset aSorryPasswordI
jmp short loc_40114C
Т.е. на вывод сообщения о неправильном пароле и возврате к вводу.
А если миновать этот переход, то попадем на нужное нам действие:
text:0040117F test eax, eax
text:00401181 jnz short loc_401198
text:00401183 push 0 ; uType
text:00401185 push offset Caption ; "Access granted!"
text:0040118A push offset Text ; "You are connected to
text:0040118F push 0 ; hWnd
text:00401191 call MessageBoxA
Получается, чтобы программа не реагировала на любой пароль, надо, чтоб инструкция
jnz short loc_401198
не сработала. Самый простой способ это сделать - удалить инструкцию как таковую к чертовой бабушке!
Запоминаем адрес (не)нужной инструкции
00401181
, и выходим из IDA (Alt+X). Можно сохранить результаты дизассемблирования в локальную базу данных (scrackme.idb
):Теперь воспользуемся
hiew
'ом, чтобы пропатчить экзешник.Копируем экзешник (например в
scrackme.patched.exe
)Запускаем
hiew
:hw scrackme.patched.exe
Переключаем в режим декодирования F4 (
Mode
) --> Decode
Нажимаем F5 (
Goto
), вводим адрес, который выяснили ранее (.00401181
) и нажимаем Enter. Попадаем на нужную инструкцию:Чтобы переход
jnz
/jne
не сработал, достаточно заменить его на пустую операцию, благо в ассемблере такая команда есть - nop
(No OPeration). Опкод: 90h
.Внимание! Команда
nop
занимает 1 байт, а команда короткого условного перехода (jnz
/jne
) занимает два байта, соответственно, и менять команду нужно на 2 nop
'а.Нажимаем F3 (
Edit
) и либо сразу вводим опкод 90
два раза:Либо, в режиме редактирования нажимаем F2 (
Asm
) и вводим команду на ассемблере (nop
ENTER nop
ENTER)Закрываем окно для ввода ассемблерных команд (ESC) и нажимаем F9 (
Update
), сохраняя изменения.Теперь при запуске пропатченного CrackMe подойдет любой пароль.
1. Исходник CrackMe
2. Бинарный файл
3. Чтоб два раза не вставать: Разница между инструкциями
test
и cmp
Копия в PDFЭто репост с сайта http://tolik-punkoff.com
Оригинал: https://tolik-punkoff.com/2023/03/03/sov