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

Java 将JVM字节码往返到文本表示和返回的故障安全方法,java,jvm,obfuscation,bytecode,decompiling,Java,Jvm,Obfuscation,Bytecode,Decompiling,我正在寻找一种故障安全的方法,在JVM类文件和文本表示之间来回切换 一个严格的要求是,只要文本表示保持不变,产生的往返JVM类文件在功能上完全等同于原始JVM类文件 此外,文本表示必须是可读和可编辑的。应该可以对文本表示进行小的更改(例如更改文本字符串或类名等),这些更改反映在生成的类文件表示中 最简单的解决方案是使用Java反编译器(如JAD)生成文本表示,在本例中,文本表示就是重新创建的Java源代码。然后使用javac生成字节码。然而,考虑到免费Java反编译器的状态,这种方法并非在所有情

我正在寻找一种故障安全的方法,在JVM类文件和文本表示之间来回切换

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

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

最简单的解决方案是使用Java反编译器(如JAD)生成文本表示,在本例中,文本表示就是重新创建的Java源代码。然后使用javac生成字节码。然而,考虑到免费Java反编译器的状态,这种方法并非在所有情况下都能工作。创建模糊的字节码相当容易,但在完整的往返类文件/java源/类文件中无法生存(部分原因是JVM字节码和java源代码之间没有1:1的映射)

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

更新:回答前-阅读以上所有要求,节省时间和精力,并特别注意:

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

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

烟尘项目有一个非常复杂的反编译器——它可能对来自Java编译器的字节码很有用。然而,它并不完美

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

提供了将类文件转换为程序集的

这可以修改,然后重新组装到类文件中。如果未进行任何编辑且版本保持兼容,则往返过程应产生相同的类文件,但行号映射可能丢失。如果您需要一个完全相同的副本用于往返案例,那么您可能需要修改该工具,以获取代码的某些方面,这些方面也是纯元数据


jasmin已经很老了,它的设计不便于在汇编中编写完整的程序,但是为了修改字符串常量表和常量,它应该已经足够了。

看起来是这样的。(这与ShuggyCoUk的答案是一样的,但使用的工具不同。)说它使用ASM来完成您所谈论的事情。

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

设计用于处理任何有效的类文件,无论这些类文件有多奇怪。它使用基于Jasmin格式的汇编格式,但扩展到支持Jasmin无法处理的所有类文件特性。它甚至支持Hotspot的一些模糊或未记录的“特性”,例如使用较小宽度的代码属性字段的pre
45.3
类文件

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


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

可以使用Kimera创建类文件的.j(Jasmin文件)表示形式吗?请详细说明。“我们开发了一个Java反汇编程序,可以从Java类文件生成与jasmin兼容的输出。”但我找不到下载它的地方。kimera.cs.washington.edu不见了。也可以试试Jasper:它的默认输出应该可以被jasmin使用。正如问题中所指出的,“字节码的文本表示”不一定是“Java源代码”。然后你需要一个Java字节码反汇编程序。。。Java字节码不是很有趣的手工制作。请随意推荐一个满足所述要求的Java字节码反汇编程序。是的,有一个故障安全的方法:创建自己的应用程序。尽管这样做,文本表示可能不是最有用的。也许如果你解释了你的实际问题,人们会给你指出一个更好的解决方案。kdgregory:问题很简单,字节码没有1:1映射到Java源代码,所以要将Java字节码转换成人类可读/可编辑/可汇编的代码,你需要的不是Java反编译器,如果您需要进一步的澄清,请告诉我。您在最初的问题中已经非常清楚了。也许我的回答不够清楚:如果你想要这样一个工具,你必须自己写。人们使用反编译器的原因不是为了对反编译代码进行更改,因此反编译器的输出并不意味着要重新编译,抱歉-你的意思是我应该编写自己的Java应用程序,而不是尝试反编译/反汇编现有的字节码:-)可能会显示你在寻找什么。jasmin-2.4的时间戳是2010-05-07,而之前的版本是jasmin-2.3 2008-01-28,比你的答案早20个月。看起来它是定期更新的。@James这是真的,但是jvm字节码是异常静态的。java 7中新的invoke dynamic东西应该是近年来唯一需要更新的东西,@James,即使它被更新了,Jasmin的问题是它不能代表许多更模糊的类文件特性。