在逆向分析的工作中,因为经常要面对海量的代码,往往都会尝试很多小技巧来高效准确的定位关键点, trace 便是其中之一,其他的在此篇就不展开了。
tracer 顾名思义就是用来追踪代码(执行)的工具,当然,根据需求的不同, tracer 也分几类,比如 trace 指令 、 trace 函数 、 trace 文件操作 等,本篇讲的是实现一个 Android Java 方法的 Tracer ,也是较为简单的一种。
现有的轮子>> frida-trace
可能有人会问, FRIDA 官网不就有一个 frida-trace 吗?不好意思,那个是用来 trace native code 的,并不支持Java方法。
Frida Android Tracer
Gi thub上面搜索类似关键词,能搜到各种各样的脚本,那咱直接用不就完了吗,还造撒子轮子..能用是能用,就是命令行刷的有点快,看得我眼睛疼。 还有的沙雕代码不支持多线程,所以结果跑完出来顺序都不对。 还有大部分,不能灵活的控制目标类名,要么只让选一两个类,要么全给你tra上然后崩掉。
综上所诉,我提出了三个需求:
1. 画个界面,带树结构的辣种。
2.支持多线程。
3.支持类名匹配。
因为现在都是Python写的多,所以我选了 Py3+PyQt5 。画界面我就不多赘述了,百度开发教程学一学画出来能看就行,树结构大概就是用 TreeView 一把梭,难度跟易语言差不多。
首先我们得实现一个就是获取到一个类里所有的方法,包括方法名和参数列表,也就是方法签名。 首先用 Java.use(classname) 获取到这个类的 Frida Wrapper ,然而虽然 Wrapper 里包含了这个类里的所有方法和字段,但其实并不能很友好的将所有method提取出来,因为 Wrapper 的声明是酱紫的...
所 以我决定使用
methods =wrapper.class.getDeclaredMethods() ;
.嗯,完美。
当然,这个获取到的是一个Java的handle, 并不是FRIDA的对象,所以还得把他们映射起来,然后用FRIDA来勾住,就像这个样子:
别纳闷 arguments 没定义是哪里来的,JS里每个 function 的作用域里都会有一个 arguments , 不需要定义。然后 method.apply(this|null, [args ]) == method(args)
Bridge
因为要把Hook和UI联动起来,所以我们得给他们定一个 通信协议 . 我的做法是使用一个 前缀 +json 来通知事件:
JavaScript 端:
Python 端:
炒鸡简单明了。
MultiThread
这个其实更简单, 直接调用API就可以
Filter
支持类名匹配这个事情,其实直接使用JS里的match就可以了,可以匹配正则表达式,所以我支持了两种模式,分别是E(qual)和M(atch),就是支持全等的类名,或者正则匹配的类名。同时还支持白名单和黑名单。
1. 崩溃率还是有,这种方式trace多了APP容易崩。
2. 眼睛不疼了...
3. 我把代码开源了: https://github.com/hluwa/ZenTracer , 而且代码里有本篇里没写的feature, 然后记得点star.
关于 这种方式 trace 多了 APP 容易崩 , FRIDA那个大胡子作者有一个叫 art-tracer 的仓库,那是利用开启系统自带的 Debug Trace 来实现同样的功能,相对来说会稳定很多。但是开关的位置不能确定,它是利用偏移来搜索,然而偏移也都不一样,所以想搞还得自己适配手机和完善代码,有兴趣的可以去读一下源码学习一下原理。
本文作者:万能钥匙SRC