Unity 保护内存变量 Anti-Cheat Toolkit 反作弊

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/wangjiangrong/article/details/93021172

开发游戏的时候,往往我们需要对一些存放在客户端的重要的内存变量进行加密保护,防止被玩家利用一些修改器,修改其数据从而达到"开挂"的效果。

Unity Asset Store有一个反作弊包的插件Anti-Cheat Toolkit可以达到以上效果,官网地址:https://assetstore.unity.com/packages/tools/utilities/anti-cheat-toolkit-10395

这边提供一个下载地址:https://download.csdn.net/download/wangjiangrong/11250361

同时我们需要一款修改器来验证其效果,cheat ngine:https://www.cheatengine.org/index.php

模拟

接下来,我们可以写个小demo来模拟下所谓的修改内存数据。假设我们在玩魂斗罗的游戏,一共有五条命(存放在内存变量中,并用一个文本显示),每次死亡都会导致生命数-1(通过点击按钮模拟死亡)。直到生命为0时结束游戏。效果如下:

代码自然也很简单:

using UnityEngine;
using UnityEngine.UI;

namespace Test {
    public class NewBehaviourScript : MonoBehaviour
    {
        [SerializeField] Text text;
        [SerializeField] Button btn;

        //生命数
        public int live = 5;

        void Start()
        {
            text.text = "剩余生命:" + live;

            btn.onClick.AddListener(() => {
                live--;
                if (live > 0)
                {
                    text.text = "剩余生命:" + live;
                }
                else
                {
                    text.text = "游戏结束";
                }
            });
        }
    }
}

然后轮到我们的修改器登场了,首先我们启动unity,然后点击修改器的左上角类似小电脑的图标,选择我们的Unity进程,然后在右边输入我们要查找的内存变量的值(5即为当前生命值)。然后点击First Scan 按钮进行扫描,在左边的列表就就会帮你找到所有的值为5的内存变量的地址。

为了方便测试(因为内存中5的值特别多,扫描结果不直观)我们将测试的live值改为200,然后先First Scan 200的数据,接着,我们先点击Unity的Dead按钮,使值变为199,然后在Cheat Engine中将value的200改为199,点击Next Scan按钮

此时你会发现左边的列表中只剩两个值了,这对应的就是我们live的值,当你再点击dead按钮时,会发现这两个值中的value也会自动进行相应的变化(若列表中的值还较多的话,可以在进行dead = 197,然后value = 197,再next scan操作)

找到我们想要的值的物理地址后,接着就可以进行修改值的操作了,如图,输入我们想要修改的值即可。

整个操作的动图如下(生命值通过修改器直接从198变为5):

 

反作弊

通过上面的例子,我们知道了内存的数据是不安全的,所以我们需要进行一些加密处理,也就是之前所说的Anti-Cheat Toolkit 插件。将插件导入unity后,我们只需要对代码进行简单的修改即可,即将原始的int改为CodeStage.AntiCheat.ObscuredTypes.ObscuredInt,其余用法不变。

//生命数
public CodeStage.AntiCheat.ObscuredTypes.ObscuredInt live = 5;

然后使用工具的时候会发现,找不到对应的值了。

 

其他

Anti-Cheat Toolkit插件提供了很多加密的类型,如ObscuredFloat,ObscuredString,ObscuredVector3等等,其内部代码也不难理解,就是对原始数据进行了简单的异或处理,从而达到加密的效果。(原理:A^B=C,C^B=A)

同时还提供了ObscuredPrefs来替代PlayerPrefs。

至于其他的功能还需要再研究研究。。。

猜你喜欢

转载自blog.csdn.net/wangjiangrong/article/details/93021172