4

I have been trying to use ASM framework to inject bytecode at my interested location and I have been successful till now.Currently I am trying to inject code which basically creates a new instance/object of a class and after reading a bit I found that this can be achieved using INVOKESPECIAL (I hope my understanding was right of INVOKESPECIAL "INVOKESPECIAL for private methods and constructors").

Below is the code snippet I used to create instance

visitor.visitLdcInsn(System.currentTimeMillis());
visitor.visitLdcInsn(System.currentTimeMillis());
visitor.visitLdcInsn(_type);
visitor.visitVarInsn(ALOAD, metanamevarindex);

eventObject = newLocal(Type.getType("com/vish/RequestTrackerEvent"));

visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "com/vish/RequestTrackerEvent", "<init>",
                            "(JJLjava/lang/String;Ljava/lang/String;)V");

visitor.visitVarInsn(ASTORE, eventObject);

The constructor of the class takes in 4 arguments (long,long,String,String) But whenever I do this I get an exception like below

java.lang.VerifyError: JVMVRFY036 stack underflow;
    at java.lang.J9VMInternals.verifyImpl(Native Method)
    at java.lang.J9VMInternals.verify(J9VMInternals.java:72)
    at java.lang.J9VMInternals.verify(J9VMInternals.java:70)
    at java.lang.J9VMInternals.initialize(J9VMInternals.java:134)

Can anyone help me in understanding whether my usage/understanding of INVOKESPECIAL is right, if right then where am I doing wrong?

Thanks

VishwanathB
  • 139
  • 2
  • 10

2 Answers2

2

I don't remeber exactly what newLocal() does, but I do know that the method does not insert a NEW instruction into the bytecode. It merly reserves space in some ASM internal local variable handling mechanisms.

Try instead using something like

visitor.visitTypeInst(Opcodes.NEW, "com/vish/RequestTrackerEvent");

Good luck

ruediste
  • 2,434
  • 1
  • 21
  • 30
  • Thanks ruediste ,I am new to ASM and ByteCode manipulation stuff, i will try what you suggested. – VishwanathB Sep 05 '13 at 17:04
  • I read a article written by Eugene Kuleshov and it stated this "Note that this transformation can’t be used to intercept class construction (new in Java language). In the bytecode object construction represented by two separate instructions that can be far apart in the steam of events. First one is NEW opcode that creates not-initialized object instance of specified type. Before that instance could be used, method of that instance has to be called using INVOKESPECIAL opcode." I used your suggestion along with INVOKESPECIAL after which i was able to create new instance with arguments – VishwanathB Sep 05 '13 at 17:50
  • It should be visitor.visitTypeInsn instead. Insn not Inst. – bumfo Jan 24 '23 at 03:18
1

Question like "how do I generate {some Java code} with ASM" has been answered in ASM FAQ:

If you want to know how to generate a synchronized block, a try catch block, a finally statement, or any other Java construct, write the Java code you want to generate in a temporary class, compile it with javac, and then use the ASMifier to get the ASM code that will generate this class (see "10. How do I get the bytecode of an existing class?").

You can go even further, by comparing output of ASMifier before and after transformation as described in this article.

Eugene Kuleshov
  • 31,461
  • 5
  • 66
  • 67
  • Thanks Eugene those links were really helpful..Also the javadocs for ClassVisitor and MethodVisitor OPCODES do not have description of what each method does or indicates what different OPCODES does...Is there a link or documenation where i can get more details about the ASM API's?? – VishwanathB Sep 06 '13 at 14:19
  • That would be another question with a separate answer... :) – Eugene Kuleshov Sep 06 '13 at 18:50
  • Thanks Euguene will open another question :P – VishwanathB Sep 10 '13 at 05:21