Перейти к содержанию

Патч для героев IV


Рекомендуемые сообщения

Герои меча и отладчика

Сначала небольшая предыстория. 7 лет назад, я вернулся из магазина с диском 4-х героев. Ощущения от них были двоякие: с одной стороны неплохие находки в плане геймплея, интересные кампании. С другой – непривычное графическое оформление, высокие (для моей машины в то время) системные требования, и, конечно же, ошибки. Их было много, но одна была особенно критичной.

cover.jpg

Если зайти в своем замке в тюрьму, в которой содержатся герои, программа вылетала в систему. Это случилось когда я победил особо сильного соперника с раскачанным героем. Была надежда на то, что в тюрьме пытками и подкупом можно склонить его на свою сторону, ан нет. В общем диск полетел в стол, где был благополучно забыт.

Сегодня у выдалось свободное время. Страдая бездельем, я решил разобрать вещи в столе, и выкинуть ненужное. Наткнулся на забытый диск, и уборку пришлось отложить. Забыл о былых обидах, и погрузился в мир Аксеота. Почти прошел первый сценарий кампании, и надо же было опять влезть в тюрьму с чужим героем. Игра закрылась, а у меня появилось занятие.

За 7 лет я несколько поумнел, и узнал про существование отладчика. Открыв игру во всеми любимом отладчике OllyDbg, и повторив последовательность действий для выявления ошибки увидел следующую картину:

ollycrash.png

Увидел, что вызывается функция, которая возвращает указатель на какой-то объект. Функция возвращает 0. Далее программа пытается что-то читать, и вызывается исключение нарушения доступа к памяти.

Затем я решил просмотреть функцию, которая возвращает указатель. Это метод какого-то класса, куда передается строка. Класс – контейнер. В контейнере находятся объекты со строками. Объекты упорядочены по возрастанию строк. Если упрощенно, то в нем с помощью алгоритма бинарного поиска ищется объект, в котором присутствует заданная аргументом строка. Если элемент найден, то возвращается указатель на него, если нет - 0 (если я ни в чем не ошибся, конечно). Судя по строкам, которые ищут, то это картинки для GUI. Строка на которой все вылетает – «background».

list2.png

На скриншоте отображена часть, которая возвращает значение из функции. Поставил breakpoint на инструкцию xor eax, eax чтобы посмотреть как часто функция возвращает нулевой указатель, и как этот указатель в дальнейшем обрабатывается. В результате я выяснил, что ноль возвращается довольно часто. Просмотрев перекрестные ссылки на эту функцию, обнаружил что чаще всего указатель проверяют. Например таким образом:

list3.png

Места чтобы добавить проверку на ноль и оператор условного перехода не было. Делать DLL Injection ради этого не сильно хотелось. Поэтому попробовал сделать все тупо, быстро и опасно. Места, где идет обращение к этому указателя забить NOP-ами:

list4.png

Получилось как-то не слишком изящно. Зато быстро и ненапряжно. Может и прокатить. Запустил игру и зашел в тюрьму. В систему не вылетает, исключений нет. Пленного героя показывает. А радости-то и никакой. Герой, как и подобает настоящему герою, оказался неподкупным. И тут я сделал то что надо было сделать с самого начала: поискал информацию про тюрьму в гугле. Обнаружилось 2 вещи. Во-первых, тюрьма не нужна и непонятно почему я вообще подумал что там можно подкупить вражеского героя. Во-вторых, есть патч, который исправляет эту ошибку. Зато было интересно, как надеюсь и вам при прочтении этой статьи.

list5.png

  • Плюс 2
Ссылка на комментарий
Поделиться на другие сайты

  • 2 года спустя...

Дошёл до последней, шестой кампании оригинальных героев 4. Там за пиратку играть. Первая миссия по захвату двух городов. Один город вообще без боя сдался, а второй при штурме выдаёт Abnormal termination во время боя. Причём бой начинается, можно сделать пару ходов, а потом БАЦ - вылет :( Как исправить?

Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.