Проблема читов в онлайн-играх

8a20b66cf148430a9a178e52db5de789.jpg

Большинство крупных многопользовательских игр рано или поздно сталкиваются с тем, что не все пользователи играют честно. В нашем шутере Warface в какой-то момент это стало ощущаться особенно сильно. Для борьбы с читерами мы используем целый комплекс решений. Одним из компонентов этого комплекса является наша внутренняя разработка под названием MRAC (Mail.Ru AntiCheat). После ее внедрения мы добились хороших результатов: среднее количество ежедневно улетающих в бан читерских аккаунтов упало с 17000 в начале года до 1500 сейчас, при том, что количество жалоб от пользователей на читеров существенно уменьшилось. На выявление подозрительной активности и блокировку аккаунта сейчас уходит примерно 5 минут, вместо прежних 20. Сейчас система распознает и реагирует на более, чем 200 сигнатур читерского ПО и постоянно совершенствуется.
У каждой игры своя специфика, и для эффективной борьбы с читерами необходимо разбираться во внутренних особенностях конкретной игры и приемах, используемых в читах. Мы могли бы подробно рассказать обо всех решениях, которые мы используем в Warface, однако, выдав такую информацию в свободный доступ, мы пригласили бы авторов вредоносного ПО к активным действиям. Пока конкретика остается в секрете читерам сложнее скрываться от системы. Тем не менее, сама по себе тема очень интересная, поэтому хочется раскрыть ее подробнее.


Думаю, многие знают, что такое «IDDQD». На протяжении всей истории компьютерных игр разработчики встраивают в свои детища подобные коды, именуемые читами. Читы позволяют становиться бессмертным, получать бесконечные патроны, ресурсы и прочее. Первичное назначение таких кодов – тестирование игры. Помимо встроенных в игру читов всегда были любители самостоятельно подправить что-нибудь в игре с той же целью – стать «бессмертным». Все это хорошо в однопользовательских играх, когда человек играет со своим компьютером и никому не мешает. В многопользовательских онлайн-играх читерство уже является проблемой, способной загубить всю игру. Если один играет не по правилам, то его соперникам играть становится просто неинтересно. Причем, если в шутере это просто испорченный матч, то в RPG нарушение игровой механики или ботоводство способно перекосить всю внутриигровую экономику.

Конечно, никаких встроенных разработчиками читов в онлайн-играх нет. Но практически для любой онлайн-игры существуют читы в виде отдельных приложений. Как правило, читы при запуске вносят изменения в работающий клиент игры. Иногда изменения вносятся прямо в файлы клиента на диске.

Одной из разновидностей читов являются боты, которые сами управляют персонажем, автоматизируя рутинные действия. Казалось бы, в таких ботах нет ничего страшного. Но на самом деле есть. Если человек спит, а его персонаж сам убивает овечек на поле в автоматическом режиме, получая за это игровой опыт, то другие игроки будут расстроены таким положением вещей. Некоторые из таких ботов позволяют писать целые скрипты для управления персонажем. Тут уже возможности ограничиваются только фантазией ботовода.

Мотивы читеров/ботоводов:

  1. «Надрать всем зад» для самоутверждения. Пусть и нечестно.
  2. Заработать денег. Для этого нужно быстрее прокачаться, собрать ресурсы, шмотки и т.п., чтобы потом продать это за реальные деньги.


Основной мотив авторов читов/ботов — заработать денег. Наиболее качественные читы/боты продаются по подписке за реальные деньги. Есть и бесплатные читы, но они обычно начинены adware и всякими полу-вирусами, что опять же, призвано принести деньги.

Давайте рассмотрим более подробно, что и как делают читы на примере многопользовательского онлайн шутера Warface.


Любой чит так или иначе взаимодействует с клиентом игры. Для этого автору чита нужно иметь представление о внутреннем устройстве клиента. Наиболее профессиональные читоделы получают такое представление, в том числе, путем реверс-инжиниринга — находят нужные переменные и восстанавливают интерфейсы классов. После чего методы классов можно вызывать в своих интересах. Внутренняя структура классов в клиенте изменяется крайне медленно на протяжении жизни игры. Через какое-то время эта информация попадает уже в гораздо больший круг менее квалифицированных читоделов и тогда разнообразие идентичных по функциональности читов увеличивается на порядок.

ESP (Extrasensory perception) – разновидность читов, способных показывать дополнительную информацию о противниках в игре. К сожалению, клиент игры знает о расположении всех противников в определенном радиусе от вас, даже если они за стеной и их не видно. В шутере действия развиваются довольно быстро и если клиент будет получать от сервера информацию о противнике только когда он попал в поле видимости, то это заведомо приведет к лагам из-за сетевых задержек. Чит получает информацию о противниках через внутренние интерфейсы классов клиента и выводит ее прямо поверх игрового изображения. Это, как минимум, расположение противника в пространстве и расстояние до него. Для отрисовки поверх игрового изображения чит перехватывает один из методов Direct3D, вызывающихся каждый кадр. Например, EndScene. Все это подразумевает, что в память клиента был внедрен код чита, необходимый для отрисовки.

Aimbot – разновидность читов для автоматического прицеливания. Вам остается только бегать и спускать курок, а прицел сам по себе попадает на ближайшего противника. Можно даже выбрать часть тела, в которую нужно целиться. Расположение противника в пространстве чит получает также через внутренние классы клиента. Далее для выполнения автоматической наводки возможны варианты. Либо чит напрямую вызывает нужные методы в клиенте для поворота вашего персонажа (прицел всегда в центре вашего взгляда). Либо посылает клиенту сообщения от имени мыши для этой же цели.

Autoshot – автоматический выстрел в тот момент, когда противник оказывается в прицеле. Такой чит работает аналогично aimbot’у — информацию о расположении противника получает через внутренние классы клиента и посылает сообщение от мыши для выстрела. Часто autoshot и aimbot совмещают вместе. Тогда вам остается просто бегать, а прицеливание и стрельба выполняются читом автоматически.

Recoil – отключает отдачу при выстреле. Такие читы, как правило, просто патчат код клиента игры в памяти, отвечающий за отдачу. В результате, стрелять становится сильно проще. Кроме отключения отдачи существует еще масса читов, отключающих различные элементы и упрощающие игру. Например, отключение разброса при выстреле или отключение эффекта работы светошумовой гранаты. Некоторые из таких читов для достижения своей цели модифицируют не код, а переменные в памяти клиента.

Безусловно, это не полный список существующих читов, но уже можно составить перечень механизмов их работы:

  1. Модификация кода клиента игры в памяти.
  2. Модификация переменных клиента игры в памяти.
  3. Вызов методов внутренних классов клиента напрямую.
  4. Отправка сообщений от имени мыши.


Как же бороться с этим? Конечно, наличие грамотной клиент-серверной архитектуры у игры — это очень важно. Но, к сожалению, это решает не все проблемы. Некоторые элементы геймплея выполняются только на стороне клиента, и сервер никак не может обнаружить факт их отключения. А сообщать клиенту о всех противниках в определенном радиусе от вас сервер вынужден для приемлемой производительности игры.

Первым наиболее действенным способом представляется валидация на сервере действий игрока. Например, если игрок каким-то образом за единицу времени переместился в пространстве дальше, чем позволяет игровая механика, то наверняка это читер (speedhack), и его нужно немедленно кикнуть. Такая валидация перемещений игрока возможна, так как в конечном счете сервер контролирует расположение игроков на карте.

Вторым способом представляется статистический анализ на сервере. Например, если все пули игрока постоянно попадают в голову врагов, то это очень подозрительно. Или не в голову, а просто без промахов. Или, скажем, результаты игрока по итогам матча сильно выбиваются из среднестатистических. Конечно, все это еще не повод для блокировки аккаунта данного игрока. Может быть он действительно очень крут. Однако это может использоваться как триггер для пристальной проверки действий игрока группой техподдержки игры. При этом надо понимать, что умный читер, скорее всего, не будет «палиться» и под проверку не попадет.

Еще один способ борьбы – встроенная в игру возможность пожаловаться на читера. Разумеется, по жалобам нужно сначала провести проверку и потом уже решать, блокировать аккаунт или нет. Но как показывает практика, этот способ имеет довольно ограниченное применение. Жалоба на читерство сразу становится элементом манипулирования в игре – люди жалуются на всех подряд, кто играет лучше них. В результате получается огромный поток жалоб, особенно на опытных игроков.

На этом, «красивые» способы защититься от читов заканчиваются, но проблему полностью не решают. Приходится обращаться к навесной защите клиента игры.


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

Защитить весь код никак нельзя. Обфусцированный код работает в разы медленнее, так как его становится в разы больше. Защищать получается только небольшие участки кода, не критичные к производительности. Например, можно как раз защитить проверку контрольной суммы всего кода. Разумеется, никакая защита кода не является панацеей. Она может лишь усложнить задачу для злоумышленника. Цель в данном случае – сделать так, чтобы стоимость взлома была выше, чем ожидаемая выгода.

Если у кода можно подсчитать его контрольную сумму, то с переменными уже сложнее. Нужно придумывать способы хранить важные с этой точки зрения переменные в зашифрованном или избыточном виде. Причем так, чтобы это не сказалось на производительности. Опять же, это не решит проблему, а лишь затруднит задачу для злоумышленника.

Допустим, от модификации кода и важных переменных клиента мы худо-бедно защитились. Но остаются читы, которым для работы не нужно модифицировать ни код, ни переменные. Например, ESP. По сути, чит берет информацию из памяти клиента и отображает ее. Но для такой функциональности в памяти клиента должен присутствовать код чита. За это уже можно зацепиться и пойти следующими путями:

  1. Не дать читу попасть в память клиента.
  2. Попытаться найти чит в памяти клиента.


Первый путь подразумевает запрет на запись в память процесса (WriteProcessMemory) и запрет на создание удаленных потоков (CreateRemoteThread). Обычный способ инжекта своего модуля в процесс как раз требует записать в память и создать свой поток в этом процессе. Учитывая, что чит имеет возможность работать с привилегиями администратора (читер всегда даст их), то в Windows никак нельзя запретить писать в память и создавать потоки в чужих процессах. Можно подумать в сторону создания своего драйвера, который будет блокировать доступ к процессу клиента игры. Но в ядре Windows нет документированных способов фильтровать запись в память чужих процессов (NtWriteVirtualMemory), а использование недокументированных способов сильно усложняется наличием Kernel Patch Protection. Даже если удастся заблокировать запись в свою память, то всегда будут другие дырки: можно внедрить свой код в системные библиотеки на диске.

Предполагается, что модули игры при этом защищены и запакованы защитой кода, и изменить их на диске довольно проблематично.

Второй путь подразумевает нечто похожее на антивирус: искать в памяти клиента заранее известные фрагменты читов. Тут технических препятствий не видно. Однако придется решить задачу оперативного обновления базы читов. Можно пойти дальше и искать фрагменты читов не только в памяти клиента, а во всей системе. Это на случай таких читов, которые работают в собственном процессе, а клиенту патчат код и переменные или шлют сообщения от мышки.

Есть еще третий путь: попробовать найти следы перехвата читом функций Direct3D и считать это угрозой. Чит перехватывает функции D3D для получения управления и отрисовки нужной информации каждый кадр. Но у такого варианта есть существенные проблемы. Есть немало «хорошего» софта, который делает то же самое: перехватывает те же функции D3D для отрисовки своей информации поверх игрового изображения. Например, RaidCall. А задача «отличить хороший софт от плохого» является в общем случае нерешаемой.

Разумеется, весь этот поиск читов и блокировку их внедрения можно отключить путем модификации кода, который за это отвечает. Тут единственный выход — использовать защиту кода. Но как код ни защищай, рано или поздно все-равно сломают. Понятно, что пока приложение работает на компьютере пользователя, ничто не может помешать пользователю изменить данное приложение. Это вопрос лишь времени и оправданности затрат.


Проблему читерства в онлайн-играх не решить только лишь улучшением клиент-серверного взаимодействия. Она комплексная, и бороться с ней тоже нужно комплексными мерами. Как следствие, большинство игр имеют дополнительные специализированные программные средства для защиты от читов (античиты), и от них есть ощутимый толк. Благодаря таким системам читеры портят игровой опыт других игроков в куда меньших масштабах, чем могли бы.

© Habrahabr.ru