
Всем привет,
Решил я давеча поиграть в одну из своих самых любимых игр (ещё со времён компьютерных клубов) про похождения Штирлица Нео, Матвея Морфеуса и про их побег из дурдома Матрицы. Но, оказалось, что читы не работают, таблиц для Cheat Engine нет, а возраст уже не тот, чтобы тащить эту игру как есть.
Так я и пришёл к тому, чтобы взять да починить трейнер для этой игры от PiZZADOX. Точнее, подсмотреть, чего они там в процессе игры патчат и сделать точно так же, но на постоянной основе (прямо в EXE). Об этом и будет мой рассказ...
Предыстория
На самом деле история достаточно типичная для того времени: открылся в нашем городишке компьютерный клуб под названием "Сенатор", куда каждый школьник мог прийти и поиграть за украденные у мамки деньги, при этом прогуливая, конечно же, уроки. В один из таких дней прямо на входе в клуб меня избил какой-то отморозок постарше, пока остальная толпа тупо смотрела и ничего не делала. Тем не менее, я всё равно в итоге взял время и пошёл играть.
Не помню, смотрел ли я тогда уже Матрицу где-либо (скорее всего смотрел), но ярлык на рабочем столе "Enter the Matrix" привлёк моё внимание и я запустил игру. Кстати, она мне очень даже зашла, и со временем игра была успешно пройдена, при этом я ещё и обзавёлся новым знакомым, который меня за такое вот достижение прозвал Нео, а я его за это - Морфеусом. Никто, правда, кроме него меня так не называл, но это ладно.
Прошло время, я вырос, клуб успешно закрылся (то ли за какие-то махинации среди админов, то ли ещё из-за чего-то незаконного), а я до сих пор периодически поигрываю в этот, так сказать, "шедевр". Конечно, графика в ней давно устарела (мем про квадратные колёса помнят многие), управление тоже не то что бы хорошее, но вот сюжет и видеовставки с теми же актёрами, что и в оригинальной трилогии (плюс некоторые сцены с Моникой Белуччи, которых не было в оригинале) - то, за что я и полюбил данную игру.
Так вот, решил я в 2к25 поиграть в "игру детства" - поставил все патчи, фикс для Widescreen, запустил. Нашёл трейнер от известных трейнер-мейкеров PiZZADOX - жму кнопки F5
, F6
, а оно не работает...

Подумав "Я реверс-инженер или кто?", я закинул трейнер в Иду, и... совсем не удивился, когда увидел, что код чем-то накрыт. Анализатор упаковщиков показал мне какой-то exe32pack
. Название звучало незнакомо, беглая гуглёжка показала лишь скрипты поиска OEP (оригинальной точки входа - места в коде программы, до которого если дойти, можно сделать работоспособный дамп процесса). К сожалению, скрипты были только для Olly Debugger
, а его в наше время мне уже совсем не хочется, когда есть x64dbg
.
Скрипт переписывать я не собирался, а вот подсмотреть логику в нём - это да, можно. Из того, что я понял, шаги были следующими:
С адреса точки входа программы найти опкод
5B
(pop ebx
)Поставить брейкпоинт
Запустить программу, после чего она должна остановиться на установленном бряке. Бряк нужно снять
С текущего адреса найти байты
BF FF E0
(это командаjmp eax
, но внутри другой команды)Поставить HW бряк на
jmp eax
Запустить программу - она остановится уже на втором бряке
Сделать один
Step Into
- мы на OEP
Дальше нужно запустить Scylla
и сдампить процесс, после чего починить таблицу импорта. Я подробно не буду на данном моменте останавливаться - он подробно освещён в различных туториалах по снятию распаковщиков. Главное - мы получили работоспособный дамп процесса, который теперь уже можно открыть в Иде и проанализировать.
Анализ трейнера
Так как трейнер написал на чистом ассемблере, Ида не смогла найти WinMain
. Но найти его крайне просто - это первая вызываемая функция с точки входа:

В самом WinMain
найти нужную функцию, которая реагирует на нажатие клавиш не трудно - указатель на неё передаётся в lpfnWndProc
:

В wnd_func
сходу находим обработчик нажатий, а именно:

Функция write_to_process
(конечно, это не оригинальное название, но суть отражает) открывает процесс на запись и по конкретному смещению в нём производит запись массива. Сами массивы представляют из себя изменённый код игры, который и будет вызываться вместо оригинального.
Конечно, по представленным смещениям в моём Matrix.exe
ничего подходящего под вставляемый код найти не удалось, иначе бы трейнер работал. Но какой именно код он патчит?
На этом шаге мне пришлось устанавливать все игры скачивать все NoCD для всех версий Enter the Matrix (очевидно, что качать все образы было бы нецелесообразно). И, в итоге, правильный EXE нашёлся - нужной версией игры оказалась 1.0
.
Дальше оставалось дело за техникой: нужно было понять, что делает вставляемый код и куда именно он вставляется. Для этого переходим по первому модифицируемому адресу 0x83FE31
и смотрим, что там есть. А есть там ни что иное, как кучка нопов (байт 0x90
) для выравнивания:


Аналогичная ситуация и с адресом 0x8214E1
. А вот адрес 0x6017DD
уже интереснее - здесь располагается само место патча кода, откуда будет происходить прыжок на предыдущие два адреса:

Теперь продизассемблируем вставляемый код:



Итого:
В код, где происходит изменение значения полоски
HP
, вставляется прыжок наПатч 1
Патч 1
: выполняет инструкцию, которая была заменена прыжком сюда, после чего прыгает наПатч 2
Патч 2
: устанавливает значение500.0
по смещению0x354
в какой-то структуре, и уже затем прыгает на остальной кодАналогичные действия происходят и с двумя другими обработчиками клавиш
Заключение
Дальше можно действовать как больше нравится:
Пропатчить оригинальный EXE (версия
1.52
)Изменить в самом трейнере адреса для мест вставок патчей
В любом случае, нужно:
Найти достаточные по размеру выравнивания из нопов (или из нулей)
Найти код, который отвечает за модификацию полоски HP (в идеале, поиском по тем же константам)
Сформировать блоки кода, аналогичные тем, что были в трейнере, но с поправленными прыжками между ними
Чтобы вы не повторяли то же самое, что и я, привожу итоговую таблицу с изменёнными байтами и адресами.
Старый адрес для вставки | Старые вставляемые байты | Новый адрес для вставки | Новые вставляемые байты |
Жизни | |||
|
|
|
|
|
|
|
|
|
|
|
|
Фокус | |||
|
|
|
|
|
|
|
|
|
|
|
|
Оружие | |||
|
|
|
|

P.S. There is no spoon.