-2

I'm facing a problem that I think I'm not using the right terms to search for a solution.

So, I have bytecode in the form of text (String), like below:

public class HelloWorld {
  public HelloWorld();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: iconst_0
       1: istore_1
       2: iinc          1, 1
       5: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       8: new           #3                  // class java/lang/StringBuilder
      11: dup
      12: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V
      15: ldc           #5                  // String Hello World
      17: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      20: iload_1
      21: invokevirtual #7                  // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      24: invokevirtual #8                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      27: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      30: return
}

Now I need to compile it to a .class file.

I looked at ASM, Jasmin and other assembler tools, but could not figure out a proper solution. What I understood from these tools is that you write a program in a specific instruction set language and it transforms it to a binary file. But what I'm looking for is using JVM own regular instruction set.

I appreciate any help.

  • are you trying to convert just this one instance or are you looking for an answer to general case? The stuff you have is quite trivial to transform to code manually. – eis Jan 08 '18 at 18:43
  • 2
    There is no standard Java assembly language, hence, you have to live with a tool-specific one. Most notably, the output from `javap` is not suitable for building the class file again. Your question’s example would not work anyway as the constant pool is missing. When you already looked at existing Java assembler tools you might have noticed that their syntax is close to the well-known `javap` output; that’s the best you can get. – Holger Jan 08 '18 at 18:45
  • Specifying a little more, the example given is just a simple example. Code I would be using are generic and could be more complex. I have both a .class and a .txt containing the bytecode used to generate the .class file. I needed to merge some classes (I'm generating fault-seeded code using code mutation) and the approach I used was diff-merge the txt of the classes. Now I have a new txt which I need to generate a .class. Maybe I could disassemble the .class files using a specific assembler framework and then reassemble using the same assembler. Would it work? – Heleno Campos Jan 08 '18 at 19:03
  • This could work. I would assume that every specific assembler package is capable of (re-)assembling its own disassembly format. Some of them even interoperate, e.g. Krakatau understands Jasmin syntax. – Holger Jan 08 '18 at 19:06
  • I will try this approach. Thanks @Holger. – Heleno Campos Jan 08 '18 at 19:11
  • 1
    @Holger Technically, Krakatau no longer supports Jasmin syntax. I originally aimed to be jasmin compatible, but that made it impossible to support certain features like binary roundtripping, and it didn't seem like anyone was actually using Jasmin, so I dropped it in the big "v1" rewrite. However, the syntax does remain very similar to Jasmin. – Antimony Jan 09 '18 at 01:51

2 Answers2

2

It looks you have javap output. Unfortunately, javap is just meant to be a quick debugging tool and the output is not designed to be able to be reassembled into a classfile.

If you want to be able to disassemble and reassemble classfiles, I'd highly recommend using Krakatau, which fully supports the classfile specification plus some undocumented features and can roundtrip arbitrary classfiles from binary to text and back.

If you want to do this programatically and don't need advanced features, I'd recommend using ASM instead, which is a library rather than a CLI tool.

Antimony
  • 37,781
  • 10
  • 100
  • 107
0

See, class file consist a Bytecode. So when you written a java source program Hello.java and compiled it using javac Hello.java. It gives you a class file i.e Hello.class This class file consist of a Java Bytecode which you can see by command : javap -c Hello.class

So the above code you have sended, is already a compiled Bytecode by javac compiler, and it a class file.

Ratnesh
  • 298
  • 3
  • 14