Android-frida-hook-java层
adb基础命令
查看设备
连接设备
1 2 3 4 5 6 7 8
| adb [-d|-e|-s <serialNumber>] <command> 连接指定设备 参数: -d 指定当前唯一通过USB 连接的Android 设备为命令目标 -e 指定当前唯一运行的模拟器为命令目标 -s <serialNumber> 指定相应serialNumber 号的设备/模拟器为命令目标 command 为所需对设备执行的命令
|
示例:
1 2 3
| adb connect 127 0.0.1:7555 adb disconnect 127.0.0.1:16416 adb -s cf27456f shell
|
安装、卸载APP应用
1.安装应用
1 2 3
| adb install test.apk adb install -r demo.apk adb install -s test.apk
|
2.卸载应用
1 2
| adb uninstall cn.com.test.mobile adb uninstall -k cn.com.test.mobile
|
-k: 卸载 APP 但保留数据和缓存文件
停止进程
比如,还没进入root环境(su)就先启动了frida-server服务,可以先杀死进程,再进入su进入root环境,启动frida-server
1 2 3
| ps -a | grep frida-server # 查找进程 kill PID # 停止进程 kill -9 PID # 强制停止进程
|
启动frida-server服务
模拟器(雷电模拟器),到雷电模拟器安装目录下输入cmd,回车进入shell
1 2 3 4 5 6 7 8
| D:\Program Green\leidian\LDPlayer9>adb shell # 进入手机shell marlin:/ $ su # 进入root环境,#代表root,$代表没root,一般模拟器都有root,没有去开启就行 :/ # cd /data/local/tmp/ # frida-server安装路径, :/data/local/tmp # ls frida-x86_64 oat :/data/local/tmp # ./frida-x86_64 & # ./xxx 运行,&代表后台运行 [1] 2817 # PID,用ps -a 可以查找到进程和PID :/data/local/tmp #
|

电脑端,再打开一个命令行窗口进行端口转发,
1 2
| adb forward tcp:27042 tcp:27042 # frida默认转发端口为27042 adb forward tcp:27043 tcp:27043 # 不行就试试27043
|
frida hook java层
python+frida实现hook
1 2 3 4 5 6 7 8 9 10 11
| ''' spawn模式,Frida会自行启动并注入进目标App,Hook的时机非常早 '''
''' attach模式,Frida会附加到当前的目标进程中,即需要App处于启动状态,这也意味着只能从当前时机往后Hook, '''
|
python脚本
Frida.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
import frida import sys
def on_message(message, data): print(message)
session = frida.get_remote_device().attach('应用名') with open("./frida.js") as f: script = session.create_script(f.read()) script.on('message', on_message)
script.load() sys.stdin.read()
|
hook 普通java层函数
frida.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| function main() { console.log("脚本加载成功!"); Java.perform(function() { console.log("进入java层成功!!"); var MainActivity = Java.use('包名.类名') console.log("成功找到包名.类名!!!"); MainActivity.方法名.implementation = function (参数1, 参数2, ...) { var retval = 方法名(参数1, 参数2, ...); console.log("key:" + retval); return retval; } }); }
setImmediate(main);
|
hook java层重载(overload)函数
frida.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| function main() { console.log("脚本加载成功!"); Java.perform(function() { console.log("进入java层成功!!"); var MainActivity = Java.use('包名.类名') console.log("成功找到包名.类名!!!"); MainActivity.方法名.overload('类型1', '类型2', ...).implementation = function (参数1, 参数2, ...) { var retval = 方法名(参数1, 参数2, ...); console.log(参数1, 参数2, ...); return retval; } }); }
setImmediate(main);
|
java层主动调用
主动调用:强制调用一个函数去执行,直接执行函数,更具主动性
被动调用:有app的按照正常逻辑执行,需完成前置交互
java中类方法可分为:类方法和实例方法;
如果是类函数的主动调用,直接使用Java.use()函数找到类进行调用即可,
如果是实例方法的主动调用,则需找到对应实例后对方法调用,使用frida的api函数Java.choose()可以在java堆中找到指定类的实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| function main() { console.log("脚本加载成功!"); Java.perform(function() { console.log("进入java层成功!!"); var MainActivity = Java.use('包名.类名') console.log("成功找到包名.类名!!!"); MainActivity.方法名(参数1, 参数2, ...); Java.choose('包名.类名'), { onEnter: function (实例) { console.log("已找到实例" + 实例); 实例.方法(参数1, 参数2, ...); }, onCompelete: function () { console.log("完成" ); } }); }
setImmediate(main);
|
rpc及其自动化(修改python与js脚本)