一、Smali注入
Smali注入又称Smali插桩(Smali Instrumentation),WIKI解释:它是在保证被测程序原有逻辑完整性的基础上在程序中插入一些探针(又称为“探测仪”),通过探针的执行并抛出程序运行的特征数据,通过对这些数据的分析,可以获得程序的控制流和数据流信息,进而得到逻辑覆盖等动态信息,从而实现测试目的的方法。这里我们注意几个词,保证程序原有逻辑性、插入探针、抛出特征数据。这几个词也是我们samli注入需要关注的几个关键点所在。
二、调试环境
可以使用Apktool+eclipse(AS),或者Netbean
这里我的eclipse是比较老的版本,可能部分功能 新版对应有所不同,但这并不影响
三、Log类
SDK提供Android.util.Log类输出调试信息,总共有五种调试方法(v(),d(),i(),w(),e()),六种调试状态(verbose,debug,info,warning,error,assert).在插入时可以插入对应的方法进行调试,如果仅是输出对象的值,可以是v或者d()方法,这里需要注意,六种调试状态存在等级之分,依顺序排序,高一级的状态会覆盖低级的状态,这个如果对java语言比较熟悉的话,可以类比java语言的exception异常类。
四、插入Log类
(1)直接插入
可以直接在smali代码插入log类,寻找到需要插入的代码,如下图:
这里我们寻找到”UserSN”的变量V6寄存器,显然,打印v6里的值便是我们想要的注册码
插入如下代码:(注意这里的逗号等以及分号必须是英文的)
const-string v8 ,”tasfa”
invoke-static {v8,v6} ,Landroid/util/Log;-
>v(Ljava/lang/String;Ljava/lang/String;)I
打开eclipse,点击DDMS,或者直接在SDK工具包中找到DDMS
左下角点击+号,添加过滤信息
然后在模拟器中打开应用,随便输入一个注册码,可以在logcat界面看到如下:
将其输出输入到注册码一栏,可见程序成功被破解
缺点:
直接插入smali代码的话,简单的逻辑可能对寄存器没有什么严格的要求,如果是复杂的逻辑结构,或者程序本身使用的寄存器比较少,那么可能没法使用该方法
(2)增加寄存器法
一般在方法的前面都会声明寄存器的个数,如图:
只要增加一个寄存器,即.local 11那么就可以使用v10寄存器来代替上面的v8寄存器(关于这里寄存器的问题,可以参考之前的安卓逆向系列文章)
接下来的处理方法同前面
优点:不需要考虑使用哪个寄存器来做tag,减少了对程序的干扰
缺点:仍旧对程序产生一定干扰
(3)定制自定义log类
编写自定义的log类,只要将其放入同个文件夹中,然后,在smali代码中插入一句调用代码即可
文件名:crack.smali
.class public Lcrack;
.super Ljava/lang/Object;
.source "crack.java"
.method public static log(Ljava/lang/String;)V
.locals 1
.prologue
const-string v0, "tasfa" #注意这里的调试信息,可以修改
invoke-static {v0, p0}, Landroid/util/Log;-
>d(Ljava/lang/String;Ljava/lang/String;)I
return-void
.end method
插入的调用方法:
invoke-static/range {vx}, Lcrack;->log(Ljava/lang/String;)V
注意这里的vx是你想要输出的寄存器的名字,本例是V6
插入如图:
将crack.smali放入smali目录其子目录中,使用apktool回编译成apk,并签名,安装后进行logcat输出,可以使用上面的eclipse的DDMS方法
也可以使用下面的方法:
命令: adb logcat *:V
关于详细的过滤输出,请参考 《如何过滤 adb logcat 命令的输出》