sktrace:基于 Frida Stalker 的 trace 工具

说一说 Stalker

我们常用 Frida hook天hook地,基于 FrIDA 的项目也遍地开花,是的 Frida 太好用了。其实 Frida 还有一些更为高级,强大的特性,例如 Stalker。
Stalker 是 Frida 中提供的代码跟踪引擎,可以在Native层方法级别,块级别,指令级别实现代码修改,代码跟踪。
其实 Stalker 很早就出现在 Frdia,但在 arm 上无法运行。最近 Frida 从 12.xx 版本直接跳到了 14.0,并且“Stalker ARM improvements” 几个大字在更新文档上赫然出现。欣喜的以为可以在 arm 上使用了,不幸的是试了一下却还是有问题,arm64 倒是还算正常。期待早日完美支持 arm。

实现原理:动态编译

Stalker 的目标是实现一个快速的,不被反调发现的,指令级别的代码追踪引擎,怎么能同时实现这些,答案是:动态编译。
官方的文档讲的很清楚,有兴趣的自己可以自己看看,会了解的比较透彻。
下面通俗的说意思自己的理解,有不对的地方还请大佬们指出哈。
Stalker 不像 InterC++eptor 一样直接在指令执行的地方做修改,Stalker 会重新开辟一块空间用于执行动态编译的代码,并且暴漏接口给用户来操纵动态编译的指令。Stalker 以基本块为基本的执行单元,从使用者的角度来说,每当执行到一个基本块,Stalker 都会做以下几件事:

  1. 对于方法调用,保存 lr 等必要信息
  2. 重定位位置相关指令,例如:ADR Xd, label
  3. 建立此块的索引,如果此块在达到可信阈值后,内容未曾变化,下次将不再重新编译(为了加快速度)
  4. 根据 transform 函数,编译生成一个新的基本块 GumExecBlock ,保存到 GumSlab 。
  5. 在上一过程中,可通过 void transform(GumStalkerIteRATor iterator, GumStalkerOutput output, gpointer user_data) 来读取,改动,写入指令。
  6. transform 过程中可通过 void gum_stalker_iterator_put_callout (GumStalkerIterator self,GumStalkerCallout callout, gpointer data, GDestroyNotify data_destroy) 来设置一个当此位置被执行到时的 callout。通过此 void callout(GumCpuContext cpu_context, gpointer user_data) 获取 cpu 信息。
  7. 执行一个基本快 GumExecBlock,开始下一个基本快

强大的 Stalker

transform 函数配合 put_callout 使得我们可以对每一个基本块做任何想做事,对于运行过程中进行解密的代码,也可以通过修改 trustThreshold 来监视解密过程。

sktrace

sktrace 是对 Stalker 最为简单的应用,实现了一个类似 IDA 指令 trace 的功能。另外对于每个寄存器的连续变化做了个统计,会更利于分析,如果出现连续四个可打印字符,会以字符串的形式打印出来。
暂时只是简单的写了一下,贴下地址:

https://github.com/bmax121/sktrace

拿大佬们玩的 ollvm9.apk 测试了一下:

python3 sktrace/sktrace.py -m attach -l libnative-lib.so -i JAVA_com_kanxue_ollvm_1ndk_MAInActivity_UUIDCheckSum com.kanxue.ollvm_ndk_9

软件页面:
804232_6QWGRU8FFXYFCA3

trace效果:
804232_UQVATA7HAKST67H

寄存器变化统计结果:
搜索页面上的字符串,就能够直接找到:
804232_VC3RK2UNZQB9FEF

over

 

标签