3

我正在寻找一种在 JVM 类文件和文本表示之间往返并再次返回的故障安全方法。

一个严格的要求是,只要文本表示保持不变,生成的往返 JVM 类文件在功能上与原始 JVM 类文件完全相同。

此外,文本表示必须是人类可读和可编辑的。应该可以对文本表示进行小的更改(例如更改文本字符串或类名等),这些更改会反映在生成的类文件表示中。

最简单的解决方案是使用 Java 反编译器(例如 JAD)来生成文本表示,在这种情况下,它只是重新创建的 Java 源代码。然后使用 javac 生成字节码。但是,鉴于免费 Java 反编译器的状态,这种方法并非在所有情况下都有效。创建无法在完整的往返类文件/java-source/class-file 中存活的混淆字节码是相当容易的(部分原因是 JVM 字节码和Java 源代码)。

鉴于上述要求,是否有一种故障安全的方法来实现 JVM 类文件/文本表示/类文件往返?

更新:在回答之前 - 通过阅读上述所有要求来节省时间和精力,并特别注意:

  • “JVM 字节码的文本表示”不一定意味着“Java 源代码”。
4

5 回答 5

6

BCEL 项目提供了一个JasminVisitor,它将类文件转换为jasmin程序集。

这可以被修改然后重新组合成类文件。如果没有进行编辑并且版本保持兼容,则往返应该会产生相同的类文件,但可能会丢失行号映射。如果您在往返情况下需要一点点相同的副本,您可能需要更改工具以获取纯元数据的代码方面。

jasmin 相当陈旧,设计起来并不容易在汇编中实际编写完整的程序,但对于修改字符串常量表和常量来说,它应该绰绰有余。

于 2009-09-22T23:38:58.403 回答
2

茉莉和基梅拉?

于 2009-09-20T13:58:21.093 回答
1

看起来ASM是这样做的。(这与 ShuggyCoUk 的答案相同,但使用了不同的工具。)Jarjar说它使用 ASM 来完成您所说的那种事情。

于 2011-09-16T15:32:01.683 回答
1

我已经编写了一个专门为此而设计的工具。

Krakatau 反汇编器和汇编器旨在处理任何有效的类文件,无论多么奇怪。它使用基于 Jasmin 格式的程序集格式,但扩展为支持 Jasmin 无法处理的所有类文件功能。它甚至支持 Hotspot 的一些晦涩或未记录的“功能”,例如45.3使用较小宽度的代码属性字段的预类文件。

它可以往返我知道的任何类文件。结果不会是相同的二进制方式,但它将具有相同的功能(例如,可以重新排列常量池条目)。

更新:Krakatau 现在支持类文件的精确二进制往返。传递-roundtrip标志将保留常量池条目的顺序等。

于 2013-03-02T20:32:50.293 回答
-2

没有。存在没有相应 Java 程序的有效字节码。

Soot 项目有一个非常复杂的反编译器- http://www.sable.mcgill.ca/dava/ - 这对于来自 Java 编译器的那些字节码可能很有用。然而,它并不完美。

您最好的选择仍然是获取类文件的源代码。

于 2009-09-20T19:57:16.577 回答