java反汇编重新组装

Lun*_*npa 4 java bytecode-manipulation

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

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

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

Gui*_*ume 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
Run Code Online (Sandbox Code Playgroud)

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


小智 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);
    }

    /*-----------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

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

编辑:应用上述补丁的Jasper现在可以在https://github.com/EugenDueck/Jasper上找到

然后是Eclipse Bytecode Outline,如本答案所述: java字节码编辑器?


Ant*_*ony 5

Krakatau提供了一个开源反汇编程序和汇编程序,使这一切变得非常容易。Krakatau 被设计为 Jasmin 的替代品。它使用类似 Jasmin 的语法来实现向后兼容性,但扩展了格式以支持类文件格式中的所有晦涩功能并修复 Jasmin 中的错误。它还可以让您轻松地反汇编、修改和重新组装类。

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