Skip to content

Instantly share code, notes, and snippets.

@VijayKrishna
Last active September 8, 2023 19:53
Show Gist options
  • Save VijayKrishna/1ca807c952187a7d8c4d to your computer and use it in GitHub Desktop.
Save VijayKrishna/1ca807c952187a7d8c4d to your computer and use it in GitHub Desktop.
Example code showing how the AdviceAdapter in ASM(.ow2.org) can be used/extended.
package self.vpalepu.stackoverflow;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.AdviceAdapter;
/**
* Class visitor that adapts a java class to insert code before
* the return instructions in the methods of the class.
* @author vijay
*
*/
public class ReturnAdapter extends ClassVisitor {
private String className;
public ReturnAdapter(ClassVisitor cv, String className) {
super(Opcodes.ASM4, cv);
}
@Override
public MethodVisitor visitMethod(
int access,
String name,
String desc,
String signature,
String[] exceptions) {
MethodVisitor mv;
mv = cv.visitMethod(access, name, desc, signature, exceptions);
mv = new MethodReturnAdapter(Opcodes.ASM4, className, access, name, desc, mv);
return mv;
}
public static void main(String[] args) throws IOException {
String classFile = args[0];//path of the class file
String className = args[1];//name of the class
File inFile = new File(classFile);
FileInputStream in = new FileInputStream(inFile);
// adapting the class.
ClassReader cr = new ClassReader(in);
ClassWriter cw = new ClassWriter(ClassReader.EXPAND_FRAMES);
ReturnAdapter returnAdapter = new ReturnAdapter(cw, className);
cr.accept(returnAdapter, 0);
}
}
/**
* Method Visitor that inserts code right before its return instruction(s),
* using the onMethodExit(int opcode) method of the AdviceAdapter class,
* from ASM(.ow2.org).
* @author vijay
*
*/
class MethodReturnAdapter extends AdviceAdapter {
public MethodReturnAdapter(
int api,
String owner,
int access,
String name,
String desc,
MethodVisitor mv) {
super(Opcodes.ASM4, mv, access, name, desc);
}
public MethodReturnAdapter(
MethodVisitor mv,
int access,
String name,
String desc) {
super(Opcodes.ASM4, mv, access, name, desc);
}
@Override
protected void onMethodExit(int opcode) {
if(opcode != Opcodes.ATHROW) {
mv.visitVarInsn(Opcodes.ALOAD, 42);
// and/or any other visit instructions.
}
}
}
@VijayKrishna
Copy link
Author

I have been busy with paper deadlines these last few weeks. Check back in a couple of days to find better code. Meanwhile, if you want to share the (compile?) error that you are getting, that would be a big help as well!

@Pasupathi-Rajamanickam
Copy link

Can you help me how to use this? I have a class named Hello, it has a method, "sayHello". I did the following in the main method that you have written here.

ByteClassLoader byteClassLoader = new ByteClassLoader();
Class class2 = byteClassLoader.findClass("com.parse.Hello", cw.toByteArray());
System.out.println(class2.getMethods());
System.out.println( ((Hello) class2.newInstance()) .sayHello());
It is showing exception. local variable table overflow in method com.parse.Hello.sayHello()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment