当前位置: 首页 > news >正文

frida 入门

一直想学 frida 一直鸽,终于有 ctf 用到了,我测东西这么多

官方文档感觉写的依托,这 python rpc 直接拿来入门真的太有生活了

frida 是一个动态插桩 (dynamic instrumentation) 工具,提供了交互式 cli 界面来追踪函数行为。用人话说就是允许用户从任意位置跳转执行自定义代码,用 js 代码片段 hook 原始程序的任意位置。具体而言,类似断点的实现方法,frida 会将 hook 入口处的汇编指令替换为跳转到 js 引擎的 jmp 指令,在 js 运行完毕时复原汇编代码。

典型的应用场景:从任意行号开始执行、替换任意函数的实现

文章目录

  • 安装
    • 安装类型补全
    • frida-gum 介绍
  • frida 使用:插桩 apk
    • 注入 frida-core 并启动 cli
    • 插桩安卓 Java 程序
      • frida hook Java 中动态加载的 dex
      • frida 调用额外 .dex 文件的函数
      • 在 activity 启动前附加 frida
      • 在 frida 中定义类,实现一个接口
      • 打印 stacktrace
    • 插桩安卓 so 原生代码
      • 按名字查找 export 函数
      • 按名字查找 module
      • 枚举 module 的符号
      • hook RegisterNative
      • 识别 jclass
      • 按地址 hook 函数
  • 使用 frida stalker 进行 assembly tracing
  • frida-python
  • MISC
    • 便捷命令 - frida-ps, frida-trace
    • 在 jailed iOS/Android 使用 frida
    • ref

安装

直接 pip install 即可。安装后会创建 frida, frida-ps 等命令。miniconda 会在切换时将 Scripts 添加到 PATH,在 windows 也可以直接用。

安装类型补全

利用 vscode 自动导入 ts 类型的机制,在 pwd 下 npm install @types/frida-gum 可以安装类型补全。这样之后写 js 的回调就有 type hint 了

frida-gum 介绍

上面依赖中出现的 gum 是 frida 的动态插桩核心库 Gum 的意思。Gum 用 C 开发,支持访问整个内存空间。考虑到 hook 的代码变化会很频繁,frida 又提供了一套脚本语言的 api GumJS ,为用户省去构建流程,缩短逆向开发时的反馈周期。

在运行时,GumGumJs 被打包成共享库注入到目标进程内。自定义脚本在用户进程中,通过 ipc 跨进程代理变量访问。这一打包、注入、双向通信的工作由 frida-core 完成。frida-core 包含了 frida 在目标机的主要功能,除了支持 gum 注入外,还包含 ps,枚举安装程序等功能。

frida 使用:插桩 apk

Frida 提供了简洁的语法,支持用户利用 js 的 api 通过字符串名称筛选符号,找到目标模块、目标类、目标对象或目标函数后,最后在 js 中检查传入参数和返回值、并支持用回调函数覆盖目标的实现。

Frida 依赖操作系统的调试 syscall 实现 hook (JVM, webasm 运行在 custom 解释器),因此天生依赖 OS,所以也会在用户体验上对 os 做很多优化。Frida 支持 Windows/Linux, Android, iOS, macos 等多种系统。被主要用于 Android/iOS, webasm 等环境。PC 系统上,Frida 只支持 Ring3 的部分特性因此不如其他平台好用,在这些平台常常需要其他工具来配合。

注入 frida-core 并启动 cli

注入 js 脚本的基础语法形如:

frida -U -f com.example.someapp -l hook.js

这个命令会在当前 shell 创建一个 REPL cli 交互环境,类似浏览器的 console,用户在里面敲命令回显结果。

  • -l 参数加载 js 脚本文件。和浏览器一样,加载 js 文件后,可以在 cli 敲符号名运行自定义的函数,也可以直接在 js 写 setImmediate(main) 加载后立即运行 main。frida 支持 js 脚本的热更新,在 js 文件 onSave 的时候会触发重新加载
  • -f 参数会 spawn 一个新的目标程序
  • -U 表示通过 USB 在目标设备上运行程序(而非当前客户机),调试移动端通常都会有 -U。理论上需要在手机上安装并启动 frida-server,但实测下来雷电模拟器似乎并不需要,不知道为啥

frida-server 在目标机运行 frida-core,并对外暴露一个 tcp 服务通信

插桩安卓 Java 程序

编写 hook.js 如下:

function main() {// Java perform 指进入 jvm 执行回调Java.perform(function() {var _class = Java.use('java.lang.String') // 从全限定名拿到 class// 根据名称直接访问成员,用类型 spec 重载函数。(变量和函数同名会将变量添加 _ 前缀)// .impl hook 函数实现_class.someMethod.overload("int", "int").implementation = function(arg0, arg1) {             var ret = this.someMethod(arg0, arg1) // this 访问原始函数console.log(arg0, arg1, ret) // 通过 log 打印return ret}let string = _class.$new("helloworld").getBytes()this.m.value = 0; // 直接设置变量值Java.choose // 从 cls 枚举所有 obj})
}setImmediate(main) // 异步执行 main 避免阻塞

常见开发模式:在 aosp java 的源码里搜索内部调用链,找一个合适的 hook 掉

frida hook Java 中动态加载的 dex

有些时候,Java 会在运行时动态加载 dex,frida 可能找不到。这是因为 frida 默认的 classloader 不一致,需要在 js 里通过 Java.enumerateClassLoaders 切换 classLoader.

frida 调用额外 .dex 文件的函数

逆向工程师可以自己写一个 Java 程序,用 d8 编译成 dex 文件后,通过 frida 的 openClassFile 加载到 frida 的 VM 里。之后,可以在 frida 中同样地用 Java.use 调用自己写的 Java 函数。

在 activity 启动前附加 frida

在启动 frida 时,指定 --no-pause -f 参数,并在 js 里 hook ActivityThread.getApplicationContext

在 frida 中定义类,实现一个接口

参看 api 文档的 Java.registerClass 节。可以实现一个新的类,用 js 编写类的成员函数,并实现接口条件。

打印 stacktrace

两种实现,既可以 hook Java 的 java.lang.Exception 类,查看文档选择 element。似乎也可以用 backtrace 的 api

插桩安卓 so 原生代码

动态库的导出其实和 js 有点像,会指明 import 和 export。在 IDA 可以看到有一个 exports 面板展示了所有导出的函数。对于 export 的函数,frida 可以直接通过函数名定位并 hook。对于其他函数,不管函数有没有导出,frida 都支持直接索引地址 hook,也可以 hook 到函数内部的任意汇编位置。

按名字查找 export 函数

借助 InterceptorModule.getExportByName 可以实现通过字符串符号名 hook 动态库 module 的函数。这里 Module 是专门用来处理动态库的组件,甚至可以写一个新 c 函数。回到 hook,文档里给的例子是 hook socket, inet 库的 send 函数,修改入参的 ip 地址以实现向别处发包。

const st = Memory.alloc(16);
// Now we need to fill it - this is a bit blunt, but works...
st.writeByteArray([0x02, 0x00, 0x13, 0x89, 0x7F, 0x00, 0x00, 0x01, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30]);
// Module.getExportByName() can find functions without knowing the source
// module, but it's slower, especially over large binaries! YMMV...
Interceptor.attach(Module.getExportByName(null, 'connect'), {onEnter(args) {send('Injecting malicious byte array:');args[1] = st;}//, onLeave(retval) {//   retval.replace(0); // Use this to manipulate the return value//}
});// Use Interceptor.replace to replace impl.

按名字查找 module

Process.findModuleByName, 见下节

枚举 module 的符号

如果是通过 JNIOnload 或其他方法动态注册的 Native 函数。被注册的 Native 函数本身并不是 export 的。此时可以 hook libart 的 RegisterNative 函数,劫持注册过程。

let libart_module = Process.findModuleByName("libart.so")
let symbols = libart_module.enumerateSymbols()for (var i = 0; i < symbols.length; i++) {var name = symbols[i].nameif (name.indexOf("RegisterNative")) {}
}

hook RegisterNative

识别 jclass

jclass 在底层只是一个序号,可以通过 frida-java-bridge 的 Env.getClassName 转换得到类名等信息

frida-java-bridge 提供了 jclass 的解析库,可以在直接使用。

Java.vm.tryGetEnv().getClassName(jclass)

按地址 hook 函数

通过地址 hook 有多种实现方法:

// 用 `Interceptor.attach` hook 特定地址。ptr 是 frida 的指针类
let base = Module.findBaseAddress("my.so")
Interceptor.attach(ptr("0x1234"), { // Or base.addonEnter(args) {console.log(args[0].toInt32());args[0] = ...}
});// 用 NativeFunction 封装二进制函数在 js invoke
// 用 Memory 在目标进程 malloc 内存,并在 invoke 传参新指针
const st = Memory.allocUtf8String("TESTMEPLZ!"); // See also: Memory.alloc(), Memory.protect()
const f = new NativeFunction(ptr("0x1234"), 'int', ['pointer']);// In NativeFunction param 2 is the return value type,// and param 3 is an array of input types
f(st);

由于安卓程序的入口是 Java,在 System.loadLibrary 之前 so 还没有加载。所以通常需要将 Interceptor 放到 loadLibrary 的 hook 回调里。或者也可以手动在 cli 执行函数。

Imyang 说,内联 hook(hook到函数内部的 asm)不如 hook 函数入口稳定。能用倒是

loader(动态 dex)

startActivity

stacktrace

使用 frida stalker 进行 assembly tracing

stalker 可以跟随线程的执行,跟踪每个函数、基本块和指令。

frida-python

官方文档乱的要死

rpc

MISC

便捷命令 - frida-ps, frida-trace

官方文档从这里入门,但对 cli 参数基本没有解释。我每次都很难对上脑电波,一定是 doc 写的依托答辩 :\

frida 除了 frida 命令外,还提供 frida-ps, frida-trace 等 cli 命令,帮助用户快速跟踪函数。

frida-ps 可以直接敲,类似 ps 可以打印进程的名字。

frida-trace 需要附加额外参数,例如 frida-trace -i "recv*" "Clash for Windows.exe" 会按照进程名称字符串或 pid 把 frida 附加到进程,然后 trace 所有以 recv 开头的受支持函数。frida-trace 会给每个监听函数生成 js 模板,用户可以修改回调脚本,热更新刷新 trace 的行为。

frida-trace 自动生成的模板包含 OnEnterOnLeave 两个关键函数,分别在目标函数进入和退出时同步调用。用户可以自定义回调函数的行为,支持覆盖参数和返回值。

{/*** Called synchronously when about to call recvfrom.** @this {object} - Object allowing you to store state for* use in onLeave.* @param {function} log - Call this function with a string* to be presented to the user.* @param {array} args - Function arguments represented as* an array of NativePointer objects.* For example use args[0].readUtf8String() if the first* argument is a pointer to a C string encoded as UTF-8.* It is also possible to modify arguments by assigning a* NativePointer object to an element of this array.* @param {object} state - Object allowing you to keep* state across function calls.* Only one JavaScript function will execute at a time, so* do not worry about race-conditions. However, do not use* this to store function arguments across onEnter/onLeave,* but instead use "this" which is an object for keeping* state local to an invocation.*/onEnter(log, args, state) {log("recvfrom()");log("recvfrom(socket=" + args[0].toInt32()+ ", buffer=" + args[1]+ ", length=" + args[2].toInt32()+ ", flags=" + args[3]+ ", address=" + args[4]+ ", address_len=" + args[5].readPointer().toInt32()+ ")");},/*** Called synchronously when about to return from recvfrom.** See onEnter for details.** @this {object} - Object allowing you to access state* stored in onEnter.* @param {function} log - Call this function with a string* to be presented to the user.* @param {NativePointer} retval - Return value represented* as a NativePointer object.* @param {object} state - Object allowing you to keep* state across function calls.*/onLeave(log, retval, state) {}
}

在 jailed iOS/Android 使用 frida

在 root 的 Android 下可以直接将 frida attach 到一个进程上,这被称为 inject mode

但在 jailed OS 上该功能可能受限。在这些设备上,Frida 提供 frida-gadget 动态共享库,开发者需要在编译应用时把 frida-gadget 加入到 lib 中,从而在应用启动时自带 frida 功能。这被称为 embed 模式。(我感觉主要用于调试而非逆向)

除了编译 so,官网也给了 其他途径 把 frida-gadget 嵌入到程序中,包括 LD_PRELOAD( DYLD_INSERT_LIBRARIES), patch binary

ref

http://littleshark.space/2024/08/25/Frida%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/Frida%E4%BD%BF%E7%94%A8%E5%A4%A7%E5%85%A8/

阿 b 直接搜 frida 看别人操作会直观很多:
https://www.bilibili.com/video/BV1wt4y1n7cq
https://www.bilibili.com/video/BV1G4sxemEuA

相关文章:

frida 入门

一直想学 frida 一直鸽&#xff0c;终于有 ctf 用到了&#xff0c;我测东西这么多 官方文档感觉写的依托&#xff0c;这 python rpc 直接拿来入门真的太有生活了 frida 是一个动态插桩 (dynamic instrumentation) 工具&#xff0c;提供了交互式 cli 界面来追踪函数行为。用人话…...

基于STM32的智能健康监测手环

1. 引言 随着可穿戴设备的普及&#xff0c;健康监测技术正逐步融入日常生活。本文设计了一款基于STM32的智能健康监测手环&#xff0c;能够实时采集用户心率、血氧饱和度、体温及运动数据&#xff0c;并通过低功耗蓝牙&#xff08;BLE&#xff09;与手机APP交互。该系统结合了…...

neo4j-community-5.26.0 install in window10

在住处电脑重新配置一下neo4j, 1.先至官方下载 Neo4j Desktop Download | Free Graph Database Download Neo4j Deployment Center - Graph Database & Analytics 2.配置java jdk jdk 21 官网下载 Java Downloads | Oracle 中国 path: 4.查看java -version 版本 5.n…...

Linux+Docer 容器化部署之 Shell 语法入门篇 【Shell 循环类型】

文章目录 一、Shell 循环类型二、Shell while 循环三、Shell for 循环四、Shell until 循环五、Shell select 循环六、总结 一、Shell 循环类型 循环是一个强大的编程工具&#xff0c;使您能够重复执行一组命令。在本教程中&#xff0c;您将学习以下类型的循环 Shell 程序&…...

WAWA鱼2024年终总结,关键词:成长

前言 本来想着偷懒一下&#xff0c;不写2024年终总结了&#xff0c;因为24年上半年还在忙毕业&#xff0c;下半年在忙转正&#xff0c;其实没什么太多好写的。结果被an_da和学弟催更了&#xff0c;哈哈哈&#xff0c;感谢大家对我近况的关注&#xff0c;学校内容基本都忘的差不…...

【Redis】hash 类型的介绍和常用命令

1. 介绍 Redis 中存储的 key-value 本身就是哈希表的结构&#xff0c;存储的 value 也可以是一个哈希表的结构 这里每一个 key 对应的一个 哈希类型用 field-value 来表示 2. 常用命令 命令 介绍 时间复杂度 hset key field value 用于设置哈希表 key 中字段 field 的值为…...

二分基础两道

Leetcode704: 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target &#xff0c;写一个函数搜索 nums 中的 target&#xff0c;如果目标值存在返回下标&#xff0c;否则返回 -1。 示例 1: 输入: nums [-1,0,3,5,9,12], target 9 输出:…...

Skyeye 云 VUE 版本 v3.15.7 发布

Skyeye 云智能制造&#xff0c;采用 Springboot winUI 的低代码平台、移动端采用 UNI-APP。包含 30 多个应用模块、50 多种电子流程&#xff0c;CRM、PM、ERP、MES、ADM、EHR、笔记、知识库、项目、门店、商城、财务、多班次考勤、薪资、招聘、云售后、论坛、公告、问卷、报表…...

位运算和操作符属性

位运算和操作符属性 除了课件中提到的那几种应用&#xff0c;其他时候一般先不考虑用这个原反补码 printf("%d\n,017")打印出来则是15 printf("%d\n,0017")打印出来也是15 printf("%d\n,0x017")打印出来是23eg:2进制转换为32进制则每5个2进制位…...

php的使用及 phpstorm环境部署

php语法 环境搭建&#xff1a;在小皮中新建网站&#xff0c;注意先填写域名再点击选择根目录。 成功创建网站后&#xff0c;打开发现forbidden&#xff0c;因为新建的网站里是空的&#xff0c;需要新建index.php文件----> 在Phpstorm中左上角打开文件&#xff0c;打开那个文…...

高阶开发基础——快速入门C++并发编程6——大作业:实现一个超级迷你的线程池

目录 实现一个无返回的线程池 完全代码实现 Reference 实现一个无返回的线程池 实现一个简单的线程池非常简单&#xff0c;我们首先聊一聊线程池的定义&#xff1a; 线程池&#xff08;Thread Pool&#xff09; 是一种并发编程的设计模式&#xff0c;用于管理和复用多个线程…...

Jupyterlab和notebook修改文件的默认存放路径的方法

文章目录 1.缘由2.操作流程2.1找到默认的路径2.2创建配置文件2.3修改配置文件内容2.4注意事项 1.缘由 我自己使用jupyterlab的时候&#xff0c;打开是在这个浏览器上面打开的&#xff0c;但是这个打开的文件路径显示的是C盘上面路径&#xff0c;所以这个就很麻烦&#xff0c;因…...

吴恩达深度学习——有效运作神经网络

内容来自https://www.bilibili.com/video/BV1FT4y1E74V&#xff0c;仅为本人学习所用。 文章目录 训练集、验证集、测试集偏差、方差正则化正则化参数为什么正则化可以减少过拟合Dropout正则化Inverted Dropout其他的正则化方法数据增广Early stopping 归一化梯度消失与梯度爆…...

享元模式——C++实现

目录 1. 享元模式简介 2. 代码示例 1. 享元模式简介 享元模式是一种结构型模式。 享元模式用于缓存共享对象&#xff0c;降低内存消耗。共享对象相同的部分&#xff0c;避免创建大量相同的对象&#xff0c;减少内存占用。 享元模式需要将对象分成内部状态和外部状态两个部分…...

【Go语言圣经】第五节:函数

第五章&#xff1a;函数 5.1 函数声明 和其它语言类似&#xff0c;Golang 的函数声明包括函数名、形参列表、返回值列表&#xff08;可省略&#xff09;以及函数体&#xff1a; func name(parameter-list) (result-list) {/* ... Body ... */ }需要注意的是&#xff0c;函数…...

win32汇编环境,窗口程序中使用进度条控件

;运行效果 ;win32汇编环境,窗口程序中使用进度条控件 ;进度条控件主要涉及的是长度单位&#xff0c;每步步长&#xff0c;推进的时间。 ;比如你的长度是1000&#xff0c;步长是100&#xff0c;每秒走1次&#xff0c;则10秒走完全程 ;比如你的长度是1000&#xff0c;步长是10&am…...

Vscode的AI插件 —— Cline

简介 vscode的一款AI辅助吃插件&#xff0c;主要用来辅助创建和编辑文件&#xff0c;探索大型项目&#xff0c;使用浏览器并执行终端命令&#xff08;需要多个tokens&#xff09;&#xff0c;可以使用模型上下文协议&#xff08;MCP&#xff09;来创建新工具并扩展自己(比较慢…...

Flink (十三) :Table API 与 DataStream API 的转换 (一)

Table API 和 DataStream API 在定义数据处理管道时同样重要。DataStream API 提供了流处理的基本操作&#xff08;即时间、状态和数据流管理&#xff09;&#xff0c;并且是一个相对低级的命令式编程 API。而 Table API 抽象了许多内部实现&#xff0c;提供了一个结构化和声明…...

Android --- handler详解

handler 理解 handler 是一套Android 消息传递机制&#xff0c;主要用于线程间通信。 tips&#xff1a; binder/socket 用于进程间通信。 参考&#xff1a; Android 进程间通信-CSDN博客 handler 就是主线程在起了一个子线程&#xff0c;子线程运行并生成message &#xff0c;l…...

[EAI-023] FAST,机器人动作专用的Tokenizer,提高VLA模型的能力和训练效率

Paper Card 论文标题&#xff1a;FAST: Efficient Action Tokenization for Vision-Language-Action Models 论文作者&#xff1a;Karl Pertsch, Kyle Stachowicz, Brian Ichter, Danny Driess, Suraj Nair, Quan Vuong, Oier Mees, Chelsea Finn, Sergey Levine 论文链接&…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...

HTML前端开发:JavaScript 获取元素方法详解

作为前端开发者&#xff0c;高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法&#xff0c;分为两大系列&#xff1a; 一、getElementBy... 系列 传统方法&#xff0c;直接通过 DOM 接口访问&#xff0c;返回动态集合&#xff08;元素变化会实时更新&#xff09;。…...

智能职业发展系统:AI驱动的职业规划平台技术解析

智能职业发展系统&#xff1a;AI驱动的职业规划平台技术解析 引言&#xff1a;数字时代的职业革命 在当今瞬息万变的就业市场中&#xff0c;传统的职业规划方法已无法满足个人和企业的需求。据统计&#xff0c;全球每年有超过2亿人面临职业转型困境&#xff0c;而企业也因此遭…...

ui框架-文件列表展示

ui框架-文件列表展示 介绍 UI框架的文件列表展示组件&#xff0c;可以展示文件夹&#xff0c;支持列表展示和图标展示模式。组件提供了丰富的功能和可配置选项&#xff0c;适用于文件管理、文件上传等场景。 功能特性 支持列表模式和网格模式的切换展示支持文件和文件夹的层…...

Spring AOP代理对象生成原理

代理对象生成的关键类是【AnnotationAwareAspectJAutoProxyCreator】&#xff0c;这个类继承了【BeanPostProcessor】是一个后置处理器 在bean对象生命周期中初始化时执行【org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization】方法时…...