Pull to refresh

Comments 14

А как защитить свое ПО от подобных инъекций? Я так понял, обфускация кода здесь не поможет.
при каждом чихе пересоздавать переменную?
под чихом подразумеваю смена состояний, важные для игры
Или лучше просто из сервера не слать данные о всей карте, как это сделано у agario
Тут соглашусь на все 146. Состоянием онлайн-игры (да и любого клиент-серверного приложения) должен рулить сервер, а клиент по данным сервера просто отображать это состояние. Иначе взлом и подмена важных данных неизбежна.

Слишком сложный вопрос.
Обфускация кода есть практически во всех играх, но дизассемблируя мы видим код, каким его видит процессор(а комменты/названия частенько затирают).
В одной из игр видел такой трюк: игра при каждом изменении переменной присваивает её другой переменной(всего их было 4 на каждую характеристику и они по кругу менялись). Это была пошаговая двухмерная стратегическая РПГ поэтому они могли себе позволить такие затраты памяти.
В некоторых играх значения изменяются через сеттеры и геттеры "обфусцируя" значение переменной. Пример: цивилизация, где ресурсы показываются как число с дробной частью (100.26 или 25.32), а на самом деле является интом 100.
В флеш играх часто значения переменных умножались на 8(и иногда вдобавок плюсовалась 6). Поэтому для Cheat Engine даже писал свой кастомный поиск "Flash Value" который искал (value || value
8 || value * 8 + 6)
В игре Dungeon Defenders(доступна в стим) все значения легко находятся и изменяются(если это не игра на офицйальном сервере, т.к. данные хранятся на сервере), но при подключении дебагера игра крашится. (До сих пор хз по какой причине)
Если XOR'ить значения переменных можно сделать очень неприятную ситуацию: обычные средства поиска подразумевают:


  1. Поиск по конкретному значению с указанием типа(целое или с плавающей точкой, знаковое или беззнаковое, 4 или 8 байт на переменную)
  2. Поиск по конкретному значению и всем типам (раньше я их разделял, потому что много времени занимало)
  3. Fuzzy Search — Нечёткий поиск. Это поиск когда мы не говорим конкретные значения, а говорим что переменная либо: Увеличилась на х / Уменьшилась на х, Увеличилась / Уменьшилась, Изменилась / Не изменилась. Значения приведены в порядке увеличения времени и итераций поиска. Поэтому в случае XOR'а придётся выбирать самый последний, долгий и мучительный вариант.
    Но всё выше перечисленное(не считая вылета при дебагинге) это лишь временная преграда, потому что самый "Крутой/жесткий/гибкий/продвинутый"(нужное подчекнуть) способ — это отслеживать изменения переменных через адресацию через базовый гейм адрес. (В статье автор использует брейкпоинт на Write, а там ещё есть брейк на Access — последний логирует все обращения к переменной и "хвост" за ней. Это позволяет нам делать совершенно любые и даже неожиданные вещи: например сделать так чтобы враги считали нас союзником(был такой хак для Halo), заставить врагов атаковать друг-друга и вообще всё, всё, всё.

Получилось много, но суть в одном — по-моему невозможно "полностью" защитить игру от подобного взлома, потому что этот способ, по-сути даёт нам возможность писать свой код в чужой программе. Например, GTA:SAMP — мультиплеер для GTA:SA работает на аналогичном методе...

Иногда можно увидеть вот такие вещи в коде (просто открыв файл):
image

Получать данные для мультиплейера с сервера.
Но, увы, поможет только частично. Можно, например, сделать чтобы не видели противника, но карту местности так спрятать не удастся. Разве что карта будет рандомная и будет получаться от сервера по частям.

который управляет логикой переключения состояний карты в зависимости от нажатых пользователем клавиш (7, 8, 9, 0)
Тут у меня вопрос не к автору перевода, а просто в воздух — что мешало повесить на две клавиши, каждое нажатие просто с 0 на 1 и обратно меняет состояние соответствующего флага.
Мы же не анализируем текущее состояние, можно завести пару статических переменных для этого.
Я подозреваю, что каждая клавиша отсылает либо 0, либо 1. Вешая на две клавиши — можно просто инвертировать бит для переключения состояния, а не отсылать константу.
UFO just landed and posted this here
Нужно больше const. Прикастовать результат функции к void и нигде не использовать. Ну и, конечно же, зафигачить весь код в extern «C» {} блок.
Простейший способ выяснить это — применить стандартные практики программирования. В частности, активная кнопка будет иметь где-то в памяти значение 1, а неактивная — значение 0.


Кстати, вот тут вам очень несказанно повезло, потому что:
  • Никто не заставляет использовать именно bool как булеву переменную ([хех]), int/short/char тоже неплохо подходят. Да и bool, вообще говоря, не обязан храниться в виде 0-1 (для C++, в Си bool вообще не существует), у него даже конкретного размера нет. То, что тут получилось именно так, — очень сильное везение, потому что обычно все складывается несколько иначе. Могу посоветовать искать не конкретно 1, а «не ноль». Сам сталкивался с ситуацией, когда переменная принимала значения или 0, или 3 (wtf!?).
  • Хранить стейты как бул — очень нехорошая идея, и стейты чаще хранятся как enum'ы, отображенные в int (ну или как дефайны, так тоже бывает). Потому что в реальности состояний бывает больше, чем два. В случае с кнопкой, например, «нажата», «не нажата», «подсвечивается» и т.д. Соответственно, не факт, что там будет все объявлено именно так последовательно, может вообще побитово или комбинацией битов, кто этих разработчиков знает то


Спасибо за статью в целом, интересно написано :)
Никто не заставляет использовать именно bool как булеву переменную ([хех]), int/short/char тоже неплохо подходят

Что в памяти программы будет одним и тем же. Нам не важно какой у неё тип в коде. Нам важно её значение во время выполняемой программы.
Про "Несказанно повезло" вы явно перегнули, потому что искать 0 и 1 — нормально, т.к. в большинстве игр так и есть(а тип не имеет значения, т.к. можно искать от меньшего к большему)
Про переменную принимающую значения нажатой кнопки 0 — объяснение в том что сначала думали что кнопка будет (включать туман войны), а потом оказалось что наоборот звучит лучше (убрать туман войны).
По поводу значение галочки в 3 — просто экономия памяти с использованием масок.
Например: 1 — включить туман войны, 2 — наложение чёрного. 0 — ни тумана, ни черного, 1 — только туман, 2 — только черный, 3 — и черный и туман. (Опять же. одна галочка может быть скрыта в релизе)

Sign up to leave a comment.

Articles