前言:本文通过解析《神庙逃亡》游戏,解析smali注入的方法,看本文前请看最后的结语,我们还要破解他的签名校验机制,而这里略过不做。(懒。。)
样本:《神庙逃亡》
工具:AndroidKiller v1.3.1.0(AK) && JEB2
语言:Java,Smali
目的:Java层破解游戏,构建smali代码库
一、利用AK对样本进行反编译
二、运行《神庙逃亡》内购商店
这里我们取消购买弹出log。
三、获取运行时关键信息
观察monitor中的logcat
这里我们发现关键字符串onProductPuChaseFailed() called!,表示支付失败。
四、在JEB2中搜索该字符串
1、关键信息对应smali代码
2、反编译后的代码
这里我们试图对此方法进行交叉引用时发现无法追踪到其调用的方法怎么办呢?
五、smali注入代码
这里用到的smali语句是:
invoke-static{}, Ljava/lang/Thread;->dumpStack()V
插入此方法后我们可以查看方法onProductPurchaseFailed()方法调用过的方法,这里利用的是栈跟踪法:
效果如下:
这个区段就是其调用过的方法路径,我们从上到下一个个去跟踪会分析到关键方法。
这里的跟踪笔者就不做了,留给读者自己去跟踪,这里给一个提示:
resultCode == 110 购买成功
六、破解成功
这里直接展示破解成功后的效果:
七、建立自己的smali代码库
利用Android Killer的插入代码管理器可以很方便地组织管理自己的代码库,这里我列出几个用处较大的代码
#LoadLibrary
const-string v0, "so name"
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
#Log
const-string v0, "you message"
invoke-static {v0}, Lcom/android/killer/Log;->LogStr(Ljava/lang/String;)V
#LogUtils
#打印int,String,Intent ,HashMap ,List ,null
invoke-static {vx}, Lcom/mtools/logutils/LogUtils;->d(Ljava/lang/Object;)V
#打印float
invoke-static {vx}, Ljava/lang/Float;->valueOf(F)Ljava/lang/Float;
move-result-object v1
invoke-static {v1}, Lcom/mtools/logutils/LogUtils;->d(Ljava/lang/Object;)V
#打印double,如传入v0,则需要写成invoke-static {v0, v1}
invoke-static {vx, vx+1}, Ljava/lang/Double;->valueOf(D)Ljava/lang/Double;
move-result-object v1
invoke-static {v1}, Lcom/mtools/logutils/LogUtils;->d(Ljava/lang/Object;)V
#打印long,如传入v0,则需要写成invoke-static {v0, v1}
invoke-static {vx, vx+1}, Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;
move-result-object v1
invoke-static {v1}, Lcom/mtools/logutils/LogUtils;->d(Ljava/lang/Object;)V
#打印json
invoke-static {vx}, Lcom/mtools/logutils/LogUtils;->json(Ljava/lang/Object;)V
#打印xml
invoke-static {vx}, Lcom/mtools/logutils/LogUtils;->xml(Ljava/lang/Object;)V
#mothodTrace 用于追踪函数也可用来性能测试,需要读写权限
#mothodTraceStart
invoke-static {}, Landroid/os/Debug;->startMethodTracing()V
#mothodTraceStop
invoke-static {}, Landroid/os/Debug;->stopMethodTracing()V
#dump出函数堆栈, Thread.dumpStack();
invoke-static{}, Ljava/lang/Thread;->dumpStack()V
#Toast
const-string v0, "you message"
const/4 v1, 0x1
invoke-static {p0, v0, v1}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v0
invoke-virtual {v0}, Landroid/widget/Toast;->show()V
#等待调试
invoke-static {}, Landroid/os/Debug;->waitForDebugger()V
#写权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
#读权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
如果还有其他需要,详见github:
https://github.com/bingghost/SmaliLibrary
把里面的代码抠出来用即可。
八、结语
这里简单展示了smali注入的效果,并建立自己的smali代码库,且此破解过程并不完整,希望读者可以探索更加厉害的破解方式。另外此游戏有签名校验,我们可以通过charles代理来查找关键的url地址并去除即可,网上相关帖子较多,这里不再赘述。
PS:现在Android攻防战场已经转移到so甚至更深处,上述方法只能拿来娱乐~