Frida 17 以后 Python API 跑旧版 JS 报 Java is not defined ?一行 import 直接恢复 Frida 16 体验

Frida 17 以后 Python API 跑旧版 JS 报 Java is not defined?一行直接恢复 Frida 16 体验

前言

如果你最近把 Frida 升级到了 17.x,然后还在用 Python API 直接注入老式 JS 脚本,大概率已经见过下面这个错误:

python 复制代码
{'type': 'error', 'description': "ReferenceError: 'Java' is not defined", 'stack': "ReferenceError: 'Java' is not defined\n at (/script1.js:3)"}

最典型的场景就是这种老代码:

python 复制代码
import frida

session = device.attach(pid)
script = session.create_script(source)
script.load()

然后 source 里还是传统写法:

javascript 复制代码
Java.perform(function () {
  var Activity = Java.use("android.app.Activity");
  console.log(Activity);
});

在 Frida 16 时代,这种写法基本没什么问题。

但从 Frida 17 开始,桥接逻辑已经和以前不一样了,很多人一升级就直接踩坑。

所以我专门做了一个兼容库:frida-legacy-compat

它的目标很简单:

  • 不改你原来的 Python 注入习惯
  • 不要求目标机器安装 Node.js
  • 不要求你把旧脚本全面改造成 TypeScript / ESM
  • 只需要多加一行 import frida_legacy_compat
  • 然后继续直接 session.create_script(source)

Frida 17 到底改了什么?

从 Frida 17 开始,旧版 bridge 不再像 Frida 16 那样,默认跟随 Python API 的 plain JS 工作流直接可用。

也就是说:

  • 以前你写 Java.perform(...) 就能跑
  • 现在你直接 session.create_script(old_js),很可能就报:
javascript 复制代码
ReferenceError: 'Java' is not defined

如果按 Frida 17 新方式走,通常会遇到这些问题:

  1. 需要改成 TypeScript / ESM 编译
  2. 需要处理 bridge 包安装
  3. 有时候还需要额外下载 bridge
  4. 对"只想继续用老 JS + Python 注入"的用户来说,链路明显变复杂了

对于习惯 Frida 16 风格工作流的人来说,这个变化确实不太友好。

我做的这个库能解决什么?

frida-legacy-compat 就是专门为这个问题做的。

它会在导入后自动 patch:

python 复制代码
frida.core.Session.create_script()

补丁逻辑大概是这样:

  1. 检测你传入的脚本是不是旧版 bridge 风格
  2. 如果脚本里出现 Java. / ObjC. / Swift. 等全局对象
  3. 自动准备 bridge
  4. 自动编译成 Frida 17 能接受的 bundle
  5. 最后再调用原始 create_script()

用户感知上就一句话:

你原来怎么写,现在基本还怎么写。

安装方式

pip

bash 复制代码
pip install frida-legacy-compat

如果你想同时安装推荐范围内的 Frida:

bash 复制代码
pip install 'frida-legacy-compat[full]'

uv

bash 复制代码
uv add frida-legacy-compat

或者:

bash 复制代码
uv add 'frida-legacy-compat[full]'

最核心的使用方式

你原来的代码可能是这样:

python 复制代码
import frida

device = frida.get_usb_device()
session = device.attach("com.example.app")

source = """
Java.perform(function () {
  var Activity = Java.use("android.app.Activity");
  console.log(Activity);
});
"""

script = session.create_script(source)
script.load()

现在你只需要多加一行:

python 复制代码
import frida
import frida_legacy_compat

device = frida.get_usb_device()
session = device.attach("com.example.app")

source = """
Java.perform(function () {
  var Activity = Java.use("android.app.Activity");
  console.log(Activity);
});
"""

script = session.create_script(source)
script.load()

就这么简单。

一个更直观的 Demo:前台应用弹 Toast

下面给一个最直观的 Android 示例:

通过 USB 连接设备,attach 当前前台应用,然后直接调用原生 Toast。

python 复制代码
import time

import frida
import frida_legacy_compat


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


device = frida.get_usb_device()
app = device.get_frontmost_application(scope="full")
session = device.attach(app.pid)

source = """
setImmediate(function () {
  if (typeof Java === "undefined" || !Java.available) {
    console.log("[toast-demo] Java bridge is not available");
    return;
  }

  Java.performNow(function () {
    var ActivityThread = Java.use("android.app.ActivityThread");
    var Context = Java.use("android.content.Context");
    var JavaString = Java.use("java.lang.String");
    var Toast = Java.use("android.widget.Toast");
    var app = ActivityThread.currentApplication();

    if (app === null) {
      console.log("[toast-demo] currentApplication() is null");
      return;
    }

    Java.scheduleOnMainThread(function () {
      var text = JavaString.$new("frida-legacy-compat OK");
      var context = Java.cast(app.getApplicationContext(), Context);
      Toast.makeText(context, text, Toast.LENGTH_SHORT.value).show();
      console.log("[toast-demo] Toast shown");
    });
  });
});
"""

script = session.create_script(source)
script.on("message", on_message)
script.load()

time.sleep(5)
session.detach()

这个示例我自己已经用 PyPI 上发布的版本实际验证过,能够正常弹出 Toast。

这个库适合谁?

我觉得这类人会很需要:

  • 已经有一堆 Frida 16 风格旧项目的人
  • 习惯 Python 注入 + 直接写老式 JS 的人
  • 不想给目标环境增加 Node.js 依赖的人
  • 只想快速恢复生产力,不想全面重构现有脚本的人

当前兼容范围

目前这个库的版本策略是:

  • frida < 17:通常不需要本库
  • 17.0 <= frida < 17.2:不支持
  • 17.2 <= frida < 18:支持
  • frida >= 18:当前默认视为未验证

也就是说,当前最适合的使用范围是:

text 复制代码
Frida 17.2.x ~ 17.x

它和直接改写新式 Frida 工作流相比有什么区别?

如果你是新项目,或者准备长期完全拥抱 Frida 17 的新工作流,那直接按官方新的编译方式走也没问题。

但如果你是下面这种情况:

  • 老代码很多
  • 旧脚本积累多
  • 只是想让 Python API 下的旧脚本继续跑

那我更建议直接用这个兼容库。

因为它的价值不是"更先进",而是:

更省事、更少改动、更接近原来的使用习惯。

项目地址

GitHub:

text 复制代码
https://github.com/RYF5584/frida-legacy-compat

PyPI:

text 复制代码
https://pypi.org/project/frida-legacy-compat/

最后

如果你也踩过下面这种坑:

javascript 复制代码
ReferenceError: 'Java' is not defined

并且你只是想继续保持:

  • Python attach
  • session.create_script(source)
  • 老式 Java.perform(...)

那这个库应该正好适合你。

如果你觉得这个项目有帮助,欢迎去 GitHub 点个 Star,也欢迎提 Issue 反馈兼容问题。

相关推荐
张道宁5 小时前
从零开始训练YOLO手机检测模型:完整实战教程
python·yolo
快乐的哈士奇5 小时前
对话框打字机效果:Vur + Java/Python 实现
java·开发语言·python
ch.ju5 小时前
Java程序设计(第3版)第四章——类的组成
java·开发语言
我命由我123455 小时前
PHP - PHP 基本随机数生成函数
开发语言·ide·后端·java-ee·php·intellij-idea·intellij idea
malog_5 小时前
PyTorch图像数据加载实战指南
图像处理·人工智能·pytorch·python
博.闻广见5 小时前
AI_Python基础-4.标准库与IO
开发语言·python
程序猿编码5 小时前
大模型的“文字障眼法“:FlipAttack 文本反转越狱技术全解析
linux·python·ai·大模型
吃好睡好便好5 小时前
在Matlab中绘制质点运动轨迹图
开发语言·学习·算法·matlab·信息可视化
richard_yuu5 小时前
C#开发全景概述:从零读懂C#的定位、优势与完整技术体系
开发语言·c#