跳转至

Apktool 资源解码

REA 通过调用方的 Apktool 启动器解码 Android 资源表和二进制清单。这补全了针对 Android 目标的静态分析三件套:通过 JADX 系列还原 Java/Kotlin 源码,通过 JEB 进行引擎级反编译,通过本系列处理资源。REA 从不安装 Apktool 或 Java 运行时。

提供工具

请使用 Apktool 2.7.0 或更高版本(已在 Linux 上使用 2.7.0 和 3.0.3 验证),以及启动器能够找到的 Java 运行时。通过环境变量选择启动器:

# Optional: absolute path to the apktool launcher (upstream wrapper or a
# java -jar script); without it, apktool resolves from PATH.
export REA_APKTOOL_COMMAND=/absolute/path/apktool

就绪检查通过 rea inspect-apktool-client 完成:它会运行 apktool --version,并报告解析到的启动器、其选择来源和版本。缺少启动器时报告 capability_unavailable 并提供 REA_APKTOOL_COMMAND 作为补救措施,而不会尝试安装。binary_session 使用相同的主机探测来检查工具可用性;它不验证特定 APK,也不保证所选输入能够被解码。

客户端检查和解码结果会披露以下已报告版本的安全公告窗口,但不会拒绝其他方面兼容的启动器:

安全公告 受影响版本范围 主机范围
CVE-2024-21633 2.9.2 之前 全部
GHSA-vgwr-4w3p-xmjv 2.9.3 之前 Windows
CVE-2026-39973 3.0.0 发布系列中 3.0.2 之前的版本 全部

2026 年的公告指出 3.0.1 及 3.0.2 修复。将 3.0.0 包含在内源自源代码:标记的 3.0.0 会原样传递类型名称;3.0.2 补丁 会在这些名称到达输出路径生成器之前,在其所有者处进行验证。固定版本之前的预发布版本会被保守披露;确切的 -dirty 下游标记会作为版本进行比较,同时保留其拼写。这是版本指导,而非对特定预发布版本或解码器的验证。

启动器版本并不能证明解码器的内容、执行平台、下游移植或整体安全性。Windows 适用性基于所选本地主机;不透明的包装器可能运行另一个引擎。缺少警告仅表示这些版本/主机窗口均未匹配。在解码不受信任的 APK 之前,请验证所选解码器的补丁;上述兼容性底线不是安全建议。REA 不会在运行时获取安全公告。

在 Windows 上,.bat 或 .cmd 启动器(例如 Chocolatey 的 apktool.bat)会通过显式调用 cmd.exe /d /s /c 运行。该调用没有 AutoRun,没有延迟展开,并且会为每个参数加引号。包含 "、%、^、!、&、|、< 或 > 的启动器路径会被报告为 not_configured,而不会传递给 cmd.exe。如果 REA 的临时解码路径包含这些字符,通过批处理启动器解码会报告 capability_unavailable。

回答分析师问题

rea inspect-apktool-client
rea decode-android-resources /targets/Example.apk
rea decode-android-resources /targets/Example.apk --locale de
rea decode-android-resources /targets/Example.apk --locales de --locales pt-BR
rea decode-android-resources /targets/Example.apk --locales de --locales pt-BR --string-tables-only
rea decode-android-resources /targets/Example.apk --no-strings
rea decode-android-resources /targets/Example.apk --decode-timeout-ms 900000

等效的 MCP 方法是 inspect_apktool_client 和 decode_android_resources。解码请求接受 path、可选的主 locale(输出 res/values-<locale>/strings.xml 而不是默认表)、locales(可重复的数组,用于在同一次单遍解码中输出额外的本地化字符串表)以及 include_strings(默认为 true)。pt-BR 等区域设置会选择 Android 的 values-pt-rBR。三位数字区域(如 es-419)会选择 values-b+es+419;es-r419 会被拒绝,因为 Android 传统的 -r 形式要求两位字母区域。也可以直接提供 pt-rBR、b+zh+Hans+CN 等 Android 限定符。

设置 string_tables_only: true(CLI 为 --string-tables-only)可仅返回 string_tables 内的字符串条目,包括在选择单个表时。此时顶级 strings 数组按请求要求为空;这并不表示主表为空。表状态、计数和覆盖率仍然描述所检查的源。这避免了在多区域设置响应中重复主表条目,并按每表一份计入聚合输出预算。省略该选项会保持现有响应不变。include_strings: false 仍然会抑制所有字符串输出,包括在此模式下。

解读结果

  • 所拥有的 APK 快照会被摘要并解码。 target.sha256 和 target.bytes 将观察结果绑定到被解码的那个确切 APK。Evidence 主体携带相同的快照摘要和调用方选择的路径,即使原始文件在解码期间发生变化也是如此。快照获取期间发生变化会报告可重试的 artifact_changed;请等待输入稳定后再重试。主机读取权限失败会报告 access_denied,而所选路径缺失或不是常规文件则报告 invalid_request,并附上被拒绝的 path 字段。
  • 元数据来自 apktool.yml,且保留 apktool 打印出的原样。 版本代码保留其自身的拼写('7' 对 7);package_name 从解码后的清单中读取,而非推断。Apktool 3 生成的 version: 3.x.y 标头会选择其单行字符串方言:字面量哈希符、单引号、空字符串以及文本 null 仍然作为值的一部分;来自生成方的反斜杠和 Unicode 转义只解码一次。较旧/带标签的文档保留 YAML 标量语义;双引号值也保留 YAML 字符串语义。这一区分与已发布的 3.0.3 元数据写入器 和 字符串转义处理类 保持一致。
  • 清单是解码后的文本,大小限制为 512 KiB,若超过则报告为已截断。
  • 字符串按原样输出。 转义实体保持转义状态,包含嵌套标记(如 <b>、<xliff:g>)的条目会被计为未解析而非扁平化——该限制指出的是被检查条目的计数。格式错误的 XML 和错误的文档根节点会导致整个文档输出失败:结果是部分的,失败原因会被披露,条目计数保持未知。它们不会被计为一个不支持的字符串。默认表限制为 2000 个条目,当存在更多条目时,覆盖率为部分覆盖。locales 列出观察到的常规 strings.xml 表,这些表的确切 values-<locale> 目录可通过请求的区域设置语法选择。区域设置后缀最多允许 23 个 ASCII 字符,源自 Apktool 的语言、文字、地区和变体字段;例如,b+sr+Latn+RS+REVISED 会选择那个确切的表。其他表目录(包括 values-en-rUS-v21 和 values-mcc310-fr 等组合限定符)会在限制说明中以原始拼写列出。它们不会被声明为可选择的区域设置;REA 不推断 Android 的运行时资源匹配。非常规字符串表路径会以部分覆盖的形式披露。发现过程使用与文件计数相同的有界遍历;文件系统错误仍然是错误,而不会被视为缺失表。当通过 locales 请求多个表时,string_tables 会记录每个输出的表,包括其区域设置、状态(present、missing、oversized、malformed 或 skipped)、条目计数和覆盖率,总预算限制为 10,000 个字符串和 32 MiB XML。当省略 locales 且 string_tables_only 不为 true 时,保留传统的单表负载,且不添加 string_tables。
  • Smali 按设计被跳过(apktool d --no-src):Java 源码恢复属于 JADX 系列。资源 smali 编辑和重建是后续通道,拥有变更权限。
  • 工作区归提供方所有且生命周期很短。 解码在提供方拥有的临时目录中进行,该目录在结果返回前会被移除。APK 快照和框架缓存都位于此目录内。如果移除失败,结果会指明残留路径,提供方保留所有权,以便在关闭时重试清理,包括解码失败的情况。

资源与生命周期限制

  • 解码墙钟时间由 decode_timeout_ms 指定(CLI 为 --decode-timeout-ms)。省略时默认为 600000 毫秒。整数范围为 1 到 2147483647。更改会在下一次解码时生效。它不会提高 4194304 字节(4 MiB)的输出捕获预算。该捕获预算没有运行时覆盖。被停止的解码会报告 provider_timeout 并指明生效的毫秒数;超出捕获预算则会报告 resource_constraint。
  • 版本探测等待 20000 毫秒,并保留 65536 字节。本版本没有针对该探测的运行时覆盖。decode_timeout_ms 不会提高该限制。
  • Manifest 读取在解码 UTF-8 之前限制为 512 KiB。Strings XML 读取限制为 8 MiB;更大的文档会被跳过,并附有部分覆盖和明确限制说明,而不会报告为缺失。
  • decoded_file_count 上限为 100,000 个文件;达到上限时,限制说明中会报告该上限。
  • 普通的非零解码退出会以 unsupported_target 形式呈现,并指明调用方选择的 APK,同时包含 Apktool 的诊断信息和捕获的输出。启动器启动、所有权准备、信号终止以及不完整的输出收集仍属于 provider 失败;它们不能证明所选 APK 不受支持。

真实验证

npm run verify:apktool -- --apk PATH 会针对真实启动器执行这两种操作。记录:在 Linux 上使用 OpenJDK 25,以 apktool 2.7.0-dirty(Debian 打包版)针对一个由 aapt2 构建、已签名且携带两个资源区域(locale)的探测 APK 进行验证——启动器版本、磁盘上的摘要一致性、apktool.yml 元数据(1.2.3,SDK 24–34)、manifest 包名一致性,以及默认与 de 字符串表的投影。测试套件中的解析器 goldens 来自同一次解码。有关 lane 摘要,请参阅 docs/testing.md。

多区域(multi-locale)和仅表格(table-only)投影也通过真实 CLI 和 stdio MCP 工作流,在 Linux 上使用 Apktool 3.0.3/JDK 21,针对 NewPipe 0.29.1、ApiDemos 6.0.18 和 Appium Settings 8.2.1 进行了验证。独立的 XML 投影检查、facts/Evidence 的精确一致性以及有界任务成本均记录在 shared-decode 和 table-only 检查点 中。此验证仅限定于选定的资源事实,而非应用程序执行或独立二进制资源解码器的完整性。

如果在复制所选 APK 的私有快照期间该 APK 发生变化,获取操作会返回 artifact_changed;request-schema 修正无法恢复稳定的快照。启动器 spawn 权限被拒绝与启动器缺失是不同的情况,配置诊断会保留所选命令和系统错误。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 rea2/rea