[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--