http://www.myhack58.com/Article/html/3/7/2014/55348.htm
通过smali注入的方式插入自定义代码来监控app的行为数据,包括性能数据
以及部分逻辑数据,可以通过inline hook的方式在运行时监控应用的行为,笔者做了一个工具可以自动往apk中插入smali代码,
具体的步骤如下:
1、通过androguard解析apk文件,并获得dex文件;
2、通过baksmali将dex文件反编译为smali文件;
3、开始解析smali文件,将smali文件映射为内存数据结构;
4、分析smali文件,找出需要替换的方法关键字,并通过改写smali文件的方法注入代码;
当然这里面有很多细节问题需要解决,比如插入代码后会对原有的smali代码逻辑产生影响,如寄存器数量
增加,寄存器的的使用,跳转逻辑的影响,这些都需要你自己分析需要插入或者替换的代码上下文逻辑,使插入逻辑正确。
我下面以json为例,来详细描述如何替换smali代码:
json对象初始化的smali代码:
new-instance v3, Lorg/json/JSONObject; invoke-direct {v3, p0}, Lorg/json/JSONObject;-><init>(Ljava/lang/String;)V
第一行代码用来生成一个JSONObject对象,并放到v3寄存器中,第二行代码调用v3中JSONObject对象的init方法,
参数为存在p0寄存器(第一个参数)中的String对象 调用json对象格式化字符串jsonObject . toString,对应的smali代码如下:
invoke-virtual {v3}, Lorg/json/JSONObject;->toString()Ljava/lang/String; move-result-object v8
第一行代码调用v3中存放的json对象的toString方法,第二行代码将该返回值存放到v8寄存器中。
下面定义一个静态的方法,覆盖jsonobject对应的方法 :
public static String toString(JSONObject jsonObject) { String jsonString = jsonObject.toString(); Log.i("json toString:" + jsonString); return jsonString; }
ok,剩下的就是将smali代码里的逻辑改为调用上面的静态方法,替换后的内容如下:
invoke-static {v3}, Lcom/test/JsonReplace;->toString(Lorg/json/JSONObject;)Ljava/lang/String; move-result-object v7
init方法做同样的处理,这样就可以截获json对象的内容,从而可以监控使用json来上传数据的app内容,
如果在上面的方法开始和结束的地方获取系统时间,还可以用来获取json toString方法耗费的时间。
json方法只是众多可以捕获的方法之一,按照类似的逻辑还可以捕获更多您感兴趣的方法。
为了测试一下smali自动注入的成果,笔者下载了一个360安全卫士,进行了自动注入,此处需要注意的是,
修改完smali 后需要重新打包签名,而360安全卫士在启动时做了签名校验,如果发现签名不一致会弹出一个
对话框让你去下载应用并 退出,不过这也可以通过修改smali代码的方式来解决,可以找到签名校验的地方将
返回值改为1即可