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

Эффективный патчинг

MC707 (mc707@mail.ru)

Спецвыпуск: Хакер, номер #057, стр. 057-040-3


Сразу же попытаемся отловить процедуру регистрации, поставив бряки на описанные в начале статьи API-функции. Итак, жмем на кнопку Already Paid в NAG'е и видим окно с приглашением ввести регистрационный код.

Переходим в отладчик и ставим точки останова сразу на все указанные API: GetDlgItem, GetDlgItemTextA, GetWindowTextA, MessageBoxA, MessageBoxExA, MessageBoxIndirectA, MessageBoxTimeoutA, ShowWindow, вводя bp <имя_API_функции> в поле Command. Введем какой-нибудь, неважно какой, серийник, нажмем Submit, и, как это ни странно, увидим сообщение - якобы неправильно набран номер ;).

Отсюда сделаем вывод, что, если мы не остановились ни на одной из функций, то в игре используются иные методы взятия введенной информации и вывода результата. Что ж, не будем отчаиваться. Перезапустим программу и пойдем по первому указанному мной методу - посмотрим наличие строк в коде, имеющих отношение к регистрации. Нажав правой кнопкой мыши по любому участку кода и выбрав пункт Search for->All referenced text strings, ты сможешь увидеть окно со списком всех строк, встречающихся в программе, и с информацией о коде, который использует эти строки. Честно говоря, найти строки из NAG-скрина вряд ли повезет. При размере exe-файла 144 Кб вряд ли в нем будут находиться процедура регистрации и сам код игры. Скорее всего, в этом случае весь код вынесен из основного модуля приложения в динамически подгружаемые библиотеки.

Итак, анализируя выведенные строки (благо из-за размера exe-файла их там не очень много), я наткнулся на подозрительную:

0040631B PUSH game.0041DAA8 ASCII "radll_HasTheProductBeenPurchased"

Очень похоже на вызов функции из библиотеки, проверяющий, приобретена ли программа. Поставим точку останова на этот PUSH, то есть на адрес 0040631B, выделив строку и нажав <F2>. Запустим игру по <F9> и, как это ни странно, еще до появления каких-либо окон остановимся на этом адресе. И вот показался очень важный код.

Не нужно быть reverse engineer'ом, чтобы, взглянув на инструкцию call esi и на esi = 77E7B332 kernel32.GetProcAddress, сообразить, что из какой-то библиотеки берется адрес функции radll_HasTheProductBeenPurchased и он записывается в некоторую переменную по адресу 0042319C. Если посмотреть на строку Reflexiv.00A70000, можно сделать вывод, что эта функция берется из библиотеки ReflexiveArcade.dll. Ее мы обнаружим в папке игры в директории ReflexiveArcade.

Чтобы отучить игру от вредной привычки просить зарегистрироваться, достаточно пропатчить функцию с длинным названием в найденной библиотеке так, чтобы она все время утверждала, что программа успешно зарегистрирована. Но зачем патчить DLL, если можно пойти более изящным путем: просто записать по адресу 0042319C адрес не radll_HasTheProductBeenPurchased, а адрес своей функции, которая всегда возвращала бы единицу, означающую, что игра зарегистрирована.

Первое, чего нам в этом случае не хватает - это своя функция. Нет ничего проще! Берем бегунок прокрутки и прокручиваем код программы в самый низ, пока не встретим там пустое место для записи нашего кода.

Назад на стр. 057-040-2  Содержание  Вперед на стр. 057-040-4