Как предотвратить мошенничество с Gamecih?
Фон
У меня были проблемы с игроками в моей игре на андроид. Для строгой однопользовательской игры это не будет большой проблемой, но поскольку моя игра содержит многопользовательские сражения и глобальные списки рекордов, это заставляет законных игроков перестать играть из-за мошенников.
Как они обманывают
Мошенники используют приложение для пользователей root под названием Gamecih. Gamecih позволяет пользователям приостанавливать работу приложения, изменять значения переменных, а затем возобновлять работу приложения. Так что в моем случае они просто приостанавливают игру, меняют "здоровье" до 74 триллионов, а затем выводят всех из себя на многопользовательскую игру. Вот видео, показывающее, как Gamecih используется для обмана в Fruit Ninja(не в моей игре).
Рассмотренные методы
- Запутывание кода. Это не будет работать, потому что запутывание не изменяет значения переменных, только имена переменных. Это означает, что мошенники могут найти переменную, значение которой совпадает с их текущим состоянием, а затем изменить эту переменную.
- Обфускация кода + изменение значения получателя и установщика. Таким образом, здоровье на самом деле не будет представлять реальную ценность для здоровья. В методе получения я бы сделал что-то вроде возврата здоровья *10; а в сеттере я бы сделал health=input/10; Это, конечно, может быть более сложным.
Что я хочу
Можно утверждать, что рассматриваемый метод № 2 - это то, что я должен использовать, но опять же, это не предотвращает взлом, а только усложняет. В идеале я хотел бы определить, когда люди обманывают с помощью Gamecih, отобразить всплывающее окно с надписью "Черт возьми, ты, злобный хакер", а затем закрыть приложение. Я не хочу, чтобы решение зависело от сервера, поскольку я хотел бы, чтобы мои игроки могли играть в автономном режиме. Если возможно, я бы также хотел избежать запутывания кода.
10 ответов
Вы можете хранить жизнь в количестве X переменных, а реальное значение будет их суммой (всегда рассчитывается динамически). Вы случайным образом выбираете, что обновлять. Кроме того, вы можете добавить некоторую проверку непротиворечивости, и мошеннику становится очень трудно понять, что и как изменить.
Проверка непротиворечивости может быть простым правилом, согласно которому 1-я, 2-я и 3-я переменные расположены в порядке возрастания, а 4-я - наименьшая. Чтобы понять это с помощью этого инструмента, понадобится время.
Кроме того, Yoy может стать более креативным и смешать немного шифрования и т. Д. (Как вы упомянули). Тогда это становится невозможным, если у кого-то нет вашего кода.
РЕДАКТИРОВАТЬ: Добавить 100 случайных переменных, которые постоянно меняются со случайными именами (или позициями в массиве, чтобы сделать это проще), а затем удачи для читеров, ищущих правильные. И сделайте все это динамичным, чтобы каждый раз им приходилось взламывать его снова.
Вы можете периодически проверять, изменилось ли ваше значение, если оно не предполагалось.
Например, вы можете сохранить в отдельном скрытом флаге тот факт, что значение здоровья изменилось. Если ваш метод проверки обнаруживает изменение значения, а флаг не установлен, то вы можете сказать, что это изменение было недопустимым.
Например:
void incrementHealth(int amount) {
health = health + amout;
hiddenCheck.hasChanged = true;
}
и в отдельном методе, который должен периодически вызываться:
void checkHealth() {
if (hiddenCheck.hasChanged) {
// change is valid
hiddenCheck.hasChanged = false;
hiddenCheck.lastKnownValue = health;
} else {
if (hiddenCheck.lastKnownValue != health) {
// An illegal change has occured ! Punish the hacker !
}
}
}
}
try{
ApplicationInfo info = getPackageManager().
getApplicationInfo("com.cih.gamecih", 0 );
return true;
} catch( PackageManager.NameNotFoundException e ){
return false;
}
Если эта функция возвращает true, даже не позволяйте хакеру войти в многопользовательский режим и не предложите ему удалить его.
Люди, которые умеют обманывать игры, тоже читают эти форумы и знают все ваши маленькие секреты.
Не существует надежного способа предотвратить обман пользователей в игре, в которой хранятся важные переменные локально. Игра должна хранить эти переменные на сервере. Если эти переменные не хранятся на сервере, всегда найдется кто-то, кто сможет взломать вашу игру.
У меня есть мысль об этом, так как я иногда сам использую GameCIH. Вы можете иметь журнал транзакций с 10 записями, который проверяет каждую новую транзакцию.
Что бы вы сделали (так как GameCIH может работать только с одной переменной за раз), есть две переменные, которые сравниваются друг с другом.
- Исходное (или 11-летнее) значение
- Массив значений изменений от 1 до 10
- Значение суммирования, отрицается. (Это полностью меняет десятичное значение, которое вы можете видеть, и оно будет меняться не так, как исходное значение, когда в него будет свернута самая старая запись журнала.)
Если отрицательное значение суммы не соответствует оригиналу плюс 10 зарегистрированных транзакций, верните ошибку.
Вам просто нужно изменить способ обработки ваших статовых модов - если хотя бы один из них все же попытается изменить исходное значение напрямую, ваша игра вернет, что оно было изменено неправильно.
Рассчитайте свою статистику динамически из сохраненного значения.
private double getSaltedSqrt(int i){
return Math.sqrt(i)+1337;
}
private int getTrueValue(double i){
return (i-1337)*(i-1337);
}
Таким образом, ни один обычный человек не сможет найти ваши значения из оперативной памяти. Кто-то со 100 здоровья будет иметь значение здоровья 1347,0
Если кто-то наносит 10 урона этому игроку, вам просто нужно позвонить:
currentHealth = getSaltedSqrt(getTrueValue(currentHealth)-damage);
Однако наиболее безопасный способ сделать это - внедрить все эти изменения через сервер.
В играх покемонов они использовали DMA. Подобный эффект можно получить, отключив таймер и запустив обновление всех значений, пока игра приостановлена на очень короткое время. Обновление добавит некоторую случайную сумму ко всем переменным (включая ту, из которой вы вычитаете, чтобы получить отдельные значения). Вы также можете попробовать сохранить значения в большом массиве и изменить начальную позицию. Вместо абсолютного указателя типа GameState[121]
, у вас было бы что-то вроде GameState[121+StartingPosition]
и просто объедините значение-инкрементор с рандомизатором местоположения. Модульная арифметика - ваш друг в обоих случаях. Будьте осторожны с переполнением массива и ошибками. Переполнение буфера не было бы хорошо.;)
Если это было приложение Flash или Java: К сожалению, использование управления памятью для быстрого переназначения позиции в ОЗУ значений не так удобно, как в собственном двоичном файле, который использует Gameboy Advance. Копирование всех переменных во второй набор, в случайном порядке, затем удаление и сбор мусора исходных значений, вероятно, сделает вашу игру медленной и чертовски медленной.
Не могли бы вы просто проверить наличие root-прав при запуске игры? Тогда запретить запуск приложения или запретить многопользовательский режим на рутованных устройствах? Обеспечьте небольшую проверку на экране начальной загрузки только тогда, когда приложение инициализировано, возможно, имейте запрос приложения супер-пользователем, тогда, если пользователь разрешает ему, попытайтесь выполнить безвредную функцию, не разрешенную без суперпользователя, затем код, чтобы проверить, была ли упомянутая функция успешно, затем отменить изменение и выведите сообщение, указывающее, что пользователь должен выйти из корневого режима, попробуйте снова.
В качестве альтернативы эта проверка может применяться при входе в многопользовательский режим.
Также вы можете просто запустить многопользовательский режим с сервера и одного игрока с устройства и позволить одиночным игрокам свободно редактировать гексы.
Чтобы предотвратить обман памяти, вы можете выполнить одно из следующих действий:
- Храните наиболее важные значения в массивах цифр, а не в переменных
- Сохраняйте значение как строку, а также при каждом его изменении проверяйте, соответствует ли оно строке.
- Взгляните на классы MochiDigits из Mochi (Actionscript 3) и придумали порт Java. https://code.google.com/p/cunitescore/source/browse/trunk/as3/unitescore/mochi/MochiDigits.as?r=92
Вы должны хранить хеш (например, crc32 или md5) здоровья и т. Д. Каждый раз, когда вы обновляете значение, выполняйте проверку хеша на текущем установленном значении. В этом случае читеры должны будут написать отдельное приложение, которое обрабатывает хэши. Возможно, но это скоро остановит мошенников-сценаристов.