Взлом ChessGenius | ||
Введение | ||
Я – любитель шахмат, часто играю в Интернете, иногда играю с компьютером. Встретил недавно программу, написанную Ричардом Лэнгом. Что меня в ней поразило, это ее компактность – программа занимает всего полмегабайта. Эта программа когда-то выигрывала самого Гарри Каспарова. | ||
Ограничения | ||
Пробная версия программы считает на ограниченную глубину ходов, и в окне анализа движка не выводятся сообщения после 10-го хода | ||
Поведение программы | ||
Итак, рассмотрим, как программа себя ведет, каким образом защищает себя от нелегального копирования. Когда мы запускаем ее, мы получаем диалоговое окно с двумя полями для ввода имени пользователя и серийника, кнопки Register и кнопки для пробной версии. Окей, пробуем ввести имя пользователя и пароль от фонаря. Получаем сообщение о неверности последних. | ||
Взлом | ||
Дизассемблируем программу в IDA. Загружаем программу в OllyDbg и устанавливаем останов на функции MessageBoxA в USER32.dll. Затем Debug – Execute till return. Жмем ОК в появившемся сообщении. Отладчик останавливается, нажимаем f8, для того, чтобы возвратиться в вызывающую процедуру. Видим, что функция была вызвана из следующего места: | ||
Процедура довольно короткая, и похоже, она является оболочкой (или упрощенным вызовом) процедуры MessageBox). Взглянув на количество перекрестных ссылок на эту процедуру, можно убедиться в частоте ее вызовов, что еще подтверждает правильность наших догадок. Произведем возврат из этой процедуры. | ||
А вот и главная процедура. Рассмотрим ее: | ||
здесь у нас сохраняются регистры и обнуляются переменные. Кстати, обнуление происходит неявно, т. е. передается адрес одной переменной, а длина – 168 байт, в результате обнуляются все используемые нелокальные переменные | ||
Здесь у нас происходит инициализация переменных, заметим обнуление регистра ebx (в последствии этот регистр останется «девственно нулевым» и очень часто некоторые переменные будут им инициализироваться. Многие эти переменные не используются в этой процедуре, но используются в диалоговой функции. | ||
Происходит копирование символа “C” и затем последующие 19 байт обнуляются. | ||
Здесь обнуляются некоторые переменные, а также в локальную переменную now записывается текущие дата/время. | ||
Далее производится попытка чтения 56 байт из файла lastgame.dat. Довольно забавная маскировка имени ключевого файла. Ну и теперь распутье. | ||
В случае удачного чтения файла начинается вычисление хэша, в противном случае, следующая секция кода пропускается | ||
Обращу ваше внимание на последнюю инструкцию – она устанавливает регистр eax в 1. Если бы эта секция была пропущена, то значение регистра eax было бы равно 0. То есть, в любом случае eax при следующей инструкции содержит признак чтения файла. | ||
Если файл был прочитан удачно и переменная magic_number равна 234567, то выполняется следующая секция. | ||
происходят какие-то операции с датами, в переменную were_date_ops записывается 1. Заметим, что в начале процедуры эта переменная была обнулена. | ||
В регистре ebx содержится 0, то есть, если не было операций с датами, то осуществляется переход на эту секцию: | ||
Выводится диалоговое окно, запрашивающее имя пользователя и серийный номер, затем происходят операции сравнения сначала were_date_ops сравнивается с нулем, если эта переменная равна нулю, то программа обречена на провал, так как переменной is_registered присваивается значение 0, и после этого сообщение о неверности ключа и возврат на 411c13, т.е в самое начало. | ||
Что ж, попробуем пропатчить программу, изменив переход | ||
на | ||
т. е. сделав его безусловным. | ||
Заключение | ||
Вот и снова проблемы в защите программ. И все из-за одних лишь окон сообщений. Как ни странно, для того, чтобы программа сломалась потребовалось изменить один лишь байт! | ||
Настоящая статья предоставлена в ознакомительных целях и ответственность за использование ее в незаконных целях ложится на ваши плечи | ||
| ||
|