[Из песочницы] Исследование чужого чита для FarCry 4
Не так давно приобрел игру FarCry 4 и она мне сразу очень понравилась. Со временем захотелось немного поковыряться во внутренностях этой игры и написать для нее чит.Немного поковырявшись в игре при помощи отладчика, мне удалось без особого труда узнать, как сделать следующие функции: бесконечные патроны, стрельба без перезарядки, телепортация игрока, скорострельность, убрать отдачу. Так же узнал, как увеличить высоту прыжка игрока. Но вот когда я принялся искать, как сделать игрока бессмертным (мне казалось, что в этом ничего сложного не будет), возникли трудности.Для начала при помощи Cheat Engine нашел адрес здоровья персонажа и поставив брекпоинт на запись. Нашел инструкцию, которая изменяет здоровье. Естественно, как и в большинстве игр эта инструкция отвечает за изменение здоровья всех персонажей в игре, будь то враги, или свои, или даже транспорт (автомобили, самолеты). Такие задачи мне решать не в первой и я знаю, что нужно найти, чем игрок отличается, допустим, от автомобиля или от врага, произвести инъекцию кода и перед изменяющей инструкцией добавить проверку. В результате чего эта инструкция будет выполнятся для всех объектов — кроме игрока.
Но в поисках этого отличия я просидел несколько дней — и все напрасно. Мне не удалось найти ни одной зацепки на то, как отличить что-либо в игре от игрока. Впрочем, не стал отчаиваться и решил пойти не совсем честным путем — просто «посмотреть», как это делают другие читы, в которых есть функция бессмертия.
Я приступил к поискам читов для FarCry 4 в интернете и нашел чит для последней версии игры 1.9. Скачал, антивирус забил тревогу. Следующий чит, который скачал, не работал, но антивирус он не разозлил. 3-й скачанный чит вроде оказался без вирусов и рабочий.
Первым делом я решил проверить исполняемый файл чита при помощи PEiD.
Как можно догадаться, ничего хорошего надпись «Not a valid PE file» не предвещает. Это означает, что над ним издевались упаковщики, протекторы и прочая нечисть. Но не все так плохо, ведь мы же не хотим модифицировать данный файл, он и так полностью бесплатный и распространяется свободно. Все, что нам нужно это узнать — откуда данный чит, что читает и куда записывает.
Для записи данных в чужой процесс есть WinApi функций WriteProcessMemory, а для чтения ReadProcessMemory. Теперь проверим, устоит ли великая и могучая защита данного чита перед API монитором. Перед OllyDBG она устояла; после того, как я попробовал открыть его в этом отладчике, он написал, что не хочет работать с невалидными файлами.
Запускаем игру и под контролем API монитора запускаем чит. API монитор к этому файлу, как оказалось, никаких претензий не имеет. Теперь проверим, перехватит ли он вызовы двух нужных нам функций. Для этого активируем в чите бессмертие и смотрим на результат.
Сначала чит прочитал один байт из памяти игры, а затем еще 3 раза произвел запись. При первом вызове он записал 5 байт, при втором — 21 байт, и при третьем вызове снова 5 байт. Если немного подумать, то можно догадаться, что к чему. Сначала производится замена оригинальной инструкции на безусловный переход, затем по адресу, куда будет совершаться прыжок, записывается код размером 21 байт и напоследок в конец этого кода добавляется безусловный переход на следующую инструкцию, которая находится за оригинальной (которая изменяет здоровье).
Однако на самом деле я угадал только со вторым и третьим вызовом, при первом вызове по адресу FC64.FCE_Engine_GetCloudTypeCount+21F923 записывается следующая инструкция:
comiss xmm9,[rbx+0C]
.Ниже находится изображение основного кода, который записывается при втором вызове функции WriteProcessMemor.
Детально я не стал разбираться, как этот чит делает игрока бессмертным. Решил просто скопировать этот алгоритм и добавить в свой чит.
Так же хочу добавить лично мое мнение по поводу читов типа «Трейнер». Я считаю, что защитить такие читы от взлома практически невозможно, поскольку известно их слабое место, которое заключается в том, что они в любом случае должны вызывать WinApi функции WriteProcessMemory и ReadProcessMemory и как бы там не шифровались данные, в эти функции они поступают в чистом виде. Также я хочу сказать, что если вы собрались писать серьезные читы с уникальным функционалом, то лучше это реализовать в виде DLL, которую при запуске игры инжектировать в процесс — там уже не так просто будет адресочки узнать.
Если трейнер скомпилирован под .NET, то API монитор откажется с ним работать. В этом случае можно в отладчике установить брекпоинт на функции WriteProcessMemory и ReadProcessMemory, а когда он сработает — посмотреть содержимое стека и извлечь оттуда адрес, по которому будут записаны данные.
То, что я написал выше — это мое личное мнение и кто-то может с этим согласится, а кто-то нет. Надеюсь, данная статья вам понравилась.
Не советую вам «копипастить» функционал чужих читов, поскольку вы при этом не набираетесь опыта. Так же создание читов таким способом не будет приносить удовольствие.