java - ASM AdviceAdapter onMethodEnter - Print all arguements -
i'm looking use asm print values of parameters passed method. i've found examples, can't make sense of it. honest, haven't done "homework" in sense haven't studied asm as need in order build this. if anyone's willing me out great.
just example, method returns void , takes single integer parameter.
(and i've seen example @ https://gist.github.com/vijaykrishna/1ca807c952187a7d8c4d)
okay figured out. here go.
here's method injector class. reads in class file (print.class) , adds instruction print int whenever printint method gets called
package asm; import java.io.file; import java.io.fileinputstream; import java.io.fileoutputstream; import java.io.ioexception; import org.objectweb.asm.annotationvisitor; import org.objectweb.asm.attribute; import org.objectweb.asm.classreader; import org.objectweb.asm.classvisitor; import org.objectweb.asm.classwriter; import org.objectweb.asm.label; import org.objectweb.asm.methodvisitor; import org.objectweb.asm.opcodes; import org.objectweb.asm.commons.adviceadapter; public class printinjector extends classvisitor { public printinjector(int api, classvisitor mv) { super(api, mv); } @override public methodvisitor visitmethod(int access, string name, string desc, string signature, string[] exceptions) { methodvisitor mv = cv.visitmethod(access, name, desc, signature, exceptions); system.out.println(string.format("%s %s %s", name, desc, signature)); if(name.equals("printint")) mv = new printsingleintparameter(opcodes.asm5, mv, access, name, desc); return mv; } public static void main(string[] args) throws ioexception { classreader cr = new classreader(new fileinputstream(new file("bin\\print.class"))); classwriter cw = new classwriter(classwriter.compute_maxs | classwriter.compute_frames); printinjector pi = new printinjector(opcodes.asm5, cw); cr.accept(pi, 0); fileoutputstream fos = new fileoutputstream(new file("print.class")); fos.write(cw.tobytearray()); fos.flush(); fos.close(); } class printsingleintparameter extends adviceadapter { protected printsingleintparameter(int api, methodvisitor mv, int access, string name, string desc) { super(api, mv, access, name, desc); } @override protected void onmethodenter() { label l0 = new label(); mv.visitlabel(l0); mv.visitfieldinsn(getstatic, "java/lang/system", "out", "ljava/io/printstream;"); mv.visitvarinsn(iload, 0); //1 instead of 0 if printint wasn't static mv.visitmethodinsn(invokevirtual, "java/io/printstream", "println", "(i)v", false); } } }
here's print.class
public class print { public static int printint(int i) { system.out.println(i); return i; } public static void main(string[] args) { int = printint(10); system.out.println("done"); } }
the output
10 a:10 done
you're going need adjust code in onmethodenter suit whatever needs have. i'm realizing code have doesn't keep bytecode clean (as in breaks when use in other programs use registers after code ran).
Comments
Post a Comment