Skip to content

Releases: wojiaoyishang/XiaoHeiCat

1.35 (112)

Choose a tag to compare

@wojiaoyishang wojiaoyishang released this 11 Jun 10:36
  • 支持每个应用独立配置脚本缓存目录,默认使用 .xhh_scripts
  • “缓存脚本到应用私有目录”默认开启,并通过 LSPosed Remote Preferences 控制是否生效。
  • 自定义缓存目录不再自动使用隐藏目录名,仅默认 .xhh_scripts 保持隐藏。
  • 修复目标应用私有目录缓存必须由目标进程自行写入的问题,避免 XiaoHeiHook 主进程无权限写入。
  • 移除 createPackageContext() 兜底逻辑,修复包加载阶段递归触发 LSPosed 回调的问题。
  • 新增 Root 脚本缓存同步能力,Root 可用且设置开启时由 XiaoHeiHook 直接同步到目标应用私有目录。
  • Root 同步会自动设置目标目录和文件权限,目录 700,文件 600,owner 为目标应用 UID/GID。
  • Root 不可用或同步失败时自动回退为目标进程自缓存。
  • 支持多用户、工作空间、分身环境下的目标应用数据目录搜索。
  • 关闭“缓存脚本到应用私有目录”后会清理旧缓存目录。
  • 新增设置项“使用 Root 同步应用私有脚本缓存”,Root 可用时默认开启。
  • 脚本运行索引改为每应用独立保存,避免单应用同步覆盖其他应用索引。
  • 新增每应用独立的 <packageName>_script_index_json
  • 新增每应用独立的 <packageName>_script_sync_manifest_json
  • 新增每应用独立的 <packageName>_script_hash_config_json
  • 目标进程优先读取当前应用自己的运行索引,旧全局索引仅作兼容回退。
  • 修复重启后部分应用脚本不生效的问题。
  • 同步单个应用时不再覆盖其他应用的脚本索引、manifest 和 hash 配置。
  • 同步已启用脚本时不再每次扫描全部脚本目录,仅同步已勾选脚本。
  • 仅在手动刷新脚本列表、首次无缓存或明确全量同步时扫描全部脚本。
  • 修复旧 Metadata 中 settingsSchema=null 导致同步崩溃的问题。
  • 新增打开 XiaoHeiHook 时打印 LSPosed Remote Preferences 诊断日志。
  • 诊断日志会输出已启用应用、脚本索引、hash 配置、manifest、缓存目录、Root 同步状态和缺失脚本状态。
  • 新增“不记录日志”开关,默认关闭。
  • 开启“不记录日志”后仅实时同步日志到 WebIDE,不再持久化保存日志文件。
  • WebIDE Hook 设置窗口新增“不记录日志”选项。
  • WebIDE Hook 设置区域改为右上角齿轮弹窗配置除应用总开关外的设置。
  • WebIDE Hook 设置切换和保存操作新增加载动画和禁用状态。
  • WebIDE 移除右侧“当前脚本 Metadata”组件。
  • 修复移除 Metadata 后右侧面板底部内容被遮挡的问题。
  • 更新 WebIDE 构建产物并同步到 App assets。
  • 更新文档,新增 LSPosed Remote Preferences 与脚本缓存运行机制说明。
  • 更新 scripts/bridge.rst 的整体调用链说明,并加入到新开发说明章节的引用。

1.34 (111)

Choose a tag to compare

@wojiaoyishang wojiaoyishang released this 11 Jun 04:08
  • WebIDE/MCP 都关闭且用户划掉 App 时,主进程会延迟检查并主动退出,避免无服务时后台驻留。
  • 优化主界面页面加载策略,页面首次进入才初始化,已加载页面切回时复用状态。
  • 优化 Apps 页加载流程,减少导航切换时的同步扫描和掉帧。
  • Apps 页应用列表使用后台过滤/排序,避免主线程重计算。
  • Apps 页启用状态改为缓存读取,减少每行重复查询。
  • Apps 页新增 App 图标硬盘缓存,未更新应用优先读取本地缓存图标。
  • App 图标缓存支持按 packageName + lastUpdateTime 增量刷新。
  • Apps 列表改为视口懒渲染,未进入视口附近的应用不渲染完整行内容。
  • Apps 列表未进入视口项改为轻量空白卡片占位,避免视觉截断。
  • Apps 列表底部 padding 优化,避免和底部导航栏背景衔接时出现被切割感。
  • 底部导航栏高度提高,视觉衔接更自然。
  • 底部导航页切换动画保留滑动效果,可通过 MainScreen.ktdurationMillis 调整速度。

1.33 (110)

Choose a tag to compare

@wojiaoyishang wojiaoyishang released this 10 Jun 17:04
  • 修复 Hook .intercept() 返回 primitive boolean 时 Java.to(...) / return true 兼容问题。
  • 优化 Hook 返回值转换逻辑,支持显式类型包装、递归 unwrap、primitive boxed 校验。
  • 移除 Hook 返回值调试日志,恢复 clean 版本。
  • 修复关闭 WebIDE 时可能触发主进程前台服务超时崩溃的问题。
  • 禁用主进程 MainProcessKeepAliveService,避免 ColorOS/OPlus 上反复触发 FGS 超时。
  • 移除 WebIDE 关闭时主动杀 :webide 进程的逻辑,改为正常停止服务。
  • 移除 App 关闭时自动杀主进程逻辑,避免误判为崩溃。
  • WebIDE 前台服务改为 dataSync 类型,提升系统识别度。
  • WebIDE 保留 WakeLock / WifiLock,降低后台冻结和断连概率。
  • 新增无障碍辅助保活服务,用户可选开启。
  • 设置页 MCP 卡片下方新增无障碍保活卡片。
  • 支持 Root 直接开启/关闭本应用无障碍服务,无 Root 时跳转系统设置。
  • WebIDE 开关仍开启但服务被系统杀掉时,主进程恢复后会尝试重新拉起。
  • App 详情页打开时增加脚本软刷新,脚本数量变化时自动更新缓存。
  • 手动刷新脚本时仍执行全量扫描并更新缓存。
  • WebIDE 工具栏新增代码生成器。
  • 代码生成器支持目标类名、方法名、参数类型、返回值类型、修改值和 Hook 点配置。
  • 代码生成器支持快速 JSON 导入/导出。
  • 代码生成器支持选择是否先 Hook android.content.Context
  • 代码生成器生成临时文件,首次 Ctrl+S 时提示输入文件名保存。
  • 简化代码生成器输出模板,去除多余辅助函数和常量抽取。
  • 代码生成器未勾选记录示例变量时,不生成相关日志和函数。
  • 代码生成器 Hook 目标代码段加入分隔注释。
  • 代码生成器按钮移动到运行控制按钮右侧,并单独分组。
  • 新建单脚本模板移除 // @grant dex.full
  • 新建单脚本模板在脚本头后加入 // 如果需要捕获全部进程请修改 @process 字段。
  • WebIDE 关闭/刷新页面时,如存在未保存文件,会触发浏览器离开确认。
  • WebIDE 标签页右键菜单新增“关闭其他文件”。
  • 新建单脚本重名时提示是否覆盖,并可直接打开已有文件。
  • 所有前端提示框、输入框替换为 WebIDE 自定义界面组件。
  • 文件管理列表表头支持拖拽调整列宽。
  • 文件管理列宽支持双击恢复默认值。
  • 文件管理列宽保存到本地缓存,刷新页面后保留。

1.32 (109)

Choose a tag to compare

@wojiaoyishang wojiaoyishang released this 10 Jun 07:41
  • 新增 Java.to(type, value[, options]),用于将 JS 值按目标 Java 类型显式转换。
  • 新增 JS 到 Java 参数转换规则,支持基本类型、包装类型、字符串、数组、集合、Map、枚举等常见类型。
  • 优化 Java Bridge 直接对象传递,Java 对象、包装对象、NativeJavaObject 不再被二次 JS 化转换。
  • 优化 Method.invoke(...) 参数处理,现在会按真实目标方法签名进行类型转换。
  • 优化 Hook chain.proceed(args) 参数处理,现在会按被 Hook 方法的真实参数类型转换。
  • 新增反射方法签名字符串支持,getDeclaredMethodgetMethodgetDeclaredConstructorgetConstructor 可直接传 "int""java.lang.String" 等类型名。
  • 新增 Java.use(...) 作为 Java.type(...) 的推荐别名。
  • 新增 Java Bridge 类型转换文档,补充 JS 与 Java 数据类型边界说明。
  • 新增 Rhino 兼容性说明链接,方便查询当前脚本环境支持的 JS 语法。
  • 新增 dex.scanSmali(options),支持按 smali 字符串、常量字符串、invoke 特征快速扫描 dex 方法。
  • 新增 dex.forEachMethod(options, callback),支持遍历 dex 方法并在 JS 回调中自定义筛选逻辑。
  • 新增 view.scanSmali(options),支持在已有 dex view 上直接进行 smali 特征扫描。
  • 新增 view.forEachMethod(options, callback),支持在已有 dex view 上逐方法遍历分析。
  • 优化 dex dump/scan API 返回值,返回给 JS 的 Map/List/数组统一转换为 JS 友好对象。
  • 修复 dex dump 返回的 paths 等字段在 JS 字符串拼接或数组访问时可能出现默认值转换异常的问题。
  • 新增动态 dex 扫描文档中的方法定位接口说明,改为 API 接口风格展示。
  • 更新脚本示例文档,增加 Smali echo 示例说明,并链接到 GitHub 仓库中的完整 qidian_dex_search.js
  • 更新 OkHttp 示例脚本,避免主动加载不存在的 okhttp3.RealCall 导致异常。
  • 优化 OkHttp Hook 示例,改为优先 Hook OkHttpClient.newCall(Request) 与实际返回的 Call 对象。
  • 优化 OkHttp 示例的反射调用,兼容混淆类和方法包装差异。
  • 新增 Java Bridge、反射、Proxy、OkHttp 等 1.32/109 版本示例脚本。

1.31 (108)

Choose a tag to compare

@wojiaoyishang wojiaoyishang released this 09 Jun 13:22

更新至 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 警告。

1.30 (107)

Choose a tag to compare

@wojiaoyishang wojiaoyishang released this 09 Jun 06:57

更新至 1.30 (107)

JS API 返回值稳定化

  • 所有保留到 JS 层的主要接口统一改为返回 JS 对象 / JS 数组,避免脚本直接遍历 Java List<Map>Map<List> 等不稳定结构。

  • 新增 JS 返回值规范化工具,用于将 Java 层返回的 MapList、数组、ThrowableFileClass 等转换为 JS 可稳定读取的结构。

  • 推荐脚本使用点访问和数组访问:

    • ret.paths
    • results[i].className
    • methods[i].methodName
  • 不再推荐旧写法:

    • ret.get("sources")
    • sources.get(i).get("path")
    • item.get("className")
  • sourcesdetails 等字段保留为调试信息,不建议脚本逻辑依赖。

Dex Dump 与 Dex 搜索 API

  • dex.dumpDexCookies(options) 返回结构稳定化。

    • 新增 ok
    • 新增 count
    • 新增 outputDir
    • 新增 paths
    • 新增 dumpedPaths
    • 保留 sources 作为调试详情
  • dex.dumpDexCookies 默认输出文件名使用 cookie_ 前缀。

    • 默认格式:cookie_<index>_<addressHex>_<fileSize>.dex
    • 示例:cookie_000_71d518e000_3777364.dex
  • dex.findMethods(query) 改为返回 JS 数组。

  • dex.findMethod(query) 未找到时返回 null

  • dex.findMethods(query) 新增 / 完善 smali 特征搜索。

    • 支持 smaliContains
    • 兼容 smaliKeywords
    • 兼容 smaliKeyword
    • 兼容 smali
  • dex.findMethods 支持仅通过 smali 特征定位方法,不再要求必须提供 classNamemethodNameproto

  • dex.findMethods 返回结果统一包含:

    • className
    • methodName
    • proto
    • descriptor
    • path
    • score
    • reasons
    • strings
    • invokes
    • smaliHead
  • dex.inspectMethodInFile(options) 严格化。

    • path 必填
    • className 必填
    • methodName 必填
    • proto 可选
    • 不再默认历史目标方法
    • 不再承担搜索职责,只用于精确检查指定方法
  • dex.locateMethodInCookieDumps(options) 严格化。

    • className 必填
    • methodName 必填
    • proto 可选
    • 不再默认历史目标方法
  • dex.dumpClassDex(options) 返回稳定字段:

    • ok
    • count
    • paths
    • dumped
    • failed
  • dex.dumpLoadedClassDex(options) 返回稳定字段:

    • ok
    • className
    • path
    • paths
    • size
  • dex.dumpMemory(options) 返回稳定字段:

    • ok
    • count
    • outputDir
    • paths
    • dumped
  • dex.scanMemory(options) / dex.dumpMemoryRaw(options) 增加稳定 candidates 字段。

  • dex.runtimeSources() 改为返回 JS 数组。

  • dex.runtimeLoaders() 改为返回 JS 数组。

  • dex.registerLoader(loader, path) 严格化。

    • loader 必须是 ClassLoader
    • path 必须是非空字符串
    • 非法参数不再兜底为默认 loader
  • dex.setLimits(options) / dex.limits() 返回稳定 JS 对象。

移除 Dex 旧式过渡接口

  • 移除或不再作为 JS 推荐接口暴露以下过渡 API:

    • dex.scanDumpDir
    • dex.fromDumpDir
    • dex.dumpCookieDex
    • dex.dumpFromCookies
    • dex.dumpRawDex
    • dex.traceStrings
    • dex.inspectDumpedMethod
    • dex.findMethodInCookieDumps
    • dex.dumpUnpackedDexForMethod
    • dex.dumpTargetDex
    • dex.dumpDexForMethod
  • 新脚本应直接使用:

    • dex.dumpDexCookies(...)
    • ret.paths
    • dex.findMethods(...)
    • dex.inspectMethodInFile(...)

JS 对象与 Java 对象边界

  • 新增对象类型判断 API:

    • xhh.objectKind(value)
    • xhh.isJsObject(value)
    • xhh.isJavaObject(value)
  • xhh.objectKind(value) 返回稳定 JS 对象,包含:

    • kind
    • isJsObject
    • isJavaObject
    • isPrimitive
    • isNull
    • isUndefined
    • rawClass
    • javaClass
    • text
  • 文档中明确推荐使用 JS 对象 / JS 数组编写脚本逻辑。

  • Java 对象仅用于调用 Android / Xposed / App 运行时方法,不建议把 Java Map/List 当作脚本数据结构使用。

Rhino / JS 语法边界

  • JS 运行时继续基于 Rhino。

  • 运行时显式启用 ES6 语言版本。

  • 新增 xhh.jsEngine(),用于查看当前 JS 引擎能力。

  • 发现并记录 Rhino 在循环体内 const / let 词法绑定上的局限:

    • for (...) { const path = paths[i]; } 在部分 Rhino 场景可能不能可靠地每轮重新绑定。
  • 取消 “ES6 词法绑定自检失败即阻断脚本启动” 的行为。

  • 当检测到 Rhino 不支持可靠循环词法绑定时,脚本仍可继续运行,并通过 xhh.jsEngine() 查看状态。

  • 新增稳定遍历 API:

    • xhh.each(items, callback)
  • 推荐遍历 ret.pathsresults 等数组时使用:

    • xhh.each(paths, function (path, i) { ... })
  • 文档中新增 “JS 脚本语法边界说明”,明确 const 的适用范围与推荐通用语法。

Xposed JS API

  • xposed.e(tag, msg, any) 第三参处理增强。

    • 支持 Java Throwable
    • 支持 JS Error
    • 支持普通对象
    • 支持字符串
    • 支持 null / undefined
  • xposed.getJavaStackTrace() 返回 JS 数组。

  • xposed.getAppStackTrace() 返回 JS 数组。

  • xposed.stackTrace() 返回 JS 数组。

  • xposed.listRemoteFiles() 返回 JS 字符串数组。

  • xposed.getFrameworkProperties() 返回稳定 JS 对象。

  • xposed.getModuleApplicationInfo() 返回稳定 JS 对象。

  • xposed.raw.call(...) 返回值经过 JS 稳定化转换。

  • Hook 回调中的 chain.getArgs() 返回 JS 数组。

XHH / RPC / MCP API

  • xhh.info() 返回稳定 JS 对象。
  • xhh.hasGrant(name) 保持布尔返回。
  • xhh.rpc.register_method(name, callback) 返回稳定 JS 对象。
  • xhh.rpc.unregister_method(name) 返回稳定 JS 对象。
  • xhh.rpc.unregister_all_methods() 返回稳定 JS 对象。
  • MCP list_methods 返回 methods: [],每一项为稳定 JS 对象。
  • MCP invoke_methodresult 尽量经过 JSON-safe / JS-safe 转换。
  • RPC 回调返回值统一经过稳定化处理,减少 Java 对象泄漏到 JS/MCP 边界。

Settings / Env / Console / Java API

  • settings.get(key) 返回值经过 JS 稳定化转换。

  • settings.all() 返回稳定 JS 对象。

  • env 文档补充常用字段说明。

  • console 文档补充与 xposed 日志的推荐使用方式。

  • Java.type(name) 文档补充 Java 对象边界说明。

  • 明确 Java 对象与 JS 对象的职责划分:

    • Java 对象用于反射和运行时调用。
    • JS 对象用于脚本配置、返回值和业务逻辑。

示例脚本

  • 更新脱壳示例为新版推荐格式:

    • dex.dumpDexCookies(...)
    • ret.paths
    • xhh.isJsObject(ret)
  • 更新 Smali 特征查找示例:

    • 使用 dex.findMethods({ path, smaliContains, limit })
    • 使用 xhh.each(paths, callback) 遍历
    • 找到第一个匹配后 return false 停止搜索
    • 最后输出命中的 dex 文件、类名、方法名和方法签名
  • 移除旧示例中的:

    • scanDumpDir
    • fromDumpDir
    • Java Map.get
    • Java List.get
    • 正则解析 dumpRet.toString()
  • 新增 / 更新 smoke test 示例,覆盖主要 JS API 返回值稳定性。

文档

  • 参考 Python 文档风格重写 JS API 文档。
  • API 参考改为 “一个标题一个方法” 的形式,便于查阅。
  • scripts/js_api.rst 重写为 JS API 总参考。
  • scripts/dynamic_dex_scan/source_api.rst 重写为 Dex Source API 参考。
  • scripts/examples.rst 更新为新版推荐脚本。
  • scripts/boundaries.rst 补充 JS 语法边界、对象边界和 Rhino 限制。
  • scripts/dynamic_dex_scan/examples.rst 更新脱壳与特征查找示例。
  • 修复 RST 标题下划线过短导致的 Title underline too short 警告。

WebIDE 运行控制优化

  • 优化 WebIDE 中目标应用重启与终止逻辑。

  • “重启并同步” 现在会优先使用 Root 权限关闭并重新打开目标应用。

  • “重启同步并调试” 现在会优先使用 Root 权限关闭并重新打开目标应用,再进入调试流程。

  • 当设备具备 Root 权限时,WebIDE 可通过 Root 执行 force-stop 与启动命令,不再要求 XiaoHeiHook 当前处于前台。

  • 当设备没有 Root 权限时,仍使用普通 Android 启动方式,此时需要 XiaoHeiHook 处于前台才能可靠拉起目标应用。

  • 优化 Root 启动策略。

    • 优先使用 am start 启动目标应用入口 Activity。
    • 无法解析入口 Activity 时,回退使用 monkey 启动目标应用。
  • “终止调试/运行” 按钮行为调整。

    • 无论当前是否处于调试模式,都会强制终止目标应用。
    • 有 Root 权限时使用 Root force-stop
    • 无 Root 权限时使用普通终止能力。
  • WebIDE API 返回信息增加运行控制状态字段,便于前端判断执行结果。

    • launchMode
    • rootLaunchOk
    • rootLaunchMessage
    • terminated
    • terminate

JS Runtime Java Bridge 重构

  • 重构 JS Runtime 的 Java Bridge,将原本集中在 JsHookRuntime 内的桥接逻辑拆分为独立模块,提升维护性。
  • Java.type() 现在返回 JS 友好的 JavaClassWrapper,不再直接返回裸 java.lang.Class
  • 新增 JavaClass wrapper 语法,支持直接读取静态字段,例如 Toast.LENGTH_SHORT
  • 新增 JavaClass wrapper 静态方法调用,支持 Looper.getMainLooper() 等自然写法。
  • 新增 JavaClass wrapper 构造函数调用,支持 new Handler(Looper.getMainLooper())
  • 新增 JavaObject wrapper,支持 Java 实例方法直接调用,例如 handler.post(...)toast.show()
  • 新增 Java 对象字段读取与写入的 wrapper 支持。
  • 新增 raw Class 入口,支持 classObjectgetRawClass() 获取原始 java.lang.Class
  • 新增 java.lang.Class 方法透传能力,支持 Application.getDeclaredMethod(...) 等反射写法。
  • 新增 Java varargs 参数转换,支持 getDeclaredMethod("attach", ContextClass) 这类调用。
  • 新增 JS function 到 Java SAM 接口的自动代理转换,支持 handler.post(function () {})
  • 新增显式 Java.proxy() 支持,可用于 Runnable、listener、callback 等 Java 接口实现。
  • 增强 Java.proxy() 对单方法接口 function 写法与多方法接口 object 写法的支持。
  • 增强 Rhino Context 进入逻辑,确保 Java proxy 回调可以安全调用 JS 函数。
  • 增强 Java 方法、构造器和字段解析,统一处理重载评分、参数转换和返回值包装。
  • 优化数字参数重载选择,使整数 JS number 优先匹配 Java int/long,避免误选 double 重载。
  • 修复 StringBuilderAtomicInteger 等构造返回值被错误当作 JS 基础值的问题。
  • 保留低层反射 API,包括 Java.callStatic()Java.call()Java.newInstance()Java.get()Java.set() 等。
  • 调整 xposed.hook() 等入口,支持接收 wrapper 返回的 MethodClass 等对象。

文件与资源桥接 API

  • 新增 xhh.fs 文件与资源桥接接口。

  • 新增目标 App 私有目录查询能力。

    • xhh.fs.appDirs(context)
    • 通过目标 App Context 动态读取私有目录。
    • 不再要求脚本硬编码 /data/user/0/data/data/sdcard
    • 兼容多用户、多 profile 与目标 App 真实运行用户。
  • 新增基础文件操作接口。

    • xhh.fs.join(...)
    • xhh.fs.exists(path)
    • xhh.fs.isFile(path)
    • xhh.fs.isDirectory(path)
    • xhh.fs.mkdirs(path)
    • xhh.fs.readText(path[, charsetOrOptions])
    • xhh.fs.writeText(path, text[, charsetOrOptions])
    • xhh.fs.appendText(path, text[, charsetOrOptions])
    • xhh.fs.readBytes(path[, options])
    • xhh.fs.writeBytes(path, bytes[, options])
    • xhh.fs.copy(src, dst[, options])
  • 文本和二进制读取默认限制为 16MB,避免目标 App 进程因误读大文件导致 OOM。

  • 读取上限可通过参数调整,适合少量配置、HTML、CSS、图片等脚本资源场景。

  • 新增脚本路径查询接口。

    • xhh.fs.scriptRoot()
    • xhh.fs.scriptDir()
    • xhh.fs.assetsDir()
    • xhh.fs.assetPath(relativePath)
  • 脚本根目录默认解析为当前用户 Documents 下的 XiaoHeiHook 目录。

  • 脚本根目录支持通过设置修改,不再在 JS API 实现中硬编码。

  • 新增脚本 assets 读取接口。

    • xhh.fs.readAssetText(relativePath[, charsetOrOptions])
    • xhh.fs.readAssetBytes(relativePath[, options])
  • assets 资源访问严格限制在当前脚本自己的 assets/ 目录内。

  • 禁止通过 assets API 读取脚本源码、其他脚本资源或 assets 外部文件。

  • 新增资源复制到目标 App 私有目录的接口。

    • xhh.fs.appAssetDir(context[, options])
    • xhh.fs.copyAssetToApp(context, assetRelativePath[, targetRelativePath[, options]])
    • xhh.fs.syncAssetsToApp(context[, options])
  • copyAssetToApp 返回值包含复制后的完整目标路径,便于脚本直接用于 ImageViewWebView、本地配置文件等场景。

  • 资源复制目标必须位于目标 App 私有 filesDir 内。

  • 复制目标子路径可由脚本指定,但必须是安全相对路径。

  • 禁止复制目标路径出现绝对路径、../ 目录穿越或符号链接逃逸。

  • syncAssetsToApp 支持递归同步当前脚本 assets/ 目录到目标 App 私有目录。

  • syncAssetsToApp 默认覆盖已有资源。

  • clean=true 时只清理当前脚本自己的资源同步目录,不会删除目标 App 其他私有文件。

  • 本版本不为文件 API 增加独立 grant 权限项,保持与现有脚本权限模型兼容。

多文件脚本与 assets 资源目录

  • 多文件脚本支持在脚本目录中放置 assets/ 目录。

  • 推荐目录结构:

    • index.js
    • main.js
    • lib/
    • assets/data/config.json
    • assets/panel/index.html
    • assets/images/icon.png
  • require() 仍只用于加载 JS 模块。

  • assets/ 只作为资源目录,不会被当作 JS 模块目录执行。

  • 脚本资源在同步时会进入 XiaoHeiHook 的脚本资源体系,目标 App 进程中可通过 xhh.fs 读取或复制。

  • 推荐脚本先将图片、HTML、CSS、JSON 等资源复制到目标 App 私有目录,再交给目标 App 的 ImageViewWebView 或普通文件 API 使用。

  • 不推荐让目标 App 直接访问脚本根目录或外部存储目录。

路径安全与运行边界

  • 明确文件路径边界:脚本目录、脚本 ...
Read more

1.20 (102)

Choose a tag to compare

@wojiaoyishang wojiaoyishang released this 08 Jun 15:24

更新至 1.20 (102)

Dex 分析能力

  • 新增 Android 端 Dex 分析入口:top.lovepikachu.XiaoHeiHook.dex.DexApiFacade
  • JsHookRuntime 新增全局对象 dex 注入能力。
  • 新增 org.smali:dexlib2:2.5.2 依赖,用于解析 Dex 字节码。
  • 新增 dex.fromLoader(loader),支持从目标 App 的 ClassLoader 解析 Dex。
  • 新增 dex.fromFile(path),支持直接解析指定 Dex / APK 文件。
  • 新增 dex.findMethod(query),支持按特征定位单个方法。
  • 新增 dex.findMethods(query),支持按特征批量搜索方法。
  • 新增 DexFile 级 API:
    • classes()
    • strings()
  • 新增 Class 级 API:
    • methods()
    • fields()
    • strings()
  • 新增 Method 级 API:
    • strings()
    • invokes()
    • instructions()
    • smali()
  • 新增 method.toMethod(loader),支持将 Dex 方法映射为运行时 Java Method
  • 支持按字符串、调用关系、类名、方法名、返回值、参数等条件搜索目标方法。
  • 支持输出目标方法的 smali 片段,便于分析 Hook 点。

WebIDE

  • 修复点击折叠区域时误触发断点的问题。
  • WebIDE 断点点击逻辑调整为只响应行号区和 glyph margin。

示例与文档

  • 新增示例脚本:sample_scripts/xhh_dex_scan_example/index.js
  • 新增说明文档:DEX_API_INCREMENTAL_README.md

JS 运行时

  • 修复 Rhino 正则表达式不可用的问题。
  • JS 运行时已支持标准正则表达式用法。

初次构建版本

Choose a tag to compare

@wojiaoyishang wojiaoyishang released this 07 Jun 12:40

发布第一个版本,推荐运行环境:

  • LSPosed >= 2.0.4