前言
手游防破解防外挂技术方案(一)客户端篇
各种作弊方案中,其中一种是直接修改内存数据,如下。
若要修改玩家当前的金币数,先用工具在内存中搜索当前的金币数值,会搜出来很多内存地址。然后消耗一些金币,在之前的内存地址中再搜索当前的金币数,得到较少的匹配地址。重复该步骤,直到只剩一个地址匹配,就是存放金币的内存地址。最后,通过工具更改该地址存储的数值,就能把金币数改成一个很大的数值。
要防止这种工具的破解,就需要对内存数据做加密,让工具搜索不到该数据所在的内存地址。
今天看JEngine源码,发现有加密内存的处理,这篇讲一下是如何做的。
JEngine JInt
自定义类型
原理很简单,就是自定义基本类型,在get set时做一些特殊处理,比如这个框架定义的JInt
JInt
虚假数据
这个类需要有三个数据,真实值。 加密的key。加密后的值。
每次设置值的时候,生成一个随机数,和真实值混合重新生成一个加密后的值。
获取值的时候需要判断一下计算出来的原始值和真实原始值是否发生了变化,发生了变化,就代表修改了内存,进行相应的处理。
以上面修改金币为例。如果自己在内存中修改了金币原始值。在获取的时候。加密值和加密的key都没变,计算出来的真实的原始值就会和修改后的字不一样。
修改内存后的处理
AntiCheatHelper.OnDetected();
就是修改内存后的回调。这个可以自己设置。框架中是只打印了一条日志。
自己处理的话,检测到内存修改可以给服务器发个请求。服务器再做相应的处理。
其他类型
其他数据类型同理
问题
实际上这种并没有实现前言引用文章中所说的内存加密效果。
还是能很轻易的找到金币这块儿内存所在。只是加了一个监视效果,能让开发者知道内存被修改了。
如果要实现加密内存的话,应该是存取的时候进行加密与解密。但是这样又不能起到监视内存的效果,因为如果要监视内存就一定要存原始值。从而比较内存是否改变。不过加密后对于破解者直接找内存地址已经不容易了。