Совсем простой 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):

Патч CrackMe.

Теперь воспользуемся 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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *