smali结构
我们之前说过,安卓的dex文件存放的是开发者写的方法(即java代码)。而一个apk包经过反编译后,一个dex文件就会变成一个smali文件,当dex内的方法超过65535个,就会出现2个dex文件夹,即反编译会出现2个smali文件。
开发者开发时,一般会用com文件夹表示是作者自己写的代码。
贪吃蛇破解内购
代码分析
随便打开一个smali文件。
1 | .class public final Lcom/alipay/a/a/a; |
映入眼帘的第一行是"包名"+"类名"
其中的Lcom
中的L
表示的是java类型
的意思。
可以看到每一个smali文件中,最先都会声明类,接口等基本信息,这个就跟java是差不多的语法。
第9行到第16行:
1 | # direct methods |
invoke-direct
,一般是指调用private或init方法。
这里看似是把一个叫做p0的参数传给了init方法,其实不然,p0在dalvik的p方法中,一般代表的是本身的意思,类似于java当中的this。最后return-void
表示返回空就代表结束了。
在往下看19-50行。
1 | # virtual methods |
这里只谈一个很重要的点
goto:goto_0
与:goto_0
是一对,为什么这么说呢?他们叫做半标签,意味着不会自己运行,只能被别的地方goto过来,才会到goto_0的函数。
关键处破解
使用全局搜索支付失败
,这里要使用uncode转码,发现在smail/com/qy/zombie/zombie$3.smali
中有对应支付失败的提示码。
发现其属于的函数叫做payFailed
1 | .method public payFailed(Ljava/util/Map;I)V |
这个方法中,我们先不管上面的定义,从new-instance v1, Ljava/lang/StringBuilder;
这里开始
首先初始化了v1与v2,v1是一个stringbuilder类型,v2是支付失败的字符串。接着使用了append方法,将v2与v1拼接。又通过move-result-object v1
将拼接后的结果返回到v1,接着又使用了tostring方法,成功将v1变为一个字符串。
将v2定义为0,传参v0,v1,v2给maketext方法,又将所有结果传给v0,将v0传给传给show方法,意味着将结果v0打印出来。
在128行就直接调用了BuyFailed
方法。
那我们应该怎么破解该软件呢?既然有支付失败,就肯定有支付成功,我们可以不管支付失败还是支付成功,都调用BuySuceess(即支付成功方法)。在往下面翻,有关于支付成功的代码,
我们就复制这几行代码覆盖在PayFailed
里面得最后两行。
在之后重新编译后就可以实现了该软件得内购。