Frida 学习之路
2018年12月20日 · 1093 字 · 3 分钟 · Android Frida
Frida 简介
贴一段官方介绍
It’s Greasemonkey for native apps, or, put in more technical terms, it’s a dynamic code instrumentation toolkit. It lets you inject snippets of JavaScript or your own library into native apps on Windows, macOS, GNU/Linux, iOS, Android, and QNX. Frida also provides you with some simple tools built on top of the Frida API. These can be used as-is, tweaked to your needs, or serve as examples of how to use the API.
frida 是一款基于 python + javascript 的 hook 框架,可运行在 android、iOS、linux、win、osx 等各平台,主要使用动态二进制插桩技术。
安装环境
pip install frida frida-tools
然后去官网下载对应版本的手机端程序 frida-server:https://github.com/frida/frida/releases
注意这里一定要把 frida-server 版本和上面 PC 端安装的 frida 版本一致,我是用的是frida-server-12.2.27-android-arm64
# 下载完成之后记得先解压
xz -d frida-server-12.2.27-android-arm64.xz
# push 到手机上
adb push frida-server-12.2.27-android-arm64 /data/local/tmp/frida-server
开发流程
1. 启动 server
# 启动服务端
adb shell "chmod 755 /data/local/tmp/frida-server"
adb shell "su -c '/data/local/tmp/frida-server &'"
# 端口转发
adb forward tcp:27042 tcp:27042
adb forward tcp:27043 tcp:27043
# 查看 frida-server 是否启动成功,执行下面命令之后出现进程列表则表明启动成功
frida-ps -U
# 重启 frida
ps | grep frida
su kill -9 fridapid
./frida &
2. 编写 py 脚本
# 这是一个查看当前 app 的脚本
import frida
rdev = frida.get_remote_device()
front_app = rdev.get_frontmost_application()
print front_app
3. 运行脚本
python xxx.py
开发经验
1. Java 层 Hook 操作
Hook 之前 我们需要先了解一下 JavaApi
Java.perform(function () {});
// obtain a Javascript obj capable of handling interactions with each class
var myClass = Java.use(com.mypackage.name.class);
// Create a new instance of a class
var myClassInstance = myClass.$new();
// Access methods and attributes of the class
var result = myClassInstance.myMethod("param");
// overwrite the implementation of a method
myClass.myMethod.implementation = function (param) {};
Hook 的操作主要包括以下几点:
1、hook 方法包括构造方法和对象方法,构造方法固定写法是$init,普通方法直接是方法名,参数可以自己定义也可以使用系统隐含的变量 arguments 获取。
// hook 构造方法
myClass.$init.overload().implementation = function () {
send("arguments: " + arguments);
};
// hook 普通方法
myClass.myMethod.overload().implementation = function () {};
2、修改方法的参数和返回值,直接调用原始方法通过传入想要修改的参数来做到修改参数的目的,以及修改返回值即可。
myClass.myMethod.overload("java.lang.String").implementation = function () {
return this.myMethod("test") + "test";
};
3、构造对象和修改对象的属性值,直接用反射进行操作,构造对象用固定写法的 $new 即可。
// 构造对象
var myClassInstance = myClass.$new();
// 修改对象字段
val name = Java.cast(myClass.getClass(), clazz).getDeclaredField("name");
name.setAccessible(true);
name.get(myClass);
name.set(myClass, "new_name");
4、打印堆栈信息
var threadef = Java.use("java.lang.Thread");
var threadinstance = threadef.$new();
var stack = threadinstance.currentThread().getStackTrace();
send("Full call stack:" + Where(stack));
2. Native 层 Hook 操作
因为目前我在逆向分析分析的 app 里大部分破解工作在 java 层就完成了,所以 native 层的 hook 我暂时还没有用到过,推荐看一下四哥的Android 逆向之旅—Hook 神器家族的 Frida 工具使用详解
工具
这部分其实主要是为了更方便找到 Hook Point
可以参考 Xposed 学习之路 中的工具相关部分
实例
- Tracing API calls in Burp with Frida – Cedric’s Cruft
- mopsled - Log iOS method arguments with Frida
- Hacking Android apps with FRIDA I
- Hacking Android apps with FRIDA II
- MDSec Blog: Instrumenting Android Applications with Frida
- Introducción a Frida - SecurityInside.info
- SECCON 2015 – Reverse engineering Android APK 2 – 400 writeup – Cedric’s Cruft
- Pentesting Android Apps Using Frida - NotSoSecure
推荐插件及项目
其他
Frida 与 Xposed 相比感觉比较适合破解分析的工作,而且对 native hook 支持的也比较好,但是不能独立运行,xposed 插件开发完毕之后可以一直运行在手机里。
目前还在探索阶段,后续继续完善更多技巧..