我很高兴地宣布 Frida 17.2.0 正式发布。本次发布的重点是让软件包发现变得极其简单。

查找现有的 Frida 专用软件包就是这么容易:

终端中显示的 frida-pm 搜索结果

使用其中任何一个软件包也同样简单:

终端中显示的 frida-pm 安装结果

亮点

  • 🔍 frida-pm search – 零干扰结果(按 keywords:frida-gum 过滤)。
  • 📦 一条命令即可安装 – 即使没有 Node.js,frida-pm install <pkg> 也能工作。
  • 🧩 编程接口 – 从 Python、C 等语言使用时具有相同的接口。

你在这里看到的是 frida-pm 命令行工具,它随 frida-tools 14.2.0 一同推出。 它的 Python 代码不到 300 行,因为它只是底层 Frida.PackageManager 实现的一层薄封装。

高级用户和软件包维护者通常仍会使用 npm、yarn 等工具,但我认为,如果要求初次接触 Frida 的用户同时熟悉更庞大的 JavaScript 生态系统,很可能会让他们不知所措并感到困惑。

frida-pm / Frida.PackageManager 的巧妙之处在于,搜索只会显示 Frida 专用软件包。 这是通过在搜索查询中内置 keywords:frida-gum 来实现的。

如果你在维护 Frida 专用软件包,请务必将 frida-gum 添加到 package.json 的 keywords 字段中。如果你的软件包是语言/运行时桥接,还请同时添加 frida-gum-bridge。

因此,可发现性是这里的一项关键功能。另一项功能是,它可以在没有 Node.js + npm 的系统上运行。 虽然我们默认使用 npm 的注册表作为后端,但你可以将它指向任何自己喜欢的注册表。

你还可以通过编程方式使用全部功能。例如,如果你想使用 Python 绑定执行搜索:

import frida

pm = frida.PackageManager()
result = pm.search("il2cpp", limit=3)
print(result)
print(result.packages)

你会看到类似下面的内容:

$ python search.py
PackageSearchResult(packages=[<3 packages>], total=13)
[Package(name="frida-il2cpp-bridge", version="0.12.0", description="A Frida module to dump, trace or hijack any Il2Cpp application at runtime, without needing the global-metadata.dat file.", url="https://npm.im/frida-il2cpp-bridge"),
 Package(name="frida-objc-bridge", version="8.0.5", description="Objective-C runtime interop from Frida", url="https://npm.im/frida-objc-bridge"),
 Package(name="frida-java-bridge", version="7.0.4", description="Java runtime interop from Frida", url="https://npm.im/frida-java-bridge")]
$

或者,你可能想安装几个软件包:

import frida

pm = frida.PackageManager()
result = pm.install(specs=["[email protected]", "frida-il2cpp-bridge"])
print(result)
print(result.packages)

运行后的结果可能类似这样:

$ python install.py
PackageInstallResult(packages=[<2 packages>])
[Package(name="frida-java-bridge", version="7.0.4", description="Java runtime interop from Frida"),
 Package(name="frida-il2cpp-bridge", version="0.12.0", description="A Frida module to dump, trace or hijack any Il2Cpp application at runtime, without needing the global-metadata.dat file.")]
$

添加安装进度也很容易:

import frida

def on_install_progress(phase, fraction, details):
    print({
        "phase": phase,
        "fraction": fraction,
        "details": details,
    })

pm = frida.PackageManager()
pm.on("install-progress", on_install_progress)
result = pm.install(specs=["frida-java-bridge", "frida-il2cpp-bridge"])
print(result)
print(result.packages)

输出可能类似下面这样:

$ python install.py
{'phase': 'initializing', 'fraction': 0.0, 'details': None}
{'phase': 'preparing-dependencies', 'fraction': 0.05, 'details': None}
{'phase': 'resolving-package',
 'fraction': -1.0,
 'details': 'frida-java-bridge@latest'}
…

我们已经看过如何从 Python 使用 PackageManager API,我或许还应该说明: 从 C 使用这个 API(几乎)同样简单:

#include <frida-core.h>

int
main (int argc,
      char * argv[])
{
  GCancellable * cancellable = NULL;
  GError * error = NULL;

  frida_init ();

  FridaPackageManager * manager = frida_package_manager_new ();

  FridaPackageInstallOptions * opts = frida_package_install_options_new ();
  frida_package_install_options_add_spec (opts, "[email protected]");
  frida_package_install_options_add_spec (opts, "frida-il2cpp-bridge");

  frida_package_manager_install_sync (manager, opts, cancellable, &error);
  if (error != NULL)
    g_printerr ("%s\n", error->message);

  return (error == NULL) ? 0 : 1;
}

如果你想试试这个示例,请从我们的发布页面下载 frida-core devkit。

你可以像下面这样构建并运行它:

$ gcc install.c -o install -I. -L. -lfrida-core -Wl,--gc-sections
$ ./install

(frida-core-example.c 顶部提供了一条示例命令行,它针对该 devkit 所适用的特定操作系统/架构进行了调整。)

请注意,可以通过传入 NULL 来省略 opts。在这种情况下,如果 package.json 中定义的软件包 尚未安装,或已安装版本不匹配,就会安装这些软件包。与 npm 一样,如果你没有 package.json 文件, 而是直接安装一些软件包,系统会为你创建 package.json。

本次发布还包含其他一些改进和修复:

  • Compiler:
    • 将 @frida/net 升级到 5.0.0。
    • 修复缺失的 shim 资源(感谢 @imlihe)。
  • frida-node:
    • 更改 Device.openChannel() 的返回类型,以公开带有 destroy() 的更具体类型。

要升级,请运行:

$ pip install --upgrade frida frida-tools

尽情享用吧!