Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
В этой статье я попробую показать, как создать собственный чит, который будет противостоять используемым в играх античит‑системам. Для этого нам понадобится поупражняться в реверсе и познакомиться с устройством игр, написанных на Unity. Другие статьи цикла о написании читов
Итак, античит — это некая программа, которая мешает игрокам в онлайновые игры получать нечестное преимущество за счет использования стороннего ПО. Не буду пытаться объяснить это на абстрактном примере, лучше давай сразу перейдем к практике. По дороге все поймешь!
Так как нет (или я просто не нашел) античитов уровня ядра с открытым исходным кодом, то выбирать будем из опенсорсных античитов, в которых присутствует только античит пользовательского уровня. Мой выбор пал на античит Quick Universal Anti-Cheat Kit (далее Quack).
Сразу предупреждаю, что Quack — это лишь простенькая опенсорсная демонстрация концепции. Обойти ее проще, чем системы, которые используются в популярных играх. Все коммерческие античиты работают как на пользовательском уровне, так и на уровне ядра. Причем самые важные защитные функции обычно реализованы именно в виде драйвера.
Однако для обучения Quack сгодится как нельзя лучше, и изложенное дальше должно стать фундаментом для будущих изысканий.
warning
Статья имеет ознакомительный характер и предназначена для оценки защищенности кода игр. Автор и редакция не несут ответственности за любой вред, причиненный с применением изложенной информации. Обратная разработка античитов нарушает пользовательские соглашения игр, поэтому, повторяя описанное в этой статье на практике, ты действуешь на свой страх и риск!
Давай посмотрим на общую архитектуру античита глазами ее автора. Далее я объясню, для чего нужен каждый выделенный на схеме компонент.
Архитектура Quack
Зеленым цветом я выделил клиентскую часть (то, что будет работать на компьютере игрока):
Синим цветом я выделил серверную часть (то, что будет работать вне компьютера игрока):
Если после развертывания Quack (как это сделать, смотри в руководстве на GitHub и на YouTube) у тебя ничего работает, то советую повнимательнее изучить следующие файлы и настроить сетевые адреса и порты в соответствии с реальными условиями.
GameDevCAServerProgram.cs var settings = MongoClientSettings.FromConnectionString(env["DB_URI"]);settings.ServerApi = new ServerApi(ServerApiVersion.V1);var mongoClient = new MongoClient(settings);database = mongoClient.GetDatabase(env["DB_NAME"]);
Quack-serversrcmain.js class Config { static DB_URI = process.env.DB_URI static DB_NAME = process.env.DB_NAME static PORT = process.env.PORT static CLIENT = new MongoClient(this.DB_URI) static DEV_MODE = true static VERSION = process.env.npm_package_version}
Quack-internalconstants.hpp namespace constants { const LPCWSTR W_DLL_NAME { L"Quack-internal" }; const LPCSTR DLL_NAME{ "Quack-internal" }; const std::string VERSION { "0.6.5" }; constexpr unsigned IPC_PORT = 5175; // Local machine communications port constexpr unsigned NET_PORT = 7982; // Foreign network communications port static constexpr bool DBG = false;}
Quack-clientconstants.hpp namespace constants { const std::string VERSION{ "0.4.2" }; const std::string NAME{ "Quack" }; constexpr unsigned IPC_PORT = 5175; // Local machine communications port constexpr unsigned NET_PORT = 7982; // Foreign network communications port static constexpr bool DBG = false;}
Quack-clientflashpoint.cpp http::Client cli{ "localhost", constants::NET_PORT };
Для начала нам нужно убедиться в том, что все работает. Для этого так же, как и автор античита, будем использовать его игру Inertia, инжектор Destroject и внутренний чит Inertia-cheat. Подключимся к серверу по адресу lh (localhost) с ником xakep0.
Подключение к игровому серверу
В консоли игрового сервера видим, что произошло подключение.
Лог игрового сервера
Также в базе данных античита видим, что появилась запись.
База данных античита
Начинаем тест. Для этого в командной строке выполним Destroject.exe Inertia
(не забыв рядом положить Inertia-cheat.dll
). Видим, что инжект чита успешно выполнен.
Внедренный чит
Активируем чит нажатием клавиши E.
Активированный чит
Видим, что чит активирован, но сразу же происходит бан.
Сообщение о бане в игре
Посмотрев в БД античита, мы можем узнать, из‑за чего нас забанили.
Сообщение о бане в БД
Пробуем сменить никнейм, но нас все равно не пускают.
Попытка смены ника
Если попытаться открыть Cheat Engine, он через пару секунд закроется, но бан не прилетит.
Прежде чем расчехлять IDA Pro и приступать к реверсу античита, сделаем небольшое отступление. Если ты уже заглянул в код чита, то мог заметить следующий участок:
Inertia-cheatplayer.cpp std::optional<Player> GetPlayer() { auto start_point = reinterpret_cast<std::uintptr_t>(GetModuleHandleA("UnityPlayer.dll")); start_point += offsets::player.start_point; // Get a pointer to health const auto health_ptr = TraverseChain(start_point, offsets::player.ptr_chain).value_or(0u); if (!health_ptr) return std::nullopt; const auto ammo_ptr = health_ptr - 0x4; const Player player{ .health = reinterpret_cast<std::int32_t*>(health_ptr), .ammo = reinterpret_cast<std::int32_t*>(ammo_ptr) }; return player;}
Здесь стоит обратить внимание на строчку "UnityPlayer.dll"
. Дело в том, что игра написана на движке Unity.
Inertia-cheatdata.cpp namespace offsets { PointerChain player = { .start_point = 0x13A1340, .ptr_chain { 0xC2C, 0xDC8, 0xEA8, 0x18, 0x38 } };}
Также мы имеем цепочку указателей для UnityPlayer.dll
. Откроем ее в IDA Pro по адресу base+0x13A1340
. Видим, что здесь размещено значение переменной из стека и дальше поиск класса игрока идет в стеке.
UnityPlayer.dll без загруженных отладочных символов
Источник: xakep.ru