src/native_dex.rs 中最初的 Rust DEX 解析器改编自
JADX v1.5.6 的解析逻辑,固定于提交
28ff15e4ae69950aebea110a13e5ab895d234dfc。
JADX 版权归 Skylot 及其贡献者所有;适用的 Android 开源项目
及其他上游声明保留在 NOTICE 中。
参考实现是
DEX 输入插件,
包括 DexReader、sections/DexHeader、sections/SectionReader、
sections/DexClassData 和 utils/Leb128。
RDX 的修改将解析器逻辑转换为 Rust,采用受检字节访问、 显式错误传播以及 RDX 自有的类/成员表示。原生源码生成器是全新的 RDX 代码。 这是一个初步的、部分实现的解析器和原生引擎实现,并非 JADX 反编译 流水线的完整移植,也不声称具有同等的输出覆盖范围。
以下文件是从固定版本下载的未修改副本:
8dada3edaf50dbc082c9a125058f25def75e625a)。5c0b69a0f5298e0b329e33e860f7626f0c2c3891)。完整的上游 NOTICE 被保留,包括历史性的捆绑库和图标声明。保留并不意味着 Rust 解析器包含了所有这些库或资源。Java 实现及其运行时依赖不再随附分发。
包含改编解析器的发行版必须包含适用的许可证和声明。 源自其他上游文件的修改应保留其声明,并随着移植的扩展更新此源映射。
src/native_resources.rs 将固定版本 JADX v1.5.6 的
jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java
中的块调度、命名空间、元素和类型化属性解析映射为原生 Rust。其字符串池
读取器和有界 XML 生成器为 RDX 代码。解码器验证输入/块/字符串边界,
支持 UTF-8/UTF-16 池,并在无 Java 运行时的情况下处理常见的 Android
类型化属性值。资源 ID 保持为数字:ARSC 符号查找和清单枚举/标志名称
尚未移植。这不是完整的上游资源子系统。
src/native_java/ 是 RDX 在改编的 DEX 读取器之上实现的保守 Rust 寄存器值
降级和 Java 生成层。它处理支持的类型化指令、前向分支、简单循环和
前向 switch,具有显式效果物化和生成的源映射。
数组/类型操作码处理遵循 AOSP DEX 指令规范。
它不是 JADX 的 CFG/SSA/类型推断流水线的移植,也不声称具有
其重建覆盖范围。不支持的方法保留原生 DEX 输出。
src/native_cfg.rs 改编自固定版本 JADX
BlockSplitter.java
的拆分/连接方法。Rust 实现直接操作受检的 DEX 代码单元,保留
goto 指令和原始偏移量,排除载荷数据,并保守地
隔离受保护指令以处理异常边。它尚未实现
JADX 的合成块变换、SSA 或区域构建。支配者
分析是下文描述的独立阶段。
此阶段通过单独的语料库审计暴露;GUI 源渲染器
仍使用现有的寄存器值降级。参见
docs/jadx-port-plan.md 了解剩余的遍。
src/native_dominators.rs 改编自固定版本
DominatorTree.java:
Cooper/Harvey/Kennedy 迭代式直接支配者算法、前驱
交集和支配边界遍历。Rust 修改保留原始块 ID,使用迭代式
逆后序遍历,限制工作/边界存储,
并使用树区间进行支配查询,而非逐块支配者
位集。虚拟入口前驱处理方法入口的回边。
可达性从实际方法入口出发,经过正常和保守的
异常边;断开连接的处理器块被报告为不可达。
这是支配者分析,不是完整的 BlockProcessor 变换遍。
src/native_ir.rs 改编自固定版本
InsnDecoder.java
的指令族操作数映射。其受检的原始 DEX 操作数读取器遵循 AOSP 指令格式,为 RDX
代码。它保留偏移量/操作码、有序寄存器读写、字宽、
字面量、索引引用和保守的抛出行为。与上游不同,
它尚未解析池条目、合并调用结果或执行类型推断。
调用参数在签名解析之前保持为有序的原始寄存器字。
src/native_calls.rs 现在解析方法池条目,并根据有效原型对接收者/参数字
进行分组,遵循相同的固定版本 InsnDecoder
调用/结果约定。它处理宽参数、数组所有者、多态
次级原型和填充数组,并链接相邻的类型化 move-result
指令。自定义调用显式拒绝缺少调用点元数据的情况。
这是签名绑定,不是虚分派解析或 SSA。
寄存器类别描述存储宽度/引用约束,而非推断的 Java 类型。CFG 和操作数解码共享一个指令宽度解码器;旧的 源渲染器在此分析流水线构建期间保持独立。
src/native_dex_metadata.rs 从
AOSP DEX 格式解码编码值、try/catch 处理器列表和
共享的类/字段/方法/参数注解集。
受检偏移量、分配/工作预算、共享处理器存储和 Rust
表示为 RDX 代码。src/native_java/annotations.rs 渲染常见的 Java
注解值,保留类型/枚举链接和转义字符串/字符。注解
放置遵循固定版本 AnnotationGen.java。
构建/运行时注解会被显示,包括在具有 DEX 回退
体的方法上。系统注解保持为元数据;Throws 也渲染为 throws 子句。
不支持的 Java 值被显式标记。注解默认值和调试
元数据未完全重建。
src/native_java/numeric.rs、strings.rs、liveness.rs 和异常
渲染器是基于 DEX 指令语义的 RDX 实现。其
保守回退边界和独立的 Rust 行为测试夹具记录在
docs/native-engine.md 和 docs/validation.md 中。它们不
执行或嵌入上游 Java 代码。
src/native_ssa.rs 改编自固定版本 JADX
SSATransform.java
的活跃入剪枝支配边界 phi 插入和重命名。
Rust 改编使用迭代遍历、有界字标识和合成
正常后继块以保留写入前的异常状态。后者替代了
上游的重命名后 try 边修复。Phi 简化仍未移植;
部分类型推断如下所述。native_call_values.rs 将
现有签名约束附加到 SSA 字。不执行任何上游 Java。
src/native_types.rs 改编自固定版本 JADX TypeInferenceVisitor.java
和 TypeUpdate.java
的赋值/使用边界分离和传播序列。
有界 Rust 工作列表、字对检查、字面量备选和显式
未解析/冲突结果是 RDX 改编。这是部分推断:
数组元素监听器现在传播加载类型和存储约束。一般的
反向数组推断、引用最小上界、泛型和转换
插入仍不完整。
src/native_constructors.rs 遵循固定版本
ConstructorVisitor.java
中的 SSA 赋值链。RDX 检查分配支配性并保留来源和原始被调用所有者。
仅当层次结构证明所有者是分配类型的祖先时,不同的所有者才被标记为重定向。
在 this 上通过已证明的祖先进行链式调用遵循固定版本
ConstructorInsn.java。此分析不删除或移动
指令,不建立初始化状态有效性,也不生成构造器。
native_java/allocation_lowering.rs 中的有界嵌套分配路径现在
消费这些 SSA 构造器绑定。精确的分配/调用标识和
RDX 效果事件检查门控共享捕获 Java 表达式。此集成
不是完整 JADX 区域/代码生成流水线的移植;所有者重定向
生成、异常区域和一般初始化状态验证在此路径中仍
不受支持。
native_hierarchy.rs 中的数组赋值关系遵循
JLS 4.10.3:
引用组件协变、不变原始组件和标准
Object/Cloneable/Serializable 超类型。描述符嵌套有界;缺失的
外部类关系保持未知。
小型平台层次结构还包括已验证的接口边: Throwable / Serializable 和 SQLException / Iterable。 这些事实避免了先前仅异常父图中 假阴性的子类型答案;它们不构成完整的 Android 平台类路径。
有界分配解码器识别被忽略的 StringBuilder.append(String)
结果,依据固定版本
SimplifyVisitor.convertInvoke
中的非链式构建器使用模式。
RDX 保留实际的构造器/append 调用和精确的效果跟踪;它不
执行上游的完整字符串拼接变换。仅接受精确的最终
平台类及其文档化接收者返回契约的重载;
任意看似流式的方法仍不受支持。参见
StringBuilder.append(String)。
native_java/method.rs 中的类 invoke-super 生成遵循固定版本
InsnGen.callSuper/getClassForSuperCall
中的超类处理。
RDX 使用其有界不可变层次结构证明严格的超类祖先关系,
而非要求 DEX 方法所有者等于直接父类。它生成
super.method(...) 并在导航元数据中保留原始 DEX 签名。
接收者仍必须是当前实例。接口默认方法、封闭
类限定 super 调用以及不完整/有歧义的祖先关系仍不受支持。
类/接口分派区别由
AOSP 的 invoke-kind 文档规定。
固定版本 JADX ConstructorVisitor.processInvoke 移除原始
NEW_INSTANCE 并就地替换构造器调用;InsnGen 随后生成
new Class(arguments)。相关上游源码:
RDX 的原生 allocation.rs 首先保持其更严格的表达式重建。
仅对于平坦窗口,它可以暂存有序捕获声明并将 new
放置在构造器位置,匹配上游可读重建
方法。与上游更广泛的重排序分类不同,RDX 仍按原始顺序检查
所有记录的 cast/call/read/string 事件。有意的
分配重定位可能改变类初始化、链接和分配
失败时机;输出覆盖范围不建立完整的语义等价性。
src/native_java/synchronized.rs 改编自固定版本 jadx-core/src/main/java/jadx/core/dex/visitors/regions/maker/SynchronizedRegionMaker.java
的入口/主体/监视器退出重建方法。
Rust 实现增加了有界 CFG 遍历、解码的寄存器写入和
异常覆盖检查、精确清理验证,以及对
嵌套/多重释放/混合异常形态的保守拒绝。它是部分实现,
不是上游区域制造器的完整移植。原始 SPDX/许可证条款
和声明仍由上述文件覆盖。
native_java/names.rs 遵循固定版本 JADX 的
RenameVisitor.java
中原始标识和有效源别名的分离,
特别是 checkClassName 和 checkPackage。RDX 使用其现有的单射
UTF-8 十六进制别名方案,而非 JADX 的可配置别名提供者和全局
冲突处理。头文件、构造器、类型操作数和导入使用别名;
源链接保留原始 DEX 名称。这不是完整的 RenameVisitor 移植。
同步区域子集还处理 DEX 保护区间之外的 非抛出循环闩锁,并生成完全位于已证明监视器 区域内的循环。它保留固定版本制造器的监视器区域分离, 同时要求对除已证明释放之外的每条抛出主体指令 进行覆盖。
native_java/finally_regions.rs 使用固定版本 JADX 的 MarkFinallyVisitor.java
的重复清理识别方法。
这是一个有界 Rust 子集,不是完整的访问器移植:一个稳定输入的 void
清理调用、一个正常副本、一个 catch-all 重新抛出,以及一个带有终止路径的
封闭类型化 catch。它在生成前检查原始逐指令异常分派、
控制流边界、清理操作数和源链接。
不支持的嵌套布局仍然回退。
精确的 Android 框架异常元数据基于平台声明: ActivityNotFoundException、 RemoteException 和 IBinder.transact。
src/frida_snippet.rs 中的方法片段 UI 和日志格式遵循
JADX FridaAction。
Rust 生成器读取精确的 DEX 符号描述符,始终选择精确的
重载,使用位置参数名称,并调用该捕获的重载。
每个片段都限定在 Java.perform 内,因此粘贴的片段不会覆盖
彼此的方法句柄。类范围和字段片段未实现。