Skip to content

1.31 (108)

Choose a tag to compare

@wojiaoyishang wojiaoyishang released this 09 Jun 13:22
· 17 commits to master since this release

更新至 1.31 (108)

JS Runtime 作用域修复

  • 修复 Hook 回调、Java SAM 回调、Java.proxy() 回调和 MCP/RPC 回调之间无法共享 JS 顶层变量的问题。

  • 每个脚本 Runtime 现在会持有长期稳定的 Rhino global scope。

  • JS 回调执行时会优先回到函数创建时所属的 scope,避免回调过程中丢失顶层变量。

  • 顶层 letvar 和对象字段现在可以在以下场景中正常保持状态:

    • xposed.hook(...).intercept(function () {})
    • handler.post(function () {})
    • Java.proxy(...)
    • xhh.rpc.register_method(...)
  • 修复跨 Java callback 调用 JS 函数时作用域不一致的问题。

  • 修复部分脚本中全局变量在 Hook 回调内修改后,RPC 回调读取不到最新值的问题。

  • 修复 Rhino callback 重新进入时没有稳定使用原始 parent scope 的问题。

新增 xhh.global 全局状态接口

  • 新增 Java-backed 全局状态对象:

    • xhh.global
  • xhh.global 用于在同一目标进程内跨脚本、跨 Hook 回调、跨 RPC 回调保存运行期状态。

  • 新增接口:

    • xhh.global.set(key, value)
    • xhh.global.get(key)
    • xhh.global.has(key)
    • xhh.global.remove(key)
    • xhh.global.clear()
    • xhh.global.keys()
    • xhh.global.size()
    • xhh.global.snapshot()
  • xhh.global 可以保存普通 JS 值,也可以保存 Java 运行期对象。

  • xhh.global 适用于保存:

    • 最近一次 Hook 捕获的参数
    • 目标 App 对象实例
    • Method
    • Class
    • ClassLoader
    • 调试状态
    • 跨 RPC 调用的临时上下文
  • xhh.global 只保证同一目标进程内共享,不跨进程共享。

  • 明确说明不同 Android 进程之间内存隔离,不能通过 xhh.global 共享 MethodClassLoaderthisObject 等运行期对象。

Java Bridge JS 到 Java 参数转换优化

  • 优化 JS 向 Java 传递参数时的类型边界。
  • 当参数是普通 JS 值时,会继续根据目标 Java 方法签名自动转换。
  • 当参数已经是 Java 对象、Java wrapper 或 Rhino 原生 Java 对象时,不再重复转换,直接传递给 Java 层。
  • 修复显式传入 Java 包装类型后仍被转换成 JS number 的问题。
  • 修复 Integer.valueOf(...) 等 Java 返回值再次传入 Java 方法时被误转为 Double 的问题。
  • 修复 Method.invoke(...) 调用时无法按真实目标方法签名转换参数的问题。
  • java.lang.reflect.Method.invoke(...) 现在会根据被调用方法本身的参数类型处理 JS 参数。
  • 修复反射调用目标参数为 int 时,JS number 被错误传递为 java.lang.Double 导致 IllegalArgumentException 的问题。
  • 保留 Java 到 JS 的既有传递逻辑,不改变 Hook 参数、返回值和已有 API 的脚本读取方式。

RPC 参数对象访问优化

  • 优化 xhh.rpc.register_method(name, callback) 中回调参数的 JS 访问体验。

  • RPC/MCP 传入的 JSON 字典参数继续支持点访问:

    • params.data
    • params.key
    • params.iv
    • params.mode
  • 保持兼容旧写法:

    • params.get("data")
    • params.has("data")
    • params.keys()
  • RPC 参数中的数组值支持常见 JS 访问方式:

    • params.items[0]
    • params.items.length
    • params.items.get(0)
  • 修复 RPC 参数直接作为 Java Map 暴露时无法使用 params.xxx 点访问的问题。

  • 保持 RPC 返回值继续经过 JS 友好转换,便于 WebIDE 和 MCP 客户端读取。

Java Bridge 反射调用稳定性修复

  • 修复 JavaObjectWrapper 调用 java.lang.reflect.Method.invoke(...) 时的参数展开问题。

  • 修复 Java varargs 场景下 JS 参数数组与 Java Object... 参数之间的转换问题。

  • 修复显式 Java 类型对象被当作普通 JS 对象继续转换的问题。

  • 修复部分 Java wrapper 调用中基础类型参数匹配错误的问题。

  • 优化 JS number 到 Java 基础类型的转换:

    • int
    • long
    • float
    • double
    • boolean
  • 修复目标方法签名为 int,但 JS 层传入 Number(...) 后被映射为 Double 的问题。

  • 修复目标方法签名为基础类型时,显式 Java boxed value 被二次转换的问题。

  • 保持 Java.type()Java.proxy()Java.call()Java.newInstance() 等已有入口兼容。

多进程 MCP 边界说明

  • 明确 MCP/RPC 方法运行在注册它的目标进程内。

  • 明确 Android 不同进程之间内存隔离。

  • MethodClassLoaderthisObject 等 Java 运行期对象不能跨进程保存或调用。

  • 当 Hook 生效进程与 MCP 连接进程不一致时,脚本内保存的 Java 对象不会互通。

  • 新增文档说明:如果目标 App 有多个进程,应优先让 MCP 调用路由到真正加载目标类、native 库和业务上下文的进程。

  • 建议后续 MCP 桥接层支持按进程选择调用目标:

    • packageName
    • processName
    • pid
    • scriptId
    • methodName
  • 当多个进程注册同名 RPC 方法时,不应随机选择进程调用,应返回候选进程或显式指定进程。

Native 调用边界说明

  • 补充说明:通过 MCP 远程反射调用 App 方法时,目标方法内部如果依赖 native 库,必须确保 native 库已在当前进程加载。

  • 如果当前进程没有加载对应 .so,调用 native 方法会抛出:

    • UnsatisfiedLinkError
  • 新增排查建议:

    • 确认 MCP 调用所在进程是否正确。
    • Hook System.loadLibrary(...)Runtime.loadLibrary0(...) 查看 native 库加载情况。
    • 确认目标 native 方法是否依赖加固壳或动态注册。
    • 不建议在错误进程中强行调用依赖 native 的目标方法。
  • 对于加固类或壳相关类,推荐优先在 App 原始调用链路中 Hook 记录参数和结果,而不是在错误进程中直接远程调用 native 链路。

WebIDE 与设置界面优化

  • 设置页新增“脚本文件夹位置”设置项。

  • 用户可以在 App 设置中自定义脚本文件夹路径。

  • 默认脚本目录为当前用户 Documents 下的 XiaoHeiHook 目录。

  • 设置保存后会同步写入脚本根目录配置,供脚本扫描、同步和 xhh.fs.scriptRoot() 使用。

  • 新增路径校验:

    • 路径不能为空。
    • 路径必须是绝对路径。
    • 已存在路径必须是目录。
  • 修改脚本文件夹位置后,会提示用户重新扫描并同步脚本。

  • 关于页面新增外部链接按钮:

    • 开源仓库
    • 开放文档
  • 修复关于页面字符串换行显示问题,推荐在 strings.xml 中使用 \n 显式换行。

文件与资源 API 延续优化

  • 保持 xhh.fs 文件与资源桥接接口。
  • xhh.fs.scriptRoot() 会读取用户设置中的脚本文件夹路径。
  • 自定义脚本根目录后,多文件脚本和 assets 资源目录会从新位置扫描。
  • 保持资源复制目标必须位于目标 App 私有目录内的安全边界。
  • 保持 assets API 只能访问当前脚本 assets/ 目录。
  • 保持资源复制返回完整目标路径,便于脚本加载图片、HTML、CSS 和 JSON 等资源。

示例脚本

  • 新增作用域与全局状态测试脚本。

  • 测试脚本覆盖:

    • 顶层 let
    • 顶层 var
    • 顶层对象字段
    • Hook 回调
    • Java SAM 回调
    • MCP/RPC 回调
    • xhh.global
  • 新增 MCP 反射调用示例,演示如何:

    • 保存目标类名和方法签名。
    • 在 MCP 调用时重新解析 Method
    • 处理 int 等 Java 基础类型参数。
    • 返回调用结果和错误信息。
  • 更新多文件 assets 示例,展示应用启动时复制资源到目标 App 私有目录并尝试展示图片。

  • 示例中补充多进程与 native 库加载边界说明。

文档

  • 文档版本更新至 1.31 (108)

  • 更新脚本 API 文档,新增 xhh.global 全局状态接口说明。

  • 更新 Java Bridge 文档,说明 JS 到 Java 参数转换规则。

  • 更新 MCP 文档,说明 RPC 参数对象、回调作用域和多进程边界。

  • 更新边界文档,说明:

    • JS Runtime 作用域边界
    • Java 对象与 JS 对象转换边界
    • xhh.global 进程边界
    • MCP 多进程调用边界
    • native 库加载边界
  • 更新示例文档,加入作用域测试、RPC 反射调用和多文件 assets 示例。

  • 修复文档搜索中 ChineseStemmer is not defined 导致前端搜索异常的问题。

  • 调整 Sphinx 中文搜索配置,补充中文搜索 fallback。

  • 修复 RST 标题层级与标题下划线长度问题,避免构建时出现 Title underline too short 警告。