“逃离大厦”游戏的破解
我们要破解一个游戏,首先要对该游戏有所了解,确定破解目标,发掘破解途径。因此,我们先安装该游戏并运行,出现如下界面:
这是一个Berry king游戏的推广广告,告诉我们安装该游戏可获得200金币。关掉该界面,进入游戏商店,我们可以在这里通过金币购买“提示”、“建议”、“大师”和“时间”,如下左图,左上角显示的是游戏者拥有的金币数,初始金币为100。这100金币要购买这些东西是不够的,因此我们首先需要花钱购买金币,如下右图所示。
我们破解的目的就是要做到不花钱能获取到“提示”、“建议”、“大师”和无限的“时间”。确定了破解目的,下面就来确定破解思路,我想到的思路有2条:
(1) 破解支付,达到不花钱购买金币的目的。
(2) 破解初始金币值,使之达到一个足够用来购买的数值。
我一开始想到的是第一种方法。可是修改后运行不了,logcat查看发现有VerifyError错误,以为有签名校验?搜索signature字符串,发现很多验证signature的地方,尝试把这些地方的返回值修改为真不管用。
后来重新反编译,不进行任何修改回编译,安装能正常运行,所以确定不是签名校验(现在想想也不一定啊,这只能证明在加载的时候没有签名验证啊)。暂时放弃,试试第二种方法吧。
由于没有多少破解游戏的经验,所以我想当然的认为金币的初始化应该是在程序初始运行的时候加载的,所以先看看MainActivity。看完了整个MainActivity.smali文件都木有找到线索,不过还是有点其它的收获,发现了开始运行时的游戏推广广告加载代码:
如果我们把判断Berry King是否安装的函数isAppInstalled的返回值改为TRUE,那么我们就不用安装该游戏也能获取到200金币了。不拿白不拿,果断将const/4 v0, 0x0改成const/4 v0, 0x1,重打包,签名安装运行,开始的推广广告就没出息了,并且显示安装了Berry king,加200金币。
加200金币是远远不够的,那我们应该从哪里去找金币初始化的地方呢?金币是要花钱购买的,如果我们搜索coin,money等关键词是不是会有收获呢?果不其然,在MoneyModel.smali文件中发现了金币的初始化代码。
MoneyModel类在构造函数中将money初始化为100,这100应该就是指的金币了。我们只需修改这个值就行了。我把它修改成了我的QQ号,如图所示(由于Java的float型不知道怎么转换成smali数值的,我是通过自己写一个包含该数据的apk,然后将其反编译出来得到的)。
打包,安装运行,可以看到破解成功了。左上角显示的金币数量约等于我的QQ号(加上原来破解游戏推广广告得到的200,貌似还多了几十个,不知道怎么回事,所以说是约等于)。现在我们已经有足够的金币数量来玩游戏了,是不是很爽啊。
不过,破解到此还木有结束。在玩的过程中,发现有广告弹出(如下图所示),老不爽了。我们还得把广告去掉。
我们在反编译的文件中发现com/google/android/gms/ads包,从而可以确定为GoogleAdMob广告。记得AdMob请求广告的函数为loadAd(),如果注释掉该方法应该就不会弹出广告了。于是搜索所有调用loadAd()方法的地方,把这些语句都给注释掉,重打包运行发现还是有广告弹出。胡乱捣腾了一阵,依然没有结果。没办法,只好查看Google Mobile Ads SDK,看添加广告的示例代码,从中查找线索。后来发现添加广告都需要通过setAdUnitId方法设置一个“中介ID”,如果没有这个“中介ID”,广告是否还能运行呢?果断注释掉调用setAdUnitId的代码,重打包运行,发现广告没有了。
注意:重打包的时候如果提示:无效寄存器,必须在0到15之间,那么就必须对寄存器进行类似如下转换:
move-object/from16 v2, p0