Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java disassemble reassemble

Say I want to take a java class file, disassemble it, tweak the java bytecode output, and then reassemble it again.

I need to rename a symbol in the constant pool table. I also don't have access to the source code, and using a decompiler seems like overkill for this. I'm not trying to optimize anything - java does a fine job at that.

Is there... a simple way to do this? I've found several tools for either disassembly or reassembly, but none for both; or no pairs of tools which seem to use the same format for representing the bytecode in text.

like image 690
Lunpa Avatar asked Dec 08 '22 00:12

Lunpa


2 Answers

Did you check the ASM API?

Here is a code sample (adapted from the official documentation) explaining how to modify a class bytecode:

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

Then b2 can be stored in a .class file for future use. You can also use the method ClassLoader.defineClass(String,byte[],int,int) to load it if you define your own classloader.

like image 63
Guillaume Avatar answered Dec 09 '22 12:12

Guillaume


This question is a bit older now, but as I don't find this answered anywhere on stackoverflow, let me put it on record:

There's the standard jasper/jasmin combo that I have successfully used in the past:

  • jasper for disassembly to a jasmin-compatible format
  • jasmin which will reassemble jasper's output

The only annoyance with jasper is that it forgets to create a label for the switch default clause, and then jasmin will give you errors like

Main.j:391: JAS Error Label: LABEL0x48 has not been added to the code.

Which then means you have to go into the .j file, and manually fix it. "javap -c" might assist you there. For that bug I'd suggest you jasper and immediately jasmin, before any modifications, just to make sure that works.

You can actually fix that label bug by applying this patch to 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);
    }

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

I submitted it to the author, but I got a feeling the project has not been worked on for many years, so I don't know if it'll get merged in.

Edit: Jasper with the above patch applied is now available at https://github.com/EugenDueck/Jasper

And then there's Eclipse Bytecode Outline, as described in this answer: java bytecode editor?

like image 24
Eugen Dück Avatar answered Dec 09 '22 12:12

Eugen Dück