thierry-janaudys-powerbook-g4-17:~/Easily.co.uk/janaudy-ws/byteslayer thierryjanaudy$
ByteSlayer
[Sept, 10th 2005]
I became quite bored lately and I decided to write a Java decompiler.
Before I could do that, I needed to fully understand the Java byte-code instructions;
so I decided to write my own javap tool. It is part of a framework called ByteSlayer.
I like the name ;-).
So, what does it do? It does exactly what it says on the can, it gets a Java .class
and spits out the byte code instructions, exactly like javap.
Here is a stupid Java class:
package org.byteslayer.test;
import java.awt.Point;
public abstract class Shape {
private Point location = null;
public Shape() {this.location = new Point(0, 0);}
public Shape(Shape s) {this.location = s.getLocation();}
public abstract void paint();
public native void renderOpenGL();
public Point getLocation() {return this.location;}
}
The official javap tools produces:
thierry-janaudys-powerbook-g4-17:~/Projects/ByteSlayer/classes thierryjanaudy$ javap -c -private -classpath . org.byteslayer.test.Shape
HotSpot not at correct virtual address. Sharing disabled.
Compiled from "Shape.java"
public abstract class org.byteslayer.test.Shape extends java.lang.Object{
private java.awt.Point location;
public org.byteslayer.test.Shape();
Code:
0: aload_0
1: invokespecial #11; //Method java/lang/Object."":()V
4: aload_0
5: aconst_null
6: putfield #13; //Field location:Ljava/awt/Point;
9: aload_0
10: new #15; //class java/awt/Point
13: dup
14: iconst_0
15: iconst_0
16: invokespecial #18; //Method java/awt/Point."":(II)V
19: putfield #13; //Field location:Ljava/awt/Point;
22: return
public org.byteslayer.test.Shape(org.byteslayer.test.Shape);
Code:
0: aload_0
1: invokespecial #11; //Method java/lang/Object."":()V
4: aload_0
5: aconst_null
6: putfield #13; //Field location:Ljava/awt/Point;
9: aload_0
10: aload_1
11: invokevirtual #27; //Method getLocation:()Ljava/awt/Point;
14: putfield #13; //Field location:Ljava/awt/Point;
17: return
public abstract void paint();
public native void renderOpenGL();
public java.awt.Point getLocation();
Code:
0: aload_0
1: getfield #13; //Field location:Ljava/awt/Point;
4: areturn
}
ByteSlayer produces this:
package org.byteslayer.test;
public abstract class Shape extends java.lang.Object {
private java.awt.Point location;
public void Shape() {
0: (0x2a aload_0)
1: (0xb7 invokespecial) 0 b -> Method :()V in class java.lang.Object
4: (0x2a aload_0)
5: (0x1 aconst_null)
6: (0xb5 putfield) 0 d -> Method location:Ljava/awt/Point; in class org.byteslayer.test.Shape
9: (0x2a aload_0)
10: (0xbb new) 0 f -> java.awt.Point
13: (0x59 dup)
14: (0x3 iconst_0)
15: (0x3 iconst_0)
16: (0xb7 invokespecial) 0 12 -> Method :(II)V in class java.awt.Point
19: (0xb5 putfield) 0 d -> Method location:Ljava/awt/Point; in class org.byteslayer.test.Shape
22: (0xb1 return)
}
public void Shape(org.byteslayer.test.Shape local1) {
0: (0x2a aload_0)
1: (0xb7 invokespecial) 0 b -> Method :()V in class java.lang.Object
4: (0x2a aload_0)
5: (0x1 aconst_null)
6: (0xb5 putfield) 0 d -> Method location:Ljava/awt/Point; in class org.byteslayer.test.Shape
9: (0x2a aload_0)
10: (0x2b aload_1)
11: (0xb6 invokevirtual) 0 1b -> Method getLocation:()Ljava/awt/Point; in class org.byteslayer.test.Shape
14: (0xb5 putfield) 0 d -> Method location:Ljava/awt/Point; in class org.byteslayer.test.Shape
17: (0xb1 return)
}
public abstract void paint();
public native void renderOpenGL();
public java.awt.Point getLocation() {
0: (0x2a aload_0)
1: (0xb4 getfield) 0 d -> Method location:Ljava/awt/Point; in class org.byteslayer.test.Shape
4: (0xb0 areturn)
}
}
Get the everything for ByteSlayer.zip (630 Kb),
or just the byteslayer-src.zip (40 Kb),
or just the executable byteslayer-0.2.jar (64 Kb), to be used like:
[Usage] java -cp %CP% org.byteslayer.main.Javap
Also, you might like this list of opcodes-with-semicolon.txt (4 Kb),
or more, this XL spreadsheet opcodes.xls (96 Kb) that I used to generate some code.
The ByteSlayer javadocs are also available.
What's next?
Well, I have some refactoring to do here because it was my first time ;-) I am not pleased with the way
I handled the operands. This version does not handle the wide and lookupswitch instructions.
What I would like to do is to come up with my own decompiler tool, and also my own simplistic AOP framework.
thierry at janaudy dot com