Frida
是一款基于 Python + JavaScript
的 Hook
与调试框架。
Firda
是一款易用的跨平 Hook
工具, Java
层到 Native
层的 Hook
无所不能,是一种 动态 的插桩工具,可以插入代码到原生 App
的内存空间中,动态的去监视和修改行为,原生平台包括 Win、Mac、Linux、Android、iOS
全平台。
Frida
的功能如同油猴插件,通过油猴插件编写的脚本可以直接改变网页的编码方式。
大部分 App
对于我们来说都是黑盒,对 App
进行逆向和动态调试、或自动化分析、需要不断的进行动态调试,Frida
通过使用 Python
注入 JavaScript
脚本,都是通过 JS
脚本来操作设备上的 Java
代码。
如果需要持久化的 Hook
还是需要通过 Xposed
等框架,但是 Frida
的动态和灵活性对逆向和自动化逆向提供了很大帮助。
xposed
而言,frida
优势是其动态执行不需要重启。因为Frida大致原理是手机端安装一个server程序,然后把手机端的端口转到PC端,PC端写python脚本进行通信,而python脚本中需要hook的代码采用javascript语言。
第一、Xposed的优缺点
优点:在编写Java层hook插件的时候非常好用,这一点完全优越于Frida和SubstrateCydia,因为他也是Android项目,可以直接编写Java代码调用各类api进行操作。而且可以安装到手机上直接使用。
缺点:配置安装环境繁琐,兼容性差,在Hook底层的时候就很无助了。
第二、Frida的优缺点
优点:在上面我们可以看到他的优点在于配置环境很简单,操作也很便捷,对于破解者开发阶段非常好用。支持Java层和Native层hook操作,在Native层hook如果是非基本类型的话操作有点麻烦。
Frida
分为客户端和服务端。
客户端:PC(控制端)
服务器:手机设备(被控制端)
客户端编写的 Python
代码,用于连接远程设备,提交要注入的 JS
代码到服务端,接受服务端发来的消息。
服务端中需要用 JS
代码注入到目标进程,操作内存数据,给客户端发送消息。
➜ ~ pip install frida-tools
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple/
Successfully installed frida-12.5.7
➜ ~ frida --version
12.5.7
frida-ps
:查看当前系统进程,表示安装成功。http://www.gouzai.pw/2019/03/07/Frida%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E6%94%BE%E5%BC%83/
官网下载
adb shell getprop ro.product.cpu.abi
查看 CPU
架构
服务端的 Frida
版本必须和客户端的 Frida
版本一致。
adb root
adb push frida-server /data/local/tmp/
adb remount # 将system分区重新挂载为可读写分区
adb shell
su
cd /data/local/tmp/
chmod 777 frida-server
./data/local/tmp/frida-server
frida-ps -U
查看连接 USB
的进程。
也可以转发 android TCP
端口到本地:
adb forward tcp:27042 tcp:27042
adb forward tcp:27043 tcp:27043
可以使用以下命令可看远程服务端(安卓设备)运行进程情况 frida-ps -R
。
Hook
跟踪、拦截函数等import frida, sys
def on_message(message, data):
if message['type'] == 'send':
print("[*] {0}".format(message['payload']))
else:
print(message)
jscode = """
Java.perform(function () {
// Hook插入数据库
var SQLiteDatabase = Java.use('com.tencent.wcdb.database.SQLiteDatabase');
var Set = Java.use("java.util.Set");
var ContentValues = Java.use("android.content.ContentValues");
SQLiteDatabase.insert.implementation = function (arg1,arg2,arg3) {
this.insert.call(this, arg1, arg2, arg3);
console.log("[insert] -> arg1:" + arg1 + "\t arg2:" + arg2);
var values = Java.cast(arg3, ContentValues);
var sets = Java.cast(values.keySet(), Set);
var arr = sets.toArray().toString().split(",");
for (var i = 0; i < arr.length; i++){
console.log("[insert] -> key:" + arr[i] + "\t value:" + values.get(arr[i]));
}
};
});
"""
rdev = frida.get_remote_device()
session = rdev.attach("com.tencent.mm") # 获取指定APP
script = session.create_script(jscode)
# script.on('message', on_message)
print('[*] Running')
script.load()
sys.stdin.read()