
1.配置frida环境,了解frida原理
2.从0到1编写frida脚本
3.了解frida的常用Api
1.教程Demo(更新)
2.jadx-gui
3.雷电模拟器
4.VS Code
Frida 是一款开源的动态插桩工具,可以插入一些代码到原生App的内存空间去动态地监视和修改其行为,支持Windows、Mac、Linux、Android或者iOS,从安卓层面来讲,可以实现Java层和Native层Hook操作。
项目地址
官网及使用文档
frida注入的原理就是找到目标进程,使用ptrace跟踪目标进程获取mmap,dlpoen,dlsym等函数库的偏移获取mmap在目标进程申请一段内存空间将在目标进程中找到存放frida-agent-32/64.so的空间启动执行各种操作由agent去实现
下载python

下载VS Code
汉化:在插件搜索Chinese,选择第一个插件安装重启即可
配置代码提示
点击下载
PS:版本一定要对应!!!

1.frida-ps -U 查看当前手机运行的进程
2.frida-ps --help 查看help指令
attach模式 :
frida_server自定义端口
logcat |grep "D.zj2595"日志捕获
adb connect 127.0.0.1:62001模拟器端口转发
静态方法
非静态方法
百度云
阿里云
哔哩哔哩
教程开源地址
PS:解压密码都是52pj,阿里云由于不能分享压缩包,所以下载exe文件,双击自解压
一篇文章带你领悟Frida的精髓(基于安卓8.1)
frida检测
IDA&Frida 学习
Frida工作原理学习(1)
frida源码阅读之frida-java
Art 模式实现XposedNativeHook兼容Android10
Frida 入门及介绍
https://bbs.kanxue.com/thread-278145.htm
[原创]FRIDA 使用经验交流分享
| 组件名称 |
功能描述 |
| frida-gum |
提供了inline-hook的核心实现,还包含了代码跟踪模块Stalker,用于内存访问监控的MemoryAccessMonitor,以及符号查找、栈回溯实现、内存扫描、动态代码生成和重定位等功能 |
| frida-core |
fridahook的核心,具有进程注入、进程间通信、会话管理、脚本生命周期管理等功能,屏蔽部分底层的实现细节并给最终用户提供开箱即用的操作接口。包含了frida-server、frida-gadget、frida-agent、frida-helper、frida-inject等关键模块和组件,以及之间的互相通信底座 |
| frida-gadget |
本身是一个动态库,可以通过重打包修改动态库的依赖或者修改smali代码去实现向三方应用注入gadget,从而实现Frida的持久化或免root |
| frida-server |
本质上是一个二进制文件,类似于前面学习到的android_server,需要在目标设备上运行并转发端口,在Frida hook中起到关键作用 |
| 工具 |
优点 |
缺点 |
| Xposed |
直接编写Java代码,Java层hook方便,可打包模块持久化hook |
环境配置繁琐,兼容性较差,难以Hook底层代码。 |
| Frida |
配置简单,免重启hook。支持Java层和Native层的hook操作 |
持久化hook相对麻烦 |
pip install virtualenvwrapper-win -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install virtualenvwrapper-win -i https://pypi.tuna.tsinghua.edu.cn/simple
mkvirtualenv 新建环境
rmvirtualenv 删除环境
mkvirtualenv 新建环境
rmvirtualenv 删除环境
pip install frida-tools -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install frida-tools -i https://pypi.tuna.tsinghua.edu.cn/simple
frida-ps --help
使用方式: frida-ps [选项]
选项:
-h, --help 显示帮助信息并退出
-D ID, --device ID 连接到具有给定ID的设备
-U, --usb 连接到USB设备
-R, --remote 连接到远程frida-server
-H HOST, --host HOST 连接到HOST上的远程frida-server
--certificate CERTIFICATE
与HOST进行TLS通信,期望的CERTIFICATE
--origin ORIGIN 连接到设置了"Origin"头为ORIGIN的远程服务器
--token TOKEN 使用TOKEN验证HOST
--keepalive-interval INTERVAL
设置心跳包间隔(秒),或设置为0以禁用(默认为-1,根据传输方式自动选择)
--p2p 与目标建立点对点连接
--stun-server ADDRESS
设置与--p2p一起使用的STUN服务器地址
--relay address,username,password,turn-{udp,tcp,tls}
添加与--p2p一起使用的中继
-O FILE, --options-file FILE
包含额外命令行选项的文本文件
--version 显示程序版本号并退出
-a, --applications 只列出应用程序
-i, --installed 包括所有已安装的应用程序
-j, --json 以JSON格式输出结果
frida-ps --help
使用方式: frida-ps [选项]
选项:
-h, --help 显示帮助信息并退出
-D ID, --device ID 连接到具有给定ID的设备
-U, --usb 连接到USB设备
-R, --remote 连接到远程frida-server
-H HOST, --host HOST 连接到HOST上的远程frida-server
--certificate CERTIFICATE
与HOST进行TLS通信,期望的CERTIFICATE
--origin ORIGIN 连接到设置了"Origin"头为ORIGIN的远程服务器
--token TOKEN 使用TOKEN验证HOST
--keepalive-interval INTERVAL
设置心跳包间隔(秒),或设置为0以禁用(默认为-1,根据传输方式自动选择)
--p2p 与目标建立点对点连接
--stun-server ADDRESS
设置与--p2p一起使用的STUN服务器地址
--relay address,username,password,turn-{udp,tcp,tls}
添加与--p2p一起使用的中继
-O FILE, --options-file FILE
包含额外命令行选项的文本文件
--version 显示程序版本号并退出
-a, --applications 只列出应用程序
-i, --installed 包括所有已安装的应用程序
-j, --json 以JSON格式输出结果
| 操作模式 |
描述 |
优点 |
主要用途 |
| CLI(命令行)模式 |
通过命令行直接将JavaScript脚本注入进程中,对进程进行操作 |
便于直接注入和操作 |
在较小规模的操作或者需求比较简单的场景中使用 |
| RPC模式 |
使用Python进行JavaScript脚本的注入工作,实际对进程进行操作的还是JavaScript脚本,可以通过RPC传输给Python脚本来进行复杂数据的处理 |
在对复杂数据的处理上可以通过RPC传输给Python脚本来进行,有利于减少被注入进程的性能损耗 |
在大规模调用中更加普遍,特别是对于复杂数据处理的需求 |
| 注入模式 |
描述 |
命令或参数 |
优点 |
主要用途 |
| Spawn模式 |
将启动App的权利交由Frida来控制,即使目标App已经启动,在使用Frida注入程序时还是会重新启动App |
在CLI模式中,Frida通过加上 -f 参数指定包名以spawn模式操作App |
适合于需要在App启动时即进行注入的场景,可以在App启动时即捕获其行为 |
当需要监控App从启动开始的所有行为时使用 |
| Attach模式 |
在目标App已经启动的情况下,Frida通过ptrace注入程序从而执行Hook的操作 |
在CLI模式中,如果不添加 -f 参数,则默认会通过attach模式注入App |
适合于已经运行的App,不会重新启动App,对用户体验影响较小 |
在App已经启动,或者我们只关心特定时刻或特定功能的行为时使用 |
| Spawn模式 |
|
|
|
|
frida -U -f 进程名 -l hook.js
frida -U -f 进程名 -l hook.js
frida -U 进程名 -l hook.js
frida server 默认端口:27042
taimen:/ $ su
taimen:/
taimen:/data/local/tmp
frida server 默认端口:27042
taimen:/ $ su
taimen:/
taimen:/data/local/tmp
| API名称 |
描述 |
Java.use(className) |
获取指定的Java类并使其在JavaScript代码中可用。 |
Java.perform(callback) |
确保回调函数在Java的主线程上执行。 |
Java.choose(className, callbacks) |
枚举指定类的所有实例。 |
Java.cast(obj, cls) |
将一个Java对象转换成另一个Java类的实例。 |
Java.enumerateLoadedClasses(callbacks) |
枚举进程中已经加载的所有Java类。 |
Java.enumerateClassLoaders(callbacks) |
枚举进程中存在的所有Java类加载器。 |
Java.enumerateMethods(targetClassMethod) |
枚举指定类的所有方法。 |
| 日志方法 |
描述 |
区别 |
console.log() |
使用JavaScript直接进行日志打印 |
多用于在CLI模式中,console.log()直接输出到命令行界面,使用户可以实时查看。在RPC模式中,console.log()同样输出在命令行,但可能被Python脚本的输出内容掩盖。 |
send() |
Frida的专有方法,用于发送数据或日志到外部Python脚本 |
多用于RPC模式中,它允许JavaScript脚本发送数据到Python脚本,Python脚本可以进一步处理或记录这些数据。 |
function main(){
Java.perform(function(){
hookTest1();
});
}
setImmediate(main);
function main(){
Java.perform(function(){
hookTest1();
});
}
setImmediate(main);
function hookTest1(){
var utils = Java.use("类名");
utils.method.implementation = function(a, b){
a = 123;
b = 456;
var retval = this.method(a, b);
console.log(a, b, retval);
return retval;
}
}
function hookTest1(){
var utils = Java.use("类名");
utils.method.implementation = function(a, b){
a = 123;
b = 456;
var retval = this.method(a, b);
console.log(a, b, retval);
return retval;
}
}
function hookTest2(){
var utils = Java.use("com.zj.wuaipojie.Demo");
utils.Inner.overload('com.zj.wuaipojie.Demo$Animal','java.lang.String').implementation = function(a,b){
b = "aaaaaaaaaa";
this.Inner(a,b);
console.log(b);
}
}
function hookTest2(){
var utils = Java.use("com.zj.wuaipojie.Demo");
utils.Inner.overload('com.zj.wuaipojie.Demo$Animal','java.lang.String').implementation = function(a,b){
b = "aaaaaaaaaa";
this.Inner(a,b);
console.log(b);
}
}
function hookTest3(){
var utils = Java.use("com.zj.wuaipojie.Demo");
utils.$init.overload('java.lang.String').implementation = function(str){
console.log(str);
str = "52";
this.$init(str);
}
}
function hookTest3(){
var utils = Java.use("com.zj.wuaipojie.Demo");
utils.$init.overload('java.lang.String').implementation = function(str){
console.log(str);
str = "52";
this.$init(str);
}
}
function hookTest5(){
Java.perform(function(){
var utils = Java.use("com.zj.wuaipojie.Demo");
utils.staticField.value = "我是被修改的静态变量";
console.log(utils.staticField.value);
Java.choose("com.zj.wuaipojie.Demo", {
onMatch: function(obj){
obj._privateInt.value = "123456";
obj.privateInt.value = 9999;
},
onComplete: function(){
}
});
});
}
function hookTest5(){
[内核课程]《Windows内核攻防实战》!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。
最后于 2024-7-15 23:11
被正己编辑
,原因: