Christian Collberg
Department of Computer Science
University of Arizona
To open a class file for editing you do the following:
org.apache.bcel.classfile.ClassParser p = new org.apache.bcel.classfile.ClassParser(classFile); org.apache.bcel.classfile.JavaClass jc = p.parse() org.apache.bcel.generic.ClassGen cg = new org.apache.bcel.generic.ClassGen(jc); org.apache.bcel.generic.ConstantPoolGen cp = new org.apache.bcel.generic.ConstantPoolGen( jc.getConstantPool());
org.apache.bcel.classfile.JavaClass jc1 = cg.getJavaClass(); jc1.setConstantPool(cp.getFinalConstantPool()); jc1.dump(classFile1);
org.apache.bcel.generic.ConstantPoolGen cp = ...; org.apache.bcel.generic.ClassGen cg = ...; org.apache.bcel.classfile.Method method = cg.containsMethod(methodName, methodSignature); org.apache.bcel.generic.MethodGen mg = new org.apache.bcel.generic.MethodGen(method,cname,cp);
org.apache.bcel.generic.MethodGen mg = ...; org.apache.bcel.generic.InstructionList il = mg.getInstructionList(); org.apache.bcel.generic.InstructionHandle[] ihs = il.getInstructionHandles(); for(int i=0; i < ihs.length; i++) { org.apache.bcel.generic.InstructionHandle ih = ihs[i]; org.apache.bcel.generic.Instruction instr = ih.getInstruction(); }
org.apache.bcel.generic.Instruction inst = ...; org.apache.bcel.generic.InstructionHandle ih = ...; if (inst instanceof org.apache.bcel.generic.INVOKESTATIC){ org.apache.bcel.generic.INVOKESTATIC call = (org.apache.bcel.generic.INVOKESTATIC) inst; String className = call.getClassName(cp); String methodName = call.getMethodName(cp); String methodSig = call.getSignature(cp); ih.setInstruction(new org.apache.bcel.generic.NOP()); }
void P() { int x= 5; System.out.println(x); float y=5.6; System.out.println(y); }
org.apache.bcel.generic.Type T = ...; org.apache.bcel.generic.LocalVariableGen lg = mg.addLocalVariable(localName, T, null, null); int localIndex = lg.getIndex(); // push something here org.apache.bcel.generic.Instruction store = new org.apache.bcel.generic.ASTORE(localIndex); org.apache.bcel.generic.InstructionHandle start = ...; lg.setStart(start);
org.apache.bcel.generic.LocalVariableGen lg = mg.addLocalVariable(localName, T, null, null); ... org.apache.bcel.generic.InstructionHandle start = ...; lg.setStart(start);
int flags = org.apache.bcel.Constants.ACC_PUBLIC; String class_name = "MyClass"; String file_name = "MyClass.java"; String super_class_name = "java.lang.Object"; String[] interfaces = {}; org.apache.bcel.generic.ClassGen cg = new org.apache.bcel.generic.ClassGen( class_name, super_class_name, file_name, flags, interfaces);
org.apache.bcel.generic.ConstantPoolGen cp = cg.getConstantPool(); org.apache.bcel.generic.Type field_type = org.apache.bcel.generic.Type.INT; String field_name = "field1"; org.apache.bcel.generic.FieldGen fg = new org.apache.bcel.generic.FieldGen( access_flags, field_type, field_name, cp); cg.addField(fg.getField());
int method_access_flags = org.apache.bcel.Constants.ACC_PUBLIC | org.apache.bcel.Constants.ACC_STATIC; org.apache.bcel.generic.Type return_type = org.apache.bcel.generic.Type.VOID; org.apache.bcel.generic.Type[] arg_types = org.apache.bcel.generic.Type.NO_ARGS; String[] arg_names = {};
String method_name = "method1"; String class_name = "MyClass"; org.apache.bcel.generic.InstructionList il = new org.apache.bcel.generic.InstructionList(); il.append( org.apache.bcel.generic.InstructionConstants.RETURN); org.apache.bcel.generic.MethodGen mg = new org.apache.bcel.generic.MethodGen( method_access_flags, return_type, arg_types, arg_names, method_name, class_name, il, cp); mg.setMaxStack(); cg.addMethod(mg.getMethod());
org.apache.bcel.generic.InstructionList il = ...; org.apache.bcel.generic.IFNULL branch = new org.apache.bcel.generic.IFNULL(null); il.append(branch); ...
org.apache.bcel.generic.InstructionHandle h = il.append(new org.apache.bcel.generic.NOP()); branch.setTarget(h);
org.apache.bcel.generic.InstructionList il = ...; org.apache.bcel.generic.MethodGen mg = ...; String exception = "java.lang.Exception"; org.apache.bcel.generic.InstructionHandle start_pc = il.append(new org.apache.bcel.generic.NOP()); // The code that builds the try-body goes here. // Code to jump out of the try-block: org.apache.bcel.generic.GOTO branch = new org.apache.bcel.generic.GOTO(null);
org.apache.bcel.generic.InstructionHandle end_pc = il.append(branch); // Pop exception off stack when entering catch block. org.apache.bcel.generic.InstructionHandle handler_pc = il.append(new org.apache.bcel.generic.POP()); // The code that builds the catch-body goes here. // Add a NOP after the exception handler. This is // where we will jump after we're through with the // try-block. org.apache.bcel.generic.InstructionHandle next_pc = il.append(new org.apache.bcel.generic.NOP()); branch.setTarget(next_pc);
org.apache.bcel.generic.ObjectType catch_type = new org.apache.bcel.generic.ObjectType(exception); org.apache.bcel.generic.CodeExceptionGen eg = mg.addExceptionHandler( start_pc, end_pc, handler_pc, catch_type);
BaseType | Type | Interpretation | |
B | byte | signed 8-bit integer | |
C | char | Unicode character | |
D | double | 64-bit floating point value | |
F | float | 32-bit floating point value | |
I | int | 32-bit integer | |
J | long | 64-bit integer | |
L<classname>; | reference | instance of class <classname> | |
S | short | signed 16-bit integer | |
Z | boolean | true pr false | |
[ | reference | one array dimension | |
V | void | ||
(BaseType*)BaseType | method descriptor |
org.apache.bcel.generic.Type return_type = org.apache.bcel.generic.Type.VOID; org.apache.bcel.generic.Type[] arg_types = new org.apache.bcel.generic.Type[] { new org.apache.bcel.generic.ArrayType( org.apache.bcel.generic.Type.STRING, 1) };
java.lang.Object[]bytecode format
[Ljava/lang/Object;and BCEL's internal format org.apache.bcel.generic.Type.
String S = "[Ljava/lang/Object;"; org.apache.bcel.generic.Type T = org.apache.bcel.generic.Type.getType(S); System.out.println(T); // ==> "java.lang.Object[]".
String type = "java.lang.Object[]"; String S = org.apache.bcel.classfile.Utility.getSignature(type); System.out.println(S); ==> [Ljava/lang/Object;
String S = "(Ljava/lang/String;I)V;"; org.apache.bcel.generic.Type[] arg_types = org.apache.bcel.generic.Type.getArgumentTypes(S); org.apache.bcel.generic.Type return_type = org.apache.bcel.generic.Type.getReturnType(S); String M = org.apache.bcel.generic.Type.getMethodSignature( return_type, arg_types);
org.apache.bcel.generic.Type T = org.apache.bcel.generic.Type.STRINGBUFFER; String M = T.getSignature(); System.out.println(M);will print out Ljava/lang/StringBuffer;.
String className = ...; String methodName = ...; String signature = ...; org.apache.bcel.generic.InstructionList il = ...; org.apache.bcel.generic.ConstantPoolGen cp = ...;
// Generate code that pushes the actual // arguments of the call. int index = cp.addMethodref(className,methodName,signature); org.apache.bcel.generic.INVOKESTATIC call = new org.apache.bcel.generic.INVOKESTATIC(index); il.append(call);
// Generate code pushing the object on the stack. // Generate code pushing the actual arguments. int index = cp.addMethodref(className,methodName,signature); org.apache.bcel.generic.INVOKEVIRTUAL s = new org.apache.bcel.generic.INVOKEVIRTUAL(index); il.append(call);
public class List { public static void main(String args[]) throws java.io.IOException { String classFile = args[0]; String className = classFile.substring( 0,classFile.length()-".class".length()); org.apache.bcel.classfile.ClassParser p = new org.apache.bcel.classfile.ClassParser(classFile); org.apache.bcel.classfile.JavaClass jc = p.parse(); org.apache.bcel.generic.ClassGen cg = new org.apache.bcel.generic.ClassGen(jc);
org.apache.bcel.classfile.ConstantPool cp = jc.getConstantPool(); org.apache.bcel.generic.ConstantPoolGen cpg = new org.apache.bcel.generic.ConstantPoolGen(cp); org.apache.bcel.classfile.Method[] methods = cg.getMethods(); for(int m=0; m<methods.length; m++) { org.apache.bcel.generic.MethodGen mg = new org.apache.bcel.generic.MethodGen( methods[m],className,cpg); System.out.println("\nMETHOD: " + mg.getClassName() + "." + mg.getName() + ":" + mg.getSignature());
org.apache.bcel.generic.InstructionList il = mg.getInstructionList(); org.apache.bcel.generic.InstructionHandle[] ihs = il.getInstructionHandles(); int pc = 0; for(int i=0; i < ihs.length; i++) { org.apache.bcel.generic.InstructionHandle ih = ihs[i]; org.apache.bcel.generic.Instruction instr = ih.getInstruction(); System.out.println(pc + " : " + instr.toString(cp)); pc += instr.getLength(); } } } }