本帖最后由 cdp20031308 于 2023-09-16 17:04 编辑
一、课程目标
1.配置frida环境,了解frida原理 2.从0到1编写frida脚本 3.了解frida的常用Api 二、工具
1.教程Demo(更新) 2.jadx-gui 3.雷电模拟器 4.VS Code 三、课程内容
1.什么是Frida?Frida 是一款开源的动态插桩工具,可以插入一些代码到原生App的内存空间去动态地监视和修改其行为,支持Windows、Mac、Linux、Android或者iOS,从安卓层面来讲,可以实现Java 层和Native 层Hook 操作。 项目地址 官网及使用文档 2.Frida原理及重要组件frida注入的原理就是找到目标进程,使用ptrace跟踪目标进程获取mmap,dlpoen,dlsym等函数库的偏移获取mmap在目标进程申请一段内存空间将在目标进程中找到存放frida-agent-32/64.so的空间启动执行各种操作由agent去实现 3.Frida与Xposed的对比4.Frida环境配置1.安装Python与VS Code下载python 下载VS Code 汉化:在插件搜索Chinese,选择第一个插件安装重启即可 2.虚拟环境的env的安装安装环境 pip install virtualenvwrapper-win -i https://pypi.tuna.tsinghua.edu.cn/simple
3.Frida安装以及多版本处理pip install frida-tools -i https://pypi.tuna.tsinghua.edu.cn/simple
配置代码提示 4.push Frida-server点击下载 PS:版本一定要对应!!!
5.Frida基础知识
1.基础指令1.frida-ps -U 查看当前手机运行的进程 2.frida-ps --help 查看help指令 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格式输出结果
2.操作模式:3.注入模式与启动命令:Spawn模式 frida -U -f 进程名 -l hook.js
attach模式 : frida -U 进程名 -l hook.js
frida_server自定义端口 frida server 默认端口:27042
taimen:/ $ su taimen:/ # cd data/local/tmp/ taimen:/data/local/tmp # ./fs1280 -l 0.0.0.0:6666
logcat |grep "D.zj2595" 日志捕获
adb connect 127.0.0.1:62001 模拟器端口转发
4.基础语法5.日志输出语法区别6.Hook框架模板function main(){ Java.perform(function(){ hookTest1(); }); } setImmediate(main);
6.Frida常用API1.Hook普通方法、打印参数和修改返回值//定义一个名为hookTest1的函数 function hookTest1(){ //获取一个名为"类名"的Java类,并将其实例赋值给JavaScript变量utils var utils = Java.use("类名"); //修改"类名"的"method"方法的实现。这个新的实现会接收两个参数(a和b) utils.method.implementation = function(a, b){ //将参数a和b的值改为123和456。 a = 123; b = 456; //调用修改过的"method"方法,并将返回值存储在`retval`变量中 var retval = this.method(a, b); //在控制台上打印参数a,b的值以及"method"方法的返回值 console.log(a, b, retval); //返回"method"方法的返回值 return retval; } }
2.Hook重载参数// .overload() // .overload('自定义参数') // .overload('int') function hookTest2(){ var utils = Java.use("com.zj.wuaipojie.Demo"); //overload定义重载函数,根据函数的参数类型填 utils.Inner.overload('com.zj.wuaipojie.Demo$Animal','java.lang.String').implementation = function(a,b){ b = "aaaaaaaaaa"; this.Inner(a,b); console.log(b); } }
3.Hook构造函数function hookTest3(){ var utils = Java.use("com.zj.wuaipojie.Demo"); //修改类的构造函数的实现,$init表示构造函数 utils.$init.overload('java.lang.String').implementation = function(str){ console.log(str); str = "52"; this.$init(str); } }
4.Hook字段function hookTest5(){ Java.perform(function(){ //静态字段的修改 var utils = Java.use("com.zj.wuaipojie.Demo"); //修改类的静态字段"flag"的值 utils.staticField.value = "我是被修改的静态变量"; console.log(utils.staticField.value); //非静态字段的修改 //使用`Java.choose()`枚举类的所有实例 Java.choose("com.zj.wuaipojie.Demo", { onMatch: function(obj){ //修改实例的非静态字段"_privateInt"的值为"123456",并修改非静态字段"privateInt"的值为9999。 obj._privateInt.value = "123456"; //字段名与函数名相同 前面加个下划线 obj.privateInt.value = 9999; }, onComplete: function(){
} }); });
}
5.Hook内部类 function hookTest6(){ Java.perform(function(){ //内部类 var innerClass = Java.use("com.zj.wuaipojie.Demo$innerClass"); console.log(innerClass); innerClass.$init.implementation = function(){ console.log("eeeeeeee"); }
}); }
6.枚举所有的类与类的所有方法function hookTest7(){ Java.perform(function(){ //枚举所有的类与类的所有方法,异步枚举 Java.enumerateLoadedClasses({ onMatch: function(name,handle){ //过滤类名 if(name.indexOf("com.zj.wuaipojie.Demo") !=-1){ console.log(name); var clazz =Java.use(name); console.log(clazz); var methods = clazz.class.getDeclaredMethods(); console.log(methods); } }, onComplete: function(){} }) }) }
7.枚举所有方法function hookTest8(){ Java.perform(function(){ var Demo = Java.use("com.zj.wuaipojie.Demo"); //getDeclaredMethods枚举所有方法 var methods =Demo.class.getDeclaredMethods(); for(var j=0; j < methods.length; j++){ var methodName = methods[j].getName(); console.log(methodName); for(var k=0; k<Demo[methodName].overloads.length;k++){ Demo[methodName].overloads[k].implementation = function(){ for(var i=0;i<arguments.length;i++){ console.log(arguments[i]); } return this[methodName].apply(this,arguments); } } } }) }
8.主动调用静态方法 var ClassName=Java.use("com.zj.wuaipojie.Demo"); ClassName.privateFunc("传参");
非静态方法 var ret = null; Java.perform(function () { Java.choose("com.zj.wuaipojie.Demo",{ //要hook的类 onMatch:function(instance){ ret=instance.privateFunc("aaaaaaa"); //要hook的方法 }, onComplete:function(){ //console.log("result: " + ret); } }); }) //return ret;
四、课后小作业
五、答疑
待更新 六、视频及课件地址
下方隐藏内容为本帖所有文件或源码下载链接:
游客你好,如果您要查看本帖隐藏链接需要登录才能查看,
请先登录
|