[kaffe] Re: Decoding compiled class files

Andy Georges andy.georges@elis.ugent.be
Tue May 13 08:20:05 2003


--------------Boundary-00=_87YTCP0CFWGG6MFBIDXU
Content-Type: text/plain;
  charset="iso-8859-1"
Content-Transfer-Encoding: 8bit

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello,

> I want something that decodes and prints out the entire contents of
> the .class file structure, so that I can see the variables, constants
> pool, initialisation, operations performed by bytecode, etc, etc.
> I'm trying to identify and then fix the difference of a single byte
> between two very simple files.

I have attached a small utility which may just do what you want. Sun's 
javap -c is also quite nice.

You will need BCEL tho'. 

http://jakarta.apache.org/bcel/

- -- 
- --
==========================================================================
Parallel Information Systems Group - Dept. ELIS - Ghent University
St. Pietersnieuwstraat 41, 9000 Ghent, Belgium
Phone: +32-9-264.33.67,   Fax: +32-9-264.35.94
E-mail: andy.georges@elis.rug.ac.be 
==========================================================================
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE+wQRkyhGN8W62M+IRArArAJ9Pl453NSP7Jki1WZdDaOoZ2pXQVwCfVNl+
whc3O90J3Bdsvbzntp1+pyQ=
=2Vjo
-----END PGP SIGNATURE-----

--------------Boundary-00=_87YTCP0CFWGG6MFBIDXU
Content-Type: text/x-java;
  charset="iso-8859-1";
  name="ShowClass.java"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="ShowClass.java"


import java.io.*;


import org.apache.bcel.*;
import org.apache.bcel.generic.*;
import org.apache.bcel.classfile.*;
import org.apache.bcel.util.*;



public class ShowClass {


	public static void writeConstantPool(JavaClass clazz) {

		System.out.println(clazz.getConstantPool());

	}

	public static void writeFields(JavaClass clazz) {

		Field [] fields = clazz.getFields();

		for(int i = 0; i < fields.length; ++i) {
			System.out.println(fields[i]);
		}

	}

	public static void writeMethods(JavaClass clazz) {

		ClassGen           clazzGenerator        = new ClassGen(clazz);
		ConstantPoolGen    constantPoolGenerator = clazzGenerator.getConstantPool();
		ConstantPool 	   cp		 	 = constantPoolGenerator.getConstantPool();

		Method [] methods = clazzGenerator.getMethods();

		for(int i = 0; i < methods.length; ++i) {
			System.out.println(methods[i]);
			MethodGen mg = new MethodGen(methods[i],clazzGenerator.getClassName(), constantPoolGenerator);
			System.out.println("maxlocals = " + 
					mg.getMaxLocals() +
					" maxstack = " + 
					mg.getMaxStack());
			InstructionList instrList = mg.getInstructionList();
			if(instrList != null) {
				InstructionHandle [] instructionHandles = instrList.getInstructionHandles();
				for(int j = 0; j < instructionHandles.length; ++j) {
					System.out.print(instructionHandles[j].getPosition() + ":\t");
					System.out.println(instructionHandles[j].getInstruction().toString(cp));
				}
				//		    System.out.println(instrList.toString(true));
			}
			else {
				System.out.println("NATIVE METHOD");
			}

			System.out.println("\n\n");

		}

	}


	public static void writeInterfaces(JavaClass clazz) {

		ClassGen           clazzGenerator        = new ClassGen(clazz);

		String [] interfaces = clazzGenerator.getInterfaceNames();
		for(int i = 0; i < interfaces.length; ++i) {
			System.out.println("interface -> " + interfaces[i]);
		}

	}


	public static void main(String [] args) throws IOException {

		if(args.length == 0) {
			System.err.println("You must give a valid filename.");
			System.exit(-1);
		}

		File file = new File(args[0]);

		JavaClass clazz;
		if(! (file.exists() && file.isFile()) ) {
			clazz = Repository.lookupClass(args[0]);
		}
		else {
			ClassParser cParser = new ClassParser(args[0]);
			clazz = cParser.parse();
		}
		if(clazz == null) {
			System.exit(42);
		}

		System.out.println("constants ---->");
		writeConstantPool(clazz);
		System.out.println("fields ------->");
		writeFields(clazz);
		System.out.println("interfaces --->");
		writeInterfaces(clazz);
		System.out.println("methods ------>");
		writeMethods(clazz);

	}


}

--------------Boundary-00=_87YTCP0CFWGG6MFBIDXU--