java反汇编重新组装

时间:2010-11-15 16:48:08

标签: java bytecode-manipulation

假设我想要一个java类文件,反汇编它,调整java字节码输出,然后重新组装它。

我需要重命名常量池表中的符号。我也无法访问源代码,使用反编译器似乎有点过分。我并没有尝试优化任何东西 - java在那方面做得很好。

有......一个简单的方法吗? 我找到了几种用于拆卸或重新组装的工具,但两者都没有;或者没有一对工具似乎使用相同的格式来表示文本中的字节码。

5 个答案:

答案 0 :(得分:6)

您是否检查了ASM API?

这是一个代码示例(改编自官方文档),解释了如何修改类字节码:

ClasssWriter cw = new ClassWriter();
ClassAdapter ca = new ClassAdapter(cw); // ca forwards all events to cw
// ca should modify the class data
ClassReader cr = new ClassReader("MyClass");
cr.accept(ca, 0);
byte[] b2 = cw.toByteArray(); // b2 represents the same class as MyClass, modified by ca

然后b2可以存储在.class文件中以备将来使用。如果您定义自己的类加载器,也可以使用方法ClassLoader.defineClass(String,byte[],int,int)加载它。

答案 1 :(得分:5)

这个问题现在有点老了,但是我没有在stackoverflow上的任何地方找到答案,让我把它记录下来:

我过去成功使用了标准的 jasper / jasmin 组合:

  • jasper用于反汇编为jasmin兼容格式
  • jasmin将重新组合jasper的输出

jasper的唯一烦恼是忘记为switch default子句创建标签,然后jasmin会给你错误,如

  

Main.j:391:JAS错误标签:LABEL0x48尚未添加到代码中。

这意味着你必须进入.j文件,并手动修复它。 “javap -c”可能会帮助你。对于那个bug,我会建议你jasper和jasmin,在进行任何修改之前,只是为了确保有效。

您可以通过将此补丁应用于jasper来实际修复该标签错误:

--- Code_Collection.java.orig   1999-06-14 14:10:44.000000000 +0000
+++ Code_Collection.java        2011-02-05 07:23:21.000000000 +0000
@@ -1210,6 +1210,7 @@
     -----------------------------------------------------------------------*/
    void getLabel(Code_Collection code) {
       for (int i = 0; i < count; i++) code.setLabel(pc+branch[i]);
+      code.setLabel(pc+tableDefault);
    }

    /*-----------------------------------------------------------------------

我已将它提交给作者,但我感觉这个项目已经工作多年了,所以我不知道它是否会被合并。

修改:已应用上述修补程序的Jasper现已在https://github.com/EugenDueck/Jasper

提供

然后有 Eclipse字节代码大纲,如本答案中所述: java bytecode editor?

答案 2 :(得分:2)

Krakatau提供了一个开源的反汇编程序和汇编程序,使这很容易。 Krakatau旨在成为Jasmin的替代品。它使用类似Jasmin的语法来实现向后兼容,但扩展了格式以支持类文件格式中的所有模糊功能并修复Jasmin中的错误。它还可以让您轻松地反汇编,修改和重新组合类。

Krakatau唯一真正的缺点是它目前没有很好地记录。但如果您有任何疑问,请随时提出。 (披露:我写过Krakatau)。

答案 3 :(得分:0)

找到原始源代码,修改它然后重新编译它会不会更容易?或者这是来自某些二进制代码,你没有源代码?

专业提示:内置Java类库的源代码作为OpenJDK项目的一部分提供,特别是在OpenJDK 6 Source中。

答案 4 :(得分:0)

您正在描述现代编译器已经做了什么。除此之外,大多数JVM可以(并尝试)在应用程序运行时继续优化字节代码。

首先研究现有编译器/ JVM使用字节代码进行的操作。最好的情况是你可以改进JVM的优化器,这是可能的,但概率很低,无论哪种方式你都可以重新发明轮子。最糟糕的情况是您的更改实际上会干扰运行时优化程序并导致整体性能下降。

  1. 学习编译器和JVM
  2. 基准
  3. 基准
  4. 基准
  5. [编辑]找到相关帖子:Bytecode manipulation patterns