frida学习及使用

文章目录

  • 安装frida
    • 安装python3.7
    • 设置环境变量
    • 安装pycharm和nodejs
  • 使用frida
    • 将frida-server push到手机设备中
    • 端口转发
    • 安装apk
    • 使用jadx查看java代码
    • 运行frida-server
  • frida源码阅读
  • frida hook方法
    • Frida Java层hoook
      • JavaHook.java
      • JavaHook.js
    • Frida native层hook 一
    • NativeHook.js

安装frida

Frida框架简介
Frida是一款基于Python + JavaScript的Hook与调试框架。
Firda是一款易用的跨平Hook工具,Java层到Native层的Hook无所不能,是一种动态 
的插桩工具,可以插入代码到原生 App 的内存空间中,动态的去监视和修改行为,
原生平台包括Win、Mac、Linux、Android、iOS全平台。环境配置步骤:
1.安装Python环境 3.72.安装frida模块打开Py输入命令:pip install fridapip install frida-toolspip uninstall fridapip uninstall frida-toolspip install frida==15.1.27pip install frida-tools==10.6.2google pixels 3a
frida=16.1.3
frida-tools=12.2.13.frida-server下载地址:查看版本信息:frida --versionhttps://github.com/frida/frida/releases下载安装frida server 版本和类型对应,框架和设备对应4.安装PyCharm 5.启动frida-server6.端口转发adb forward tcp:27042 tcp:270427.测试frida-ps -U	frida -U -f com.qianyu.fridaapp --no-pause

安装python3.7

在这里插入图片描述

设置环境变量

在这里插入图片描述

安装pycharm和nodejs

创建工程的时候,记得将鼠标所在的两个勾选框选上
在这里插入图片描述
在这里插入图片描述

使用frida

将frida-server push到手机设备中

在这里插入图片描述
在这里插入图片描述

端口转发

在这里插入图片描述

安装apk

使用jadx查看java代码

在这里插入图片描述

运行frida-server

我使用15.1.27版本的frida版本,在安卓手机上会报错。所以我果断升级了frida版本

sargo:/data/local/tmp # ./frida-server-15.1.27-android-arm64
{"type":"error",
"description":"Error: Unable to determine ClassLinker field offsets",
"stack":"Error: Unable to determine ClassLinker field offsets\n    at Ye (frida/node_modules/frida-java-bridge/lib/android.js:400:1)\n    at frida/node_modules/frida-java-bridge/lib/memoize.js:4:1\n    at ze (frida/node_modules/frida-java-bridge/lib/android.js:193:1)\n    at Oe (frida/node_modules/frida-java-bridge/lib/android.js:16:1)\n   at _tryInitialize (frida/node_modules/frida-java-bridge/index.js:29:1)\n    at new _ (frida/node_modules/frida-java-bridge/index.js:21:1)\n    at Object.4../lib/android (frida/node_modules/frida-java-bridge/index.js:332:1)\n    at o (frida/node_modules/browser-pack/_prelude.js:1:1)\n    at frida/node_modules/browser-pack/_prelude.js:1:1\n    at Object.22.frida-java-bridge (frida/runtime/java.js:1:1)",
"fileName":"frida/node_modules/frida-java-bridge/lib/android.js","lineNumber":400,"columnNumber":1}

frida源码阅读

在这里插入图片描述

frida hook方法

注意点:

  1. frida和frida-server版本号必须要一致
  2. hook的时候,必须要运行hook的程序,否则报错

Frida Java层hoook

JavaHook.java

# -*- coding: utf-8 -*-import os
import sys
import frida
import codecsdef message(message, data):if message["type"] == 'send':print("[*] {0}".format(message['payload']))else:print(message)process = frida.get_remote_device().attach('NDKDemo')
if not os.path.isfile('./JavaHook.js'):raise TypeError("./JavaHook.js does not exist")
with codecs.open('./JavaHook.js', 'r', 'UTF-8') as file:js_code = file.read()
script = process.create_script(js_code)
script.on("message", message)
script.load()
# script.exports.test()
# script.exports.test()
# script.exports.test()
# script.exports.test()
sys.stdin.read()# frida使用非标准端口
# /data/local/tmp # ./fs_12.7.22_arm64 -l 127.0.0.1:31928  默认端口: 27046
# process = frida.get_device_manager().add_remote_device('127.0.0.1:31928').attach('FridaApp')
# if not os.path.isfile('./JavaHook.js'):
#     raise TypeError("./JavaHook.js does not exist")
# with codecs.open('./JavaHook.js', 'r', 'UTF-8') as file:
#     js_code = file.read()
# script = process.create_script(js_code)
# script.on("message", message)
# script.load()
# sys.stdin.read()

JavaHook.js

// HOOK普通方法、静态方法
function Test01(){let loginActivity = Java.use('com.yijincc.ndkdemo.LoginActivity');loginActivity.login.implementation = function () {console.log("=============login===============");console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));console.log(arguments[0]);console.log(arguments[1]);this.login(arguments[0],arguments[1]);}
}// HOOK构造方法、重载方法
function Test02(){let intent = Java.use('android.content.Intent');intent.$init.overload('android.content.Context', 'java.lang.Class').implementation = function () {console.log("=============intent===============");console.log(arguments[0]);console.log(arguments[1]);this.$init(arguments[0],arguments[1]);}
}// HOOK内部类
function Test03(){let loginActivity$1 = Java.use('com.yijincc.ndkdemo.LoginActivity$1');loginActivity$1.onClick.implementation = function () {console.log("=============onClick===============");console.log(arguments[0]);this.onClick(arguments[0]);}
}// 主动调用构造方法
function Test04(){let money = Java.use('com.yijincc.fridaapp.Money');let obj = money.$new(1000,'RMB');console.log(obj.getInfo());
}// 操作对象里面的成员变量
function Test05(){let money = Java.use('com.yijincc.fridaapp.Money');let obj = money.$new(10000,'RMB');console.log(obj.name.value);console.log(obj.num.value);console.log('===============================');obj.name.value = 'RMB';obj.num.value = 10000000;console.log(obj.name.value);console.log(obj.num.value);
}// 主动调用普通方法
function Test06(){let money = Java.use('com.yijincc.fridaapp.Money');let obj = money.$new(2000,'RMB');console.log(obj.getInfo());
}// 获取当前类已有的实例实现主动调用普通方法
function Test07(){Java.choose('com.yijincc.ndkdemo.MainActivity',{onMatch: function(obj){ // 枚举时调用console.log(obj);console.log(obj.name.value);console.log(obj.age.value);console.log(obj.sex.value);console.log(obj.rand('B',99))}, onComplete: function(){ // 枚举完成后调用console.log("end");}});
}// 主动调用静态方法
function Test08(){let mainActivity = Java.use('com.yijincc.ndkdemo.MainActivity');console.log(mainActivity.isRel(444,444));
}// HOOK打印堆栈信息
// function Test09(){
//     let money = Java.use('com.yijincc.fridaapp.Money');
//     money.getInfo.implementation = function () {
//         console.log("=============getInfo===============");
//         console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
//         return this.getInfo();
//     }
// }// HOOK指定类的所有方法
function Test10(){let money = Java.use('com.yijincc.ndkdemo.MainActivity');let methods = money.class.getDeclaredMethods();for(let j = 0; j < methods.length; j++){let methodName = methods[j].getName();console.log(methodName);for(let k = 0; k < money[methodName].overloads.length; k++){money[methodName].overloads[k].implementation = function(){console.log('==========='+methodName+'===========');for(let i = 0; i < arguments.length; i++){console.log(arguments[i]);}console.log('===========end===========');return this[methodName].apply(this, arguments);}}}
}// 枚举已加载的所有类与枚举类的所有方法
function Test11(){let classes = Java.enumerateLoadedClassesSync();for(let i = 0; i < classes.length; i++){if(classes[i].indexOf("com.") !== -1){console.log("clazz:"+classes[i]);let clazz = Java.use(classes[i]);let methods = clazz.class.getDeclaredMethods();for(let j = 0; j < methods.length; j++){console.log("method:"+methods[j]);}}}
}// hook动态加载dex文件
function Test12(){// Java.enumerateLoadedClasses({//     onMatch: function (name, handle) {//         if (name.indexOf("com.example") >= 0) {//             console.log(name);//             let class6 = Java.use(name);//             class6.check.implementation = function () {//                 console.log("check:", this);//                 return true;//             };//         }//     }, onComplete: function () {}// });Java.enumerateClassLoaders({onMatch: function (loader) {try {if (loader.findClass("com.example.androiddemo.Dynamic.DynamicCheck")) {console.log(loader);Java.classFactory.loader = loader;      //切换classloader}} catch (error) {}}, onComplete: function () {}});let DynamicCheck = Java.use("com.example.androiddemo.Dynamic.DynamicCheck");console.log(DynamicCheck);DynamicCheck.check.implementation = function () {console.log("DynamicCheck.check");return true;}
}// 动态加载dex文件
function Test13(){// jar -cvf dex.jar com/example/androiddemo/StringUtils.class// dx --dex --output=dex.dex dex.jarlet dex= Java.openClassFile("/data/local/tmp/dex.dex");dex.load();let stringUtils = Java.use("com.example.androiddemo.StringUtils");console.log(stringUtils.tohexString("1234567890"));
}rpc.exports = {test:function () {Java.choose('com.yijincc.ndkdemo.MainActivity',{onMatch: function(obj){ // 枚举时调用console.log(obj);console.log(obj.name.value);console.log(obj.age.value);console.log(obj.sex.value);console.log(obj.rand('B',99))}, onComplete: function(){ // 枚举完成后调用console.log("============end============");}});}
}Java.perform(function () {Test01();// Test02(); // 重载方法// Test03(); // 内部类// Test04()  // 主动调用构造方法,创建一个对象// Test07();// Test08();// Test10(); // 打印所有的方法// Test11();//Test13();
});

Frida native层hook 一

通过IDA找到要hook的native函数(静态)
在这里插入图片描述base64魔改
在这里插入图片描述## NativeHook.py

# -*- coding: utf-8 -*-import os
import sys
import frida
import codecsdef message(message, data):if message["type"] == 'send':print("[*] {0}".format(message['payload']))else:print(message)process = frida.get_remote_device().attach('NDKDemo')
if not os.path.isfile('./NativeHook.js'):raise TypeError("./NativeHook.js does not exist")
with codecs.open('./NativeHook.js', 'r', 'UTF-8') as file:js_code = file.read()
script = process.create_script(js_code)
script.on("message", message)
script.load()
sys.stdin.read()# frida使用非标准端口
# /data/local/tmp # ./fs_12.7.22_arm64 -l 127.0.0.1:31928  默认端口: 27046
# process = frida.get_device_manager().add_remote_device('127.0.0.1:31928').attach('Android_crackme')
# if not os.path.isfile('./NativeHook.js'):
#     raise TypeError("./NativeHook.js does not exist")
# with codecs.open('./NativeHook.js', 'r', 'UTF-8') as file:
#     js_code = file.read()
# script = process.create_script(js_code) # 创建脚本
# script.on("message", message)
# script.load()
# sys.stdin.read()

NativeHook.js

// HOOK导出函数
function Test01(){// 用于在指定的模块中查找导出函数的地址let funGetFlag = Module.findExportByName("libnative-lib.so", "Java_com_yijincc_ndkdemo_LoginActivity_login");send("native: " + funGetFlag); // 基地址Interceptor.attach(funGetFlag, {onEnter: function(args){send("============getFlag===============");send(args[0]);send(args[1]);},onLeave: function(retval){send("============result===============");send(retval);// 获取JNIEnv*let env = Java.vm.tryGetEnv();// 将jstring 转换 const char*let str=env.getStringUtfChars(retval,0);send(str.readCString());}});
}// HOOK未导出函数
function Test02(){// 绝对地址=so模块起始地址(基地址)+偏移地址let baseAddr = Module.findBaseAddress("libnative-lib.so");send("baseAddr:"+baseAddr);// 指令集 分为ARM指令、thumb指令// ARM指令地址不变  thumb指令地址+1 sub_ 开头的函数 这种函数只能使用这种方式来进行Interceptor.attach(baseAddr.add(0x15F08), {onEnter: function(args){send("============encrypt===============");send(args[0]);send(args[1]);send(args[2]);console.log(hexdump(args[2], {offset: 0,length: 16,header: true,ansi: false}));// 获取JNIEnv*let env = Java.vm.tryGetEnv();// 将jstring 转换 const char*let str=env.getStringUtfChars(args[2],0);send(str.readCString());},onLeave: function(retval){send("============result===============");send(retval);// 获取JNIEnv*let env = Java.vm.tryGetEnv();// 将jstring 转换 const char*let str=env.getStringUtfChars(retval,0);send(str.readCString());}});
}// HOOK枚举导入函数信息
function Test03(){send("Test03")let imports = Module.enumerateImportsSync("libnative-lib.so");send(imports)for(let i=0;i<imports.length;i++){// if(imports[i].name.indexOf('raise') !== -1){send(imports[i]);// }}
}// HOOK枚举导出函数信息
function Test04(){send("Test04-start")send(device)let exports = Module.enumerateExportsSync("libnative-lib.so");send(exports)for(let i=0;i<exports.length;i++){if(exports[i].name.indexOf('Java_') !== -1){send("name:"+exports[i].name+"  address:"+exports[i].address);}}send("Test04-end")
}// 遍历模块列表信息
function Test05(){Process.enumerateModules({onMatch: function(exp){send(exp)if(exp.name.indexOf('libnative-lib.so') !== -1){send('enumerateModules find');send(exp);return 'stop';}},onComplete: function(){send('enumerateModules stop');}});
}// 读写内存数据
function Test06(){let mem_addr=Memory.alloc(20);//Memory.writeInt(mem_addr,0x1234567890abcdef);Memory.writeLong(mem_addr,0x1234567890abcdef);// console.log(hexdump(mem_addr));console.log(hexdump(mem_addr, {offset: 0,length: 20,header: true,ansi: true}));
}// 使用frida api读写文件
function Test07(){let file = new File("/data/data/com.yijincc.ndkdemo/yijincc.txt", "w");file.write("hello world!!!\\n");file.flush();file.close();
}// 基于主动调用libc.so里面的函数实现文件的读写操作
function Test08(){let addr_fopen = Module.findExportByName("libc.so", "fopen");send("1")let addr_fputs = Module.findExportByName("libc.so", "fputs");send("2")let addr_fclose = Module.findExportByName("libc.so", "fclose");send("3")let fopen = new NativeFunction(addr_fopen, "pointer", ["pointer", "pointer"]);send("4")let fputs = new NativeFunction(addr_fputs, "int", ["pointer", "pointer"]);send("5")let fclose = new NativeFunction(addr_fclose, "int", ["pointer"]);send("6")let filename = Memory.allocUtf8String("/data/data/com.yijincc.ndkdemo/yijincc.txt");send("7")let open_mode = Memory.allocUtf8String("w");send("8")let file = fopen(filename, open_mode);send("9")let buffer = Memory.allocUtf8String("hello world!!!\\n");send("10")let result = fputs(buffer, file);send("11")send("fputs:" + result);fclose(file);
}Java.perform(function () {// Test01();// Test02();// Test03();// Test04();// Test05();// Test06();// Test07();Test08();
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/20837.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

YOLOv5:使用7.0版本训练自己的实例分割模型(车辆、行人、路标、车道线等实例分割)

YOLOv5&#xff1a;使用7.0版本训练自己的实例分割模型&#xff08;车辆、行人、路标、车道线等实例分割&#xff09; 前言前提条件相关介绍使用YOLOv5-7.0版本训练自己的实例分割模型YOLOv5项目官方源地址下载yolov5-7.0版源码解压目录结构 准备实例分割数据集在./data目录下&…

xlrd与xlwt操作Excel文件详解

Python操作Excel的模块有很多&#xff0c;并且各有优劣&#xff0c;不同模块支持的操作和文件类型也有不同。下面是各个模块的支持情况&#xff1a; .xls.xlsx获取文件内容写入数据修改文件内容保存样式调整插入图片xlrd√√√xlwt√√√√√xlutils√√√√xlwings√√√√√…

【分布式能源选址与定容】光伏、储能双层优化配置接入配电网研究(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f308;4 Matlab代码、数据、讲解 &#x1f4a5;1 概述 由于能源的日益匮乏&#xff0c;电力需求的不断增长等&#xff0c;配电网中分布式能源渗透率不断提高&#xff0c;且逐渐向主动配电网方…

《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(15)-Fiddler弱网测试,知否知否,应是必知必会

1.简介 现在这个时代已经属于流量时代&#xff0c;用户对于App或者小程序之类的操作界面的数据和交互的要求也越来越高。对于测试人员弱网测试也是需要考验自己专业技术能力的一种技能。一个合格的测试人员&#xff0c;需要额外关注的场景就远不止断网、网络故障等情况了。还要…

BI报表工具有哪些作用?奥威BI全面剖析数据

BI报表工具有哪些作用&#xff1f;主要的作用是通过整合多业务来源数据&#xff0c;全面分析挖掘数据&#xff0c;来帮助企业实现数据化运营、支持智能决策、实现数据资产沉淀和增值、进行数据挖掘和预测分析、提高数据可读性和数据可视化程度等&#xff0c;从而提高企业的竞争…

51单片机学习--蜂鸣器播放音乐

由原理图可知&#xff0c;蜂鸣器BEEP与P1_5 相关&#xff0c;但其实这个原理图有错&#xff0c;实测接的是P2_5 下面这个代码就是以500HZ的频率响500ms的例子 sbit Buzzer P2^5;unsigned char KeyNum; unsigned int i;void main() {while(1){KeyNum Key();if(KeyNum){for(i …

1.初识typescript

在很多地方的示例代码中使用的都是ts而不是js&#xff0c;为了使用那些示例&#xff0c;学习ts还是有必要的 JS有的TS都有&#xff0c;JS与TS的关系很像css与less ts在运行前需要先编译为js&#xff0c;浏览器不能直接运行ts 目录 1 编译TS的工具包 1.1 安装 1.2 基本…

iphone备份用什么软件?好用的苹果数据备份工具推荐!

众所周知&#xff0c;如果要将iPhone的数据跟电脑进行传输备份的话&#xff0c;我们需要用到iTunes这个pc工具。但是对于iTunes&#xff0c;不少人都反映这个软件比较难用&#xff0c;用不习惯。于是&#xff0c;顺应时代命运的iPhone备份同步工具就出现了。那iphone备份用什么…

【Python】Web学习笔记_flask(3)——上传文件

用GET、POST请求上传图片并呈现出来 首先还是创建文件上传的模板 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>上传图片</title> </head> <body> <form action""…

maven发布到中央仓库

创建账号 https://issues.sonatype.org 【第二步】登录申请新项目 右上角点击Create&#xff0c;Project选择第一项&#xff0c;有的时候带不出来第二个New Project&#xff0c;可以再选一次Project的选项。

推荐两款github敏感信息搜集工具(gsil、gshark)

推荐两款github敏感信息搜集工具&#xff08;gsil、gshark&#xff09; - 云社区 - 腾讯云 (tencent.com) github敏感信息泄露是很多企业时常忽视的一个问题&#xff0c;国外有一份研究报告显示&#xff0c;在超过24,000份的GitHub公开数据中&#xff0c;发现有数千个文件中可能…

力扣 C++|一题多解之动态规划专题(2)

动态规划 Dynamic Programming 简写为 DP&#xff0c;是运筹学的一个分支&#xff0c;是求解决策过程最优化的过程。20世纪50年代初&#xff0c;美国数学家贝尔曼&#xff08;R.Bellman&#xff09;等人在研究多阶段决策过程的优化问题时&#xff0c;提出了著名的最优化原理&…

视频爬虫:解析m3u8文件 python m3u8库,m3u8文件中.ts视频流的解密下载

一、引用的库 这里需要引用的库是&#xff1a;from Crypto.Cipher import AES 有坑哈&#xff0c;python3.0之后直接安装crypto你会发现不管怎么着都会报错。 经过查找资料找到了原因&#xff0c;原来是20年之后crypto已经被pycryptohome替换掉啦&#xff0c; 如果之前安装过…

外网渗透信息收集漏洞挖掘

外网渗透信息收集&漏洞挖掘 信息收集一、“资产收集”的重要性二、企业信息收集之域名信息收集2.1、通过域名找到公司2.2、通过公司找到域名3.3、收集每个域名的⼦域名 三、企业信息信息收集之移动资产3.1、移动端APP收集3.2、微信⼩程序收集 四、信息收集流程漏洞挖掘一、…

开发框架软件公司:与之携手,共同开启办公流程化之路!

在快节奏的社会里&#xff0c;如何提高企业的办公效率&#xff1f;如何让各部门之间的协作关系更为顺畅&#xff1f;如何把企业内部的数据真正利用起来&#xff0c;成为高层做出经营决策的重要依据&#xff1f;其实&#xff0c;要做到这些&#xff0c;与开发框架软件公司联手合…

用户权限管理是保证企业图文档安全最有效的策略

企业拥有大量的图文档数据&#xff0c;涉及多个部门和员工&#xff0c;因此需要建立有效的用户权限管理策略&#xff0c;以保护图文档的安全。智橙平台将在线图文档管理与BOM系统的融合应用为企业提供了强大的权限管理功能&#xff0c;能够确保只有授权用户能够访问和编辑特定的…

item_get-小红薯-商品详情

一、接口参数说明&#xff1a; item_get-获得小红薯商品详情&#xff0c;点击更多API调试&#xff0c;请移步注册API账号点击获取测试key和secret 公共参数 名称类型必须描述keyString是调用key&#xff08;http://o0b.cn/iimiya&#xff09;secretString是调用密钥api_nameS…

Couldn‘t lock the file :/tmp/bbc-filesystem-base_syscache_service

解决方案&#xff1a; 进去带这个目录&#xff0c;然后切换成root用户&#xff0c;将它删除

spider-flow可视化爬虫界面从入门到放弃

目录 下载编译部署官网地址编译部署启动 简单使用输出文件方式可以正常执行的任务 自定义任务获取小说名 总结 下载编译部署 官网地址 修改端口、数据库、存放地址、执行文件等配置&#xff08;前后端不分离&#xff0c;配置文件端口即页面登录端口&#xff09; spider-flow-w…

《长安的荔枝》阅读笔记

《长安的荔枝》阅读笔记 2023年6月9号在杭州的小屋读完&#xff0c;作者以“一骑红尘妃子笑”的典故&#xff0c;想象拓展出来的荔枝使李善德&#xff0c;为了皇帝要求在贵妃寿辰&#xff0c;六月一号那天要吃到10斤的荔枝。需要从广州运送到长安即如今的西安。本来以为这个差事…