Pull to refresh

Реверс-инжинирим игру Hogs of War, часть 1

Reading time3 min
Views6.4K

Мотивация


В связи с испорченным местными властями отпуском приходится занимать свое время чем-нибудь интересным. Например, подлечить старую игрушку, косяки которой не позволяют нормально поиграть на современных ОС, либо поменять несколько байтов для получения разных extra-возможностей just for fun. Подопытным будет игра из далекого 2000 года под названием Hogs of War. Если кто не знает, то это turn-based стратегия, где вам дается команда хрюшек, с помощью которых вы должны ни много ни мало, завоевать мир. В процессе игры в зависимости от результатов можно модифицировать каждую хрюшку, например повысив её в звании. В 2009 Atari объявила о продолжении игры в виде разработки HOW2, но по последним данным проект свернули из-за недостатка финансирования. Ничего приятного.

Цель этой части: исправление бага, при котором блокируется весь рабочий стол, если произошел appcrash по какой-либо причине и подготовка приложения для работы в экранном режиме для упрощения отладки.

Хочу всех предупредить: все нижеследующее вы делаете на свой страх и риск. Автор не несет ответственности за любого рода убытки, понесенные в результате воспроизведения описанных действий. Все описанные действия выполнил кот автора.

Инструменты


Для отладки использовались IDA, MSDN, ida_patcher, DxWnd. Обо все более подробнее далее.

Подготовка


Итак, никакого опыта такой отладки нет, поэтому на первых порах придется все делать на интуитивном уровне. Для начала открываем в отладчике бинарный файл, а это у нас warhogs.exe. Возможная причина бага: приложение просто не может по-другому стартовать корректно, либо не может функционировать корректно. В отладчике пробегаемся по импортированным функциям как-либо связанными с окнами Windows, встречая там, конечно-же CreateWindowEx, а так же EnableWindow. Если первый вызов прозрачен, хоть и встречается несколько раз, то второй, пожалуй, настораживает. Переходим в точку вызова функции EnableWindow (всего их 2) и видим следующий код:



Нас интересуют следующие команды:

.text:0044D0A0 and edx, 0FFh
.text:0044D0A6 push edx; bEnable
.text:0044D0A7 push ecx; hWnd
.text:0044D0A8 call ds:EnableWindow

Которые подсказывают что для каких-то окон эта функция вызывается в виде EnableWindow(TRUE, ...);, а для каких-то EnableWindow(FALSE, ...);. Прыгаем по зависимостям вверх (лучше именовать функции, в логике которых вы полностью уверены) и обнаруживаем, что функция EnumFunc используется как callback-функция при вызове EnumWindows, после которой следует вызов функции SystemParametersInfo с кодом 0x61. Недолгое гугление позволяет выяснить что таким способом авторы пытались выключить комбинацию Alt-Tab. Нам это не интересно, поэтому лечим байты по смещению .text+0x0044D0A0, исправляем инструкцию and edx, 0FFh на or edx, 0FFh, что позволит вызывать функцию EnableWindow всегда с первым параметром не равным нулю. Второй reference к функции EnableWindow происходит при закрытии приложения, что говорит о том, что авторы восстанавливают перемирие после того как натворили делов. Здесь ничего не правим.

Конечно же, хочется сразу применить патч и посмотреть на результат, но не тут-то было! Для начала придется сгенерировать diff-файл, который будет выглядеть так:

This difference file has been created by IDA Pro
warhogs.exe
0004C4A1: E2 CA

Затем необходимо сторонней утилитой применить патч к исполняемому файлу. Это делается с помощью скомпилированного исходника ida_patcher.c. Параметры у получившегося консольного приложения следующие: -i <binary_file_to_patch>, -p <.diff file>. Внимание, никаких предупреждений не последует, так что лучше заранее следать backup.

Запускаем приложение, пробуем Alt-Tab, переключается, но warhogs.exe сразу уходит в appcrash. В принципе, не удивительно зачем они нагородили в коде столько костылей. Но есть и приятный бонус, теперь после appcrash рабочий стол не заблокирован, можно спокойно продолжать работать!

Теперь необходимо сделать так, чтобы приложение запускалось в экранном режиме. После небольшого изучения информации было найдено 2 пути для выполнения следующего действия: 1 — изменение кода приложения (изменение кода работы с Direct3D 7), и 2 — использование стороннего приложения под названием DxWnd, которое позволит forcibly запустить warhogs.exe в экранном режиме.

Выбираем второй путь, т.к. он более простой. DxWnd перехватывает вызовы к Direct3D.
Пробуем — получается! Переключение между окнами безболезненное, warhogs работает стабильно в экранном режиме, IDA спокойно отлаживает warhogs.exe пошагово. Все готово для углубления во внутренности движка, что я кот и сделает в следующей части. Всем хороших чиновников!
Tags:
Hubs:
Total votes 42: ↑32 and ↓10+22
Comments19

Articles