将JVM字节码往返的文本表示和返回的故障安全方法

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

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

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

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

根据上述要求,是否存在实现JVM类文件/文本表示/类文件往返的故障安全方法?

更新:在回答之前 – 通过阅读上述所有要求节省时间和精力,并具体说明:

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

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

这可以修改,然后重新组合成类文件。 如果没有进行编辑并且版本保持兼容,则往返应该导致相同的类文件,除了行号映射可能丢失。 如果您需要为往返案例提供一点点相同的副本,您可能需要更改该工具以获取纯元数据的代码方面。

jasmin相当陈旧,并不是很容易在程序集中编写完整的程序,但是为了修改字符串常量表和常量,它应该是足够的。

Jasmin和Kimera?

看起来像ASM这样做。 (这与ShuggyCoUk的答案相同,但是使用了不同的工具。) Jarjar说它使用ASM来实现你正在谈论的那种东西。

我写了一个专门为此设计的工具。

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

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

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

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

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

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