手游 反外挂
天道有轮回,苍天绕过谁。曾经都是我开外挂玩别人的游戏,现在轮到别人开挂玩我们的游戏了。说起外挂,我游戏生涯接触还算挺多了,从最开始单机游戏的金山游侠、金手指,到网游时代传奇的变速齿轮、DNF的封包外挂,到手游时代的葫芦侠、八门神器等各种内存修改器,很不好意的讲,我都用过……当然,我还是有原则,竞技游戏坚决不会开外挂。当下绝地求生颇受外挂困扰,各大主播因外挂嫌疑被锤得死去活来,外挂对于游戏的破坏力,可见一斑。
手游的反外挂和端游也有所区别。端游可以运行其他程序监控客户端,比如大名鼎鼎的腾讯TP。而手游由于操作系统权限的限制,很难能像端游一样用其他程序监控客户端,反外挂只能尽量做在客户端包里或者服务器上。
我们的游戏是unity做的一款ARPG游戏,上线两天后,就开始受到各种外挂的侵害。还好预先有为反外挂做了准备,通过封角色进行了打压。
题外话不多说,现在分享一下目前我们手游的反外挂方法。先分两个大块,一个是游戏本身架构设计,另一个是上报日志查外挂。
一、游戏架构的设计
游戏的架构设计之初就应该有反外挂的思想。首先,手游作为一种网络应用,网络通信内容的加密、登陆的token校验、客户端时间与服务器为准等最基础的做法肯定不能少。然后,做为网游,还得有更深入的反外挂策略。这里又分为客户端、服务器两种。
服务器:
1、“不信任”客户端数据的原则。理论上来说,对于绝大多数业务逻辑,都应该在服务器进行,客户端只上报用户的操作,服务器校验之后并进行业务处理,再把产生的结果返回客户端显示。例如客户端上报用户对某件装备进行了升级操作,服务器收到请求后,先校验用户是不是真的有这件装备,有的话才进行升级,然后把升级之后的结果返回客户端。而不能让客户端把装备升级之后通知服务器存储数据。这是最基础也最重要的原则,这个原则确保了客户端不能直接修改服务器的数据。
2、战报去重、校验。一般普通的手游,战斗逻辑都只跑的客户端,战斗结束之后上报结果给服务器。这就会存在客户端伪造战报的情况,比如没进战斗就发胜利战报、重复发起胜利战报等。之前阴阳师业原火bug,应该就是没有做好战报校验,玩家进入副本时进行切换,结果消耗扣的一个副本的,奖励却发的另一个副本的。我们的做法是,玩家进入某场战斗时,会生成一个票据号存在服务器并发给客户端。客户端上报战斗结果时携带返回。服务器比较保存的票据号和上报的票据号一致,才进行发奖,并且清除保存的票据号。
当然,这样只能对战报做一些简单的校验,针对修改战斗过程中客户端属性的作弊后面讲。
客户端:
客户端主要针对安卓包要做反外挂处理。
1、 防止二次打包。官方包发布之后,往往会被各种破解论坛破解并二次打包。大多数小白玩家开挂都是直接用这种非官方包。所以我们就需要识别出登陆的客户端是不是官方包。做法很简单,客户端登陆时上报包的签名(md5),服务器做校验,非官方包的签名就不让登陆。还有发布出去的官方包,最好做了代码混淆或者请专业的第三方加壳加固。
2、 存取数据时加密。使用过葫芦侠等内存修改外挂的应该都知道,玩家通过游戏界面上显示的数值,搜索内存,然后多次操作改变这个值继续搜索,逐渐缩小匹配的范围,最终确定出内存地址,修改内存地址上的数值,就会改变客户端的值。通过这种方法把战斗中的血量、攻击各种属性值改大而作弊。针对这种情况,解决的策略是保存的数值和客户端显示的数值不一致。比如说界面显示攻击1000,但是内存里存的值并不是1000,而是经过双向加密算法加密的值。存取时都通过加解密处理,不直接用内存地址上的值。让外挂搜不到真实值的内存地址。加密算法的选择倒是不必要复杂,简单的异或都可以。毕竟战斗中数值存取频繁,能达到效果就好。
二、上报日志查外挂
我们的游戏服务器由于已经做了上面说到的服务器反外挂原则,除了战斗逻辑,其他业务逻辑都是“不信任”客户端数据,所以业务逻辑没有被外挂突破。但由于我们游戏服务器并没有跑战斗逻辑,并且当时客户端也没做数值存取加密,所以战斗就成了外挂的重灾区。大多数手游战斗逻辑也都不会在服务器跑,因为每场战斗都要再服务器跑的话,服务器负载很大,王者荣耀的战斗逻辑也只是在客户端运行。(当然,也有服务器也跑战斗逻辑来同步战斗和反外挂的,比如天美的魂斗罗)。
我们通过客户端上报战斗过程中属性的变化日志,由服务器分析判定是否开挂。上报的信息例如进战斗和出战斗的属性对比、战斗中伤害和受伤信息、血量蓝量变化、技能释放间隔等信息。一些公共的校验的规则比如:
锁血:战斗中过程中受到了伤害,并且没有回血,但是战斗开始和结束时血量是一样的。
无敌:战斗中受到伤害为0
修改属性:战斗中的属性比进战斗的初始属性高出N倍
技能无CD:技能释放的间隔比配置的少
等等……通过这些上报日志,分析用户是否有开挂的嫌疑。但是这些通用的规则针对某种特殊的战斗玩法可能会有误判的情况。所以还要针对特殊的玩法做特殊的校验规则。
当发现有开挂嫌疑并不直接封号。毕竟现在流量成本越来越大。我们的策略是,一段时间内发现某个玩家被检测到外挂嫌疑超过一定次数(并且是免费玩家)的话,才直接封号;如果检测到的次数很少,则忽略,因为很可能是误判。如果检测到的次数还没达到直接封号的阀值(或者是冲了很多钱的付费用户)但是也有开挂嫌疑的话,提交人工处理。
当然,上面这种过了一段时间才判定是否开挂的策略,只是适用于PVE等对游戏环境影响不大的玩法。如果是竞技PVP玩法,这种秋后算账的办法显然不太及时。我们游戏有多人PVP,采用帧同步。由于服务器不跑战斗逻辑,所以只能从客户端的战报来判断。帧同步的原理保证了如果参战的客户端没开挂的话,所有客户端的战斗过程和结果是一样的。所以当同一场战斗超过三个人的时候,可以简单的通过比较战报相同数量来裁决正确的结果。但当只有两人时,如果两人的战报不一样,就很尴尬了,不能直接判定相信谁的战报,这时候就只有通过上面的校验方法判定谁更可信了。
暂时就总结这些了,大家还有什么反外挂心得欢迎讨论。
http://blog.csdn.net/best789248/