Русский
Русский
English
Статистика
Реклама

Как защитить данные игры на Unity в оперативной памяти?

image

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

В общем случае мы имеем профиль игрока с кучей параметров, который сериализуется в Saved Game и загружается/сохраняется при запуске/завершении игры. И если добавить шифрование при сериализации довольно просто, то защитить этот же профиль в RAM несколько сложнее. Постараюсь привести простой пример:

var money = 100; // "100" is present in RAM now (as four-byte integer value). Cheat apps can find, filter and replace it since it was declared.money += 20; // Cheat apps can scan RAM for "120" values, filter them and discover the RAM address of our "money" variable.Debug.Log(money); // We expect to see "120" in console. But cheat apps can deceive us!ProtectedInt experience = 500; // four XOR-encrypted bytes are present in RAM now. Cheat apps can't find our value in RAM.experience += 100;Debug.Log(experience); // We can see "600" in console;Debug.Log(JsonUtility.ToJson(experience)); // We can see four XOR-encrypted bytes here: {"_":[96,96,102,53]}. Our "experience" is hidden.

Второй момент, на который стоит обратить внимание внедрение новой защиты должно происходить с минимальным изменением исходного кода игры, где все уже отлично работает и протестировано много раз. В моем способе достаточно будет заменить типы int/long/float на ProtectedInt/ProtectedLong/ProtectedFloat. Далее я приведу комментарии и код.

Базовый класс Protected хранит зашифрованный массив байт в поле "_", он также отвечает за шифрование и дешифрование данных. Шифрование примитивное XOR с ключом Key. Такое шифрование быстрое, поэтому с переменными можно будет работать даже в Update. Базовый класс работает с массивами байт. Дочерние классы отвечают за преобразование своего типа в массив байт и обратно. Но главное, они маскируются под простые типы с помощью implicit operator, поэтому разработчик может даже не заметить, что изменился тип переменных. Вы также можете заметить атрибуты на некоторых методах и свойствах, они нужны для сериализации с помощью JsonUtility и Newtonsoft.Json (оба способа поддерживаются одновременно). Если вы не используете Newtonsoft.Json, то нужно убрать #define NEWTONSOFT_JSON.

#define NEWTONSOFT_JSONusing System;using UnityEngine;#if NEWTONSOFT_JSONusing Newtonsoft.Json;#endifnamespace Assets{    [Serializable]    public class ProtectedInt : Protected    {        #if NEWTONSOFT_JSON        [JsonConstructor]        #endif        private ProtectedInt()        {        }        protected ProtectedInt(byte[] bytes) : base(bytes)        {        }        public static implicit operator ProtectedInt(int value)        {            return new ProtectedInt(BitConverter.GetBytes(value));        }        public static implicit operator int(ProtectedInt value) => value == null ? 0 : BitConverter.ToInt32(value.DecodedBytes, 0);        public override string ToString()        {            return ((int) this).ToString();        }    }    [Serializable]    public class ProtectedLong : Protected    {        #if NEWTONSOFT_JSON        [JsonConstructor]        #endif        private ProtectedLong()        {        }        protected ProtectedLong(byte[] bytes) : base(bytes)        {        }        public static implicit operator ProtectedLong(int value)        {            return new ProtectedLong(BitConverter.GetBytes(value));        }        public static implicit operator long(ProtectedLong value) => value == null ? 0 : BitConverter.ToInt64(value.DecodedBytes, 0);        public override string ToString()        {            return ((long) this).ToString();        }    }    [Serializable]    public class ProtectedFloat : Protected    {        #if NEWTONSOFT_JSON        [JsonConstructor]        #endif        private ProtectedFloat()        {        }        protected ProtectedFloat(byte[] bytes) : base(bytes)        {        }        public static implicit operator ProtectedFloat(int value)        {            return new ProtectedFloat(BitConverter.GetBytes(value));        }        public static implicit operator float(ProtectedFloat value) => value == null ? 0 : BitConverter.ToSingle(value.DecodedBytes, 0);        public override string ToString()        {            return ((float) this).ToString(System.Globalization.CultureInfo.InvariantCulture);        }    }    public abstract class Protected    {        #if NEWTONSOFT_JSON        [JsonProperty]        #endif        [SerializeField]        private byte[] _;        private static readonly byte[] Key = System.Text.Encoding.UTF8.GetBytes("8bf5b15ffef1f485f673ceb874fd6ef0");        protected Protected()        {        }        protected Protected(byte[] bytes)        {            _ = Encode(bytes);        }        private static byte[] Encode(byte[] bytes)        {            var encoded = new byte[bytes.Length];            for (var i = 0; i < bytes.Length; i++)            {                encoded[i] = (byte) (bytes[i] ^ Key[i % Key.Length]);            }            return encoded;        }        protected byte[] DecodedBytes        {            get            {                var decoded = new byte[_.Length];                for (var i = 0; i < decoded.Length; i++)                {                    decoded[i] = (byte) (_[i] ^ Key[i % Key.Length]);                }                return decoded;            }        }    }}

Если что-то где-то забыл или натупил, пишите в комментариях =) Удачи в разработке!

PS. Котик не мой, автор фотки CatCosplay.
Источник: habr.com
К списку статей
Опубликовано: 05.09.2020 00:15:39
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Unity

Unity разработка шифрование защита

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru