语言桥接

本页为社区译文;如有疑义,请以英文原文为准。 英文原文

从 Frida 17.0.0 开始,桥接不再随 Frida 的 GumJS 运行时一起提供。你可以在 发布说明中了解更多信息。这意味着用户现在必须明确引入自己想要使用的桥接。 不过,为了兼容现有脚本,Frida REPL 和 frida-trace 仍然捆绑了全部三种桥接。

目录

  1. REPL 和 frida-trace
    1. 使用纯 JavaScript
    2. REPL 自动编译
    3. 使用 frida-compile 手动编译
  2. 使用 API
    1. Python 示例
    2. Go 示例

REPL 和 frida-trace

我们将使用一个简单脚本,在屏幕上打印 ObjC.available。

// script.js
console.log(ObjC.available);

使用纯 JavaScript

由于 REPL 和 frida-trace 捆绑了全部三种桥接,其工作方式与以前完全相同。

$ frida -p0 -l script.js
     ____
    / _  |   Frida 17.0.5 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at https://frida.re/docs/home/
   . . . .
   . . . .   Connected to Local System (id=local)
Attaching...
true
[Local::SystemSession ]->

REPL 自动编译

REPL 也可以处理 .ts 文件:在空目录中使用 frida-create -t agent,即可建立 所需的项目框架。

使用 frida-compile 手动编译

你需要在脚本中添加相应的行,指定要使用的桥接(ObjC、Java、Swift):

  • import ObjC from "frida-objc-bridge"; - 用于 ObjC
  • import Swift from "frida-swift-bridge"; - 用于 Swift
  • import Java from "frida-java-bridge"; - 用于 Java

下面将重现前面的示例,也就是使用纯 JavaScript 打印 ObjC.available。

// script.ts
import ObjC from "frida-objc-bridge";

console.log(ObjC.available);

在空目录中初始化并安装必要的软件包:

$ frida-create -t agent
$ npm install
$ npm install frida-objc-bridge

然后编译 agent 并加载它:

$ frida-compile script.ts -o _agent.js -S -c
$ frida -p0 -l _agent.js
     ____
    / _  |   Frida 17.0.5 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at https://frida.re/docs/home/
   . . . .
   . . . .   Connected to Local System (id=local)
Attaching...
true
[Local::SystemSession ]->

使用 API

通过语言绑定提供的 API 实现这一功能,需要完成以下几步:

  • 编写脚本
  • 运行 frida-create -t agent
  • 安装所需的桥接,例如 frida-objc-bridge
  • 编写代码来编译脚本,并将其加载到进程中

Python 示例

import frida

def on_diagnostics(diag):
    print("diag", diag)

def on_message(message, data):
    print(message)

compiler = frida.Compiler()
compiler.on("diagnostics", on_diagnostics)
# script is located in /tmp, so we set project root to /tmp
bundle = compiler.build("script.ts", project_root="/tmp")

session = frida.attach(0)

script = session.create_script(bundle)

script.on("message", on_message)
script.load()

Go 示例

package main

import (
	"bufio"
	"fmt"
	"github.com/frida/frida-go/frida"
	"os"
)

func main() {
	comp := frida.NewCompiler()
	comp.On("diagnostics", func(diag string) {
		fmt.Printf("Diagnostics: %s\n", diag)
	})

	bopts := frida.NewCompilerOptions()
	bopts.SetProjectRoot("/tmp")
	bopts.SetSourceMaps(frida.SourceMapsOmitted)
	bopts.SetJSCompression(frida.JSCompressionTerser)

	bundle, err := comp.Build("script.ts", bopts)
	if err != nil {
		panic(err)
	}

	session, err := frida.Attach(0)
	if err != nil {
		panic(err)
	}

	script, err := session.CreateScript(bundle)
	if err != nil {
		panic(err)
	}

	script.On("message", func(message string, data []byte) {
		fmt.Printf("%s\n", message)
	})

	script.Load()

	r := bufio.NewReader(os.Stdin)
	r.ReadLine()
}