ASM Keep Method Calls Logs

736 views Asked by At

I want to keep track of all method calls. I have an additional class which is named writerTest. So I want to add method call for writerTest.print(FullMethodName) at the beginning of each method. I worked on it. Found some tutorials about it but I could not handle. Here is the code I have. In this particular example I could add method call at the first line. But I could not get method name with ALOAD 0 or etc. ALOAD 0 gets this. If I used visitMethodInsn instead of visitcode, result is wrong

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
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;

public class MyInstrumenter {
public static void main(final String args[]) throws Exception {
    FileInputStream is = new FileInputStream(args[0]);
    byte[] b;

    ClassReader cr = new ClassReader(is);
    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
    ClassVisitor cv = new ClassAdapter(cw);
    cr.accept(cv, 0);
    b = cw.toByteArray();

    FileOutputStream fos = new FileOutputStream(args[1]);
    fos.write(b);
    fos.close();
  }
 }

Class Adapter Class

class ClassAdapter extends ClassVisitor implements Opcodes {

public ClassAdapter(final ClassVisitor cv) {
    super(ASM5, cv);
}

@Override
public MethodVisitor visitMethod(final int access,
                                 final String name,
                                 final String desc,
                                 String signature,
                                 String[] exceptions) {
    MethodVisitor mv = cv.visitMethod(access, name, desc, signature,     exceptions);
    return new MethodAdapter(mv) ;
  }
}

Method Adapter class

class MethodAdapter extends MethodVisitor implements Opcodes {

public MethodAdapter(final MethodVisitor mv) {
    super(ASM5, mv);
}

 @Override
 public void visitCode() {

     mv.visitVarInsn(Opcodes.ALOAD, 0);
     mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/yunus/test", "print", "      (Ljava/lang/Object;)V",false);
     super.visitCode();

  }
 }
2

There are 2 answers

0
Gilad On

You did not describe what was went wrong... Can you please add the details?

Two pointers: 1. in visitCode() call super.visitCode() before you execute your own code.

  1. The code you wrote won't work when applied to static methods (ALOAD 0 won't get "this")
0
adaf On

Dump ASM and switch to the simpler Javaassist. It has less control over opcodes but will get you there much faster. You will not need to worry about tiny errors like too many spaces in your "visitMethodInsn" call (and more complicated byte code problems).