1

我有兴趣在 dx 将已编译的 Class 文件转换为 dex 文件之前对其进行一些修改。我查看了一些官方的Dalvik 文档以及DEX 格式和 Class 格式之间的比较。我找不到太多关于实际转换过程的信息,class->dex。dx 在转换之前是否首先验证 Class 文件?它是否只是逐个字段和逐个方法地进行,将指令组合并为更紧凑的分组?任何见解将不胜感激。

谢谢。

4

2 回答 2

5

运行方式dx,它通常没有足够的信息来进行所有可能的验证,也不是为了这样做而编写的。特别是,部分验证与一个类中的代码如何引用其他类中dx的代码有关,并且在运行时,所讨论的“其他类”的代码实际上可能不可用。例如,您可以针对 Android API 级别 6 编译一些代码,生成一个.dex文件。稍后,当运行 API 级别 29 的设备出现时,您可以尝试运行该.dex文件。只有当文件在系统上并准备好运行时,系统才会拥有执行验证所需的所有信息。此时,它可以检查.dex文件与系统上可用的内容并接受(通过验证)或拒绝(验证失败)该文件。

举个简单的例子,也许该.dex文件引用了 API 级别 6 中存在但在 API 级别 29 中被删除的类或方法。

但要明确的是,正如@JesusFreke 所说,dx需要能够解析.class文件以完成其翻译工作。如果它在该层遇到问题,它将报告为翻译失败,在上下文中,这大约相当于验证错误,尽管它通常不会这样表述。

即使不考虑 API 演变的可能性,也有可能取一个.class无法验证的文件,成功地将其翻译成一个(a 的一部分).dex文件,然后观察该.dex文件无法验证。

我希望这有帮助!

于 2012-04-25T22:37:30.943 回答
2

我不像 dalvik 字节码那样熟悉 dx 本身和转换过程,但我不记得看到原始 java 字节码的任何验证,尽管显然它必须格式良好,才能被 dx 解析/理解.

我知道没有关于转换过程的文档。它涉及将字节码转换为几种中间格式(ROP、SSA),并包括一些用于有效寄存器分配的逻辑和对中间格式的一些优化(我认为)。

有关转换过程的更多信息,最好的办法是查看 dx 源本身 (/dalvik/dx)

于 2012-04-25T17:01:22.390 回答