基于frida对代码进行验证,判断当前请求是否会执行此方法
一、python解释器
-
安装python 3.7.9
- https://www.python.org/downloads/release/python-379/
-
利用python3.7.9创建一个虚拟环境+项目
二、frida客户端
pip install frida==16.0.1 pip install frida-tools==12.0.1
三、frida-server
-
查看手机cpu架构
adb shell getprop ro.product.cpu.abi
-
下载对应cpu架构和版本的frida-server
- https://github.com/frida/frida/releases
- 解压并上传文件至手机
- 上传
adb push Path\to\frida-server-16.0.1-arm64 /data/local/tmp/
- 赋予可执行权限
>>>adb shell >>>su >>>cd /data/local/tmp/ >>>chmod 755 frida-server-16.0.1-android-arm64
- 上传
四、启动和Hook
-
手机端启动frida-server
>>>adb shell >>>su >>>cd /data/local/tmp >>>./frida-server-16.0.1-android-arm64
-
电脑端Hook
-
1、端口转发
import subprocess subprocess.getoutput("adb forward tcp:27042 tcp:27042") subprocess.getoutput("adb forward tcp:27043 tcp:27043")
-
2、获取进程(先打开app)
# 枚举手机上的所有进程 & 前台进程 import frida # 获取设备信息 rdev = frida.get_remote_device() # 枚举所有的进程 processes = rdev.enumerate_processes() for process in processes: print(process) # 获取在前台运行的APP front_app = rdev.get_frontmost_application() print(front_app)
-
3、Hook
-
python脚本
- attach模式:需要先运行App,再执行脚本
''' attach:需要先手动打开并运行app,再运行Hook脚本 ''' import frida import sys # 连接手机设备 rdev = frida.get_remote_device() session = rdev.attach("app名") # 应用名,比如:车智赢+ scr = """ Java.perform(function () { // 包.类 var 类名 = Java.use("包名.类名"); // 注意构造方法名:$init // 注意有重载的方法:类名.方法名.overload('参数类型').implementation;参数类型示例:boolean.class, int.class, '[B'(表示字节数组) 类名.方法名.implementation = function(参数){ // 调用方法前可以打印日志信息 var res = this.方法名.apply(this, arguments) 调用原有方法 // 调用原方法后可以打印日志信息 return res } }); """ script = session.create_script(scr) def on_message(message, data): print(f'{message} => {data}') script.on("message", on_message) script.load() sys.stdin.read()
- spawn模式:脚本自动重启App并进行Hook
''' spawn:脚本自动重启APP并进行Hook ''' import frida import sys # 连接手机设备 rdev = frida.get_remote_device() pid = rdev.spawn(["app包名"]) # 自动重启应用,并返回进程id session = rdev.attach(pid) scr = """ Java.perform(function () { // 包.类 var 类名 = Java.use("包名.类名"); // 注意构造方法名:$init // 注意有重载的方法:类名.方法名.overload('参数类型'),implementation xxx;参数类型示例:boolean.class, int.class, '[B'(表示字节数组) 类名.方法名.implementation = function(参数){ // 调用方法前可以打印日志信息 var res = this.方法名.apply(this, arguments) 调用原有方法 // 调用原方法后可以打印日志信息 return res } }); """ script = session.create_script(scr) def on_message(message, data): print(f'{message} => {data}') script.on("message", on_message) script.load() rdev.resume(pid) sys.stdin.read()
- attach模式:需要先运行App,再执行脚本
-
JavaScript脚本
-
demo.js
Java.perform(function () { // 包.类 var 类名 = Java.use("包名.类名"); 类名.方法名.implementation = function(参数){ // 调用原方法前可以打印日志信息 // console.log(`明文:${参数}`) //调用原有方法 var res = this.方法名.apply(this, arguments) // 调用原方法后可以打印日志信息 // console.log(`密文:${参数}`) return res } });
-
attach:先启动app,然后再在终端执行
frida -UF -l demo.js
-
spawn:脚本自动重启APP并进行Hook
frida -U -f 包名 -l demo.js
注意:输入q + 再点击回车则退出
- 命令行参数说明:
-U:表示使用 USB 连接方式与目标设备建立通信 -F:表示强制重新加载脚本。这样可以在脚本发生变化后不重启目标应用的情况下更新脚本,以便及时应用新的修改 -f:指定要监控的应用程序的包名或进程名,以便 frida 在启动时可以自动启动并监控该应用程序 -l:指定要加载的 JavaScript 脚本文件
-
-
-