程序员怎么通关羊了个羊

5,466 阅读9分钟

本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

前两天和同事聊天,同事A说,同事B也在玩羊了个羊啊!当时的我一脸懵,羊了个羊?是个啥?

羊了个羊?

可能我不太关注微博,从别人那儿才听说到这个游戏,那我必须紧跟潮流啊!于是我就打开微信小程序搜了一下《羊了个羊》这个小游戏。不得不说,这游戏真上(xia)头。刚打开的时候,我心里想的是:“就这?”,然后进入第二关,一开始还没觉得什么,直到后面,我感觉到了不对劲。大概刷了七八次,我就放弃了。然后过了一个小时...不行,我今天一定要把它通了!大概又刷了七八次,这什么破游戏!坑爹呢!

说实话,这个游戏,一开始我是看不上的,我认为这个游戏的真正厉害的地方,在于方块堆叠的设计,看似没有多少层,但是扒开一层,却发现还有下一层,当你觉得你越来越接近最后一层的时候,实则还在差的老远了;另外,看似随机打乱的方块,实则也需要精打细算每一步。我不知道真正通关这个小游戏的人有多少,但至少,我是没那个耐心的,大家尽可放心,不能通关这个游戏,只能证明这个方块的随机性和摆放的设计非常巧妙,并不能证明智商高低,至少从程序的角度来看,无非就是随机打乱而已。

直到后来,无意中看了别人的通(po)关(jie)教程,才发现原来这个游戏,还有另一个玩法

漏了个洞?

老实说,虽然我是做服务器的,但是在我印象中,认为微信小游戏还是相对比较安全的,毕竟有微信的加持,小程序的代码加密,混淆,加壳之类的安全保障应该会有吧?服务器端的话,接口的发送频率,幂等性判断,token校验,重发包,数据防护,包体加密等的防护也应该会有吧?可万万没想到的是,我在网上刷视频的时候,竟然也会刷到这类的破解视频,而且破解刷分的原理,也是简单到离谱。我猜测,可能人家小团队,也没有想到这么小的游戏会有这么高的热度?

本地修改

这是我第一个看到的破解方式,方法简单到离谱。几年前,我也用cocos写过一些微信小游戏,赚了一些小零花钱,虽然过去了一段时间了,但也还记得一部分。这个破解方法,也让我一眼看出来它是cocos写的。

直接通关

本地修改尚且需要修改文件,并且还要手动玩一下才能通关,接下来这个漏洞,就稍显严重了。 微信小程序本质是基于html+js的h5应用,只不过经过微信的一层封装,摇身一变,成了微信小程序。它的本质仍然是h5应用,既然是h5应用,那么请求和获取服务器的数据就一定是通过http请求。http的抓包工具又遍地都是,所以我们很容易就能抓取到我们在玩羊了个羊的过程中的所有请求数据。 如果我们通关一次羊了个羊,并进行抓包,就会发现,整个游戏过程都是单机进行,并且在游戏结束后向服务器请求了一个接口,这个接口名字叫做game_over。这就相当于,我们在自己手机上通关之后,再告诉服务器“我通关了”,服务器再记录下你的通关信息。

既然这样,我们岂不是可以省去手机上通关的过程,直接告诉服务器“我通关了”

还真就能这样!甚至直接使用get请求就够了!通过抓包我们可以看到,它的通关请求里,实际上是有带有一些参数的,为了不让服务器发现异常,我们也无需修改这些参数,只要让它帮我们记录通关数据即可。但是这些参数里并没有玩家相关信息,那么它怎么知道我是谁的呢?

这一点还算稍微有一点门槛,“有一点门槛,但不多”。在web开发中,最常用到的一个表示用户身份的东西叫做token,这个东西是一个临时身份认证,就像一个临时身份证,在它失效前,你用这个临时身份证,就可以代表你是谁,一旦过期,那么我就不认识你了。在羊了个羊这个游戏中,也有一个用户token,这个token是由微信给你分配的,不过它并没有放在请求参数中,而是藏在了http请求的header中,所有的请求的header中,都有一个叫t的值,它甚至不用token来作为变量名。不过看着这个乱序的字符串,大致也能猜出来, 它就是token。

而通关这个接口,就需要带上这个“t”的值。这样一来,服务器就能记录上你通关了。而这个接口,你请求几次,服务器就给你通关几次

其他破解

以上两种是我见到的最常见,操作也相对简单的破解方法。其实还有其他的破解方式,我就没做太深入的了解,因为大致原理其实是差不多的。比如有看到说能修改小程序的js代码,拥有无限道具的。甚至有能通过接口修改其他任何人的省份的(如果你发现的归属羊群一直在变,很可能是别人在反复修改你的定位)。 总的来说,方法都大同小异,关键在于游戏本身有没有对这些安全性做保护。

反了个思!

玩笑归玩笑,娱乐归于娱乐。看见别的bug,我们总是很开心的,但是我们也要时刻通过这些bug反思我们自己。如果是我,我要如何防范这些破解和刷分? 从羊了个羊这个游戏来看,对这个游戏的破解无非就分为两大类:本地修改客户端,和伪造消息给服务器

本地修改客户端

就算是说破了天,单机游戏想要破解都只是时间早晚的问题。别说微信小游戏了,主机游戏甚至游戏主机,都难逃命运,不是破不了,只是时间成本的问题。但我认为,我们还是可以通过以下方式来做安全防护:

1.资源文件加密处理

这也是我用到的第一个修改方式——修改关卡配置,但是如果配置文件本身做加密处理,或者打包成二进制文件等,机器认识,人不认识,那么也就很难做修改了。

2.内存防护

我之前项目有用到过腾讯提供的客户端加壳保护,一旦发现你通过内存修改器修改内存等违规操作,保护程序会立即杀死程序来做自我保护。以前我玩腾讯PC游戏的TP子程序,大致也是这个作用。

3.服务器校验

一般来说,就算是单机游戏,我们最好也需要有服务器来进行校验。 往简单了说,我们至少可以通过分析玩家的行为,比如通关时间过短,通过次数过多,或者点击次数过快等分析出玩家的异常行为。 往复杂了说,我们把单机改成服务器运行逻辑,或者单机和服务器分别运行逻辑,服务器来做数据校验。 总之,服务器参与的越多,本地修改数据的可行性越低

伪造消息包

这种方式需要抓包客户端和服务器的交互数据。一旦玩家发现了交互逻辑,则可以通过伪造相同的消息包来达到相同的效果。而这种方式,我们需要在服务端做好各种非法请求的校验。 从通用点来说,我们可以通过接口请求频率,ip访问限制,参数篡改校验等拦截一批非法请求。 从逻辑点来说,我们依然可以通过玩家的异常行为,来拦截玩家非法请求。

一键通关

一键通关的接口随意发送通关消息,就能无限通关,它的保护做的是远远不够的。从游戏逻辑上来说,羊了个羊每天是只能通关一次的,至少从这一点来说,如果对每天通关次数有拦截的话,就算是伪造消息,也只能一天通关一次;其次,重复伪造消息就需要重发消息包,只要对消息包加上时间戳或者事物id,保证同一个包只能请求一次,这也能拦截一大批重发的伪造消息包。

修改任意玩家地理位置

另外需要重点说的是,能通过接口请求修改其他人的定位地址,绝对是属于很严重的漏洞了。它的原理是直接请求修改地理位置的接口来达到修改玩家定位的效果,但是致命的是,它只需要传玩家的uid,就可以修改对应玩家的定位,但偏偏游戏大厅能请求到所有玩家的uid。这样的话,修改任意玩家的定位就显得十分容易。在这个接口中,最基础的,我们不能泄露玩家的关键信息在公共接口中,必须保证请求这个接口的一定是玩家本人;其次,修改地理位置这个操作理应也做一些限制,比如必须一天或一周或一个月才能修改一次。