Injecting a Java method _before_ another method is called

I am using ASM and want to rewrite something like:

someMethod().targetMethod(args...)

to:

someMethod().injectedMethod(arg).targetMethod(args...)

The trouble is that I don’t know what the method before is, I only know the target method (so finding someMethod() and injecting after that isn’t an option).

I also have many versions of the target method, with different sets of parameters I want this to work with.

Using ASM I can easily find the target method invocation, but unfortunately the operand stack at that point is:

[ argN, ..., arg1, instance, ... ]

And while I can work out how far down the instance will be, there’s no bytecode I can inject that will read it. I know you can do it for up to 4 parameters using tricks with dup commands, but I need a general solution.

I could add a bunch of local variables and copy everything off the stack, dup the instance pointed and put everything back on, but that’s a runtime inefficiency I really don’t want.

What I think would work is if I could track which instruction(s) were responsible for putting the instance pointer on the stack, and then I could inject my method invocation there rather than at the target method invocation. However I have had no luck in finding anything to help me do this.

I know that things like AspectJ allow for this, but have to do this for a lot of classes as they load and AspectJ is just too slow.

Can anyone point me at analysis tools built on top of ASM that might let me do this or can anyone think of a better approach for injecting one method call before another?

Java – Calling one method before another

Using class methods, I want to make sure that the getAverage method is always called before the setAverage method If setAverage is called first, it should return an error. I’m confused as to how t

Run a method before and after a called method in Java

I’m trying to write a Java program such that after calling a methodA(), first a method named methodBeforeA() is called and then methodA() gets executed followed by another method being called named, m

Check if a method was called inside another method

Is there any way in java to check if a certain method was called inside another method? I am testing a class and the method I am having trouble with plays sound and there is virtually no way of gettin

Call method before another

I have bunch of methods in which i need to test whether remote server has been reached or not and if not, reach it. My first idea was __call magic method, but the method is called only when real metho

How to make a method be called passive before invoke a method

Like so : a class has a method called sayHello() . When a instance of the class call the sayHello(), a method in another class is called automatic before the sayHello() is called. the sample code can

Get the name of the method that called another method

The goal Get the name of a method that called another method. The problem I need to get a method name in another method, and now I’m using this: $crazyDinosaur = new CrazyDinosaur(300, 600); $crazyDin

error method called before start element java sax processor

I am parsing an xml document using java sax parser and validating it against a schema. When validating for empty elements, the parser works fine if the the element is of the following format <submi

Does the viewdidload method get called before the view appear?

I’ve started learning IOS, I’m wondering does the viewdidload: method get called before the view appears on screen? The apple developer guide says this method gets called after the view is loaded into

iOS method called before scrollViewDidScroll on UITableView

I need to process scroll event on UITableView before it is processed in scrollViewDidScroll method. Is there any way to do that?

Is there a way in .NET to have a method called automatically after another method has been invoked but before it is entered

What I am looking for is a way to call a method after another method has been invoked but before it is entered. Example: public class Test { public void Tracer ( … ) { } public int SomeFunction( str

Answers

In general case you can offload values off the stack into temporary local variables. LocalVariableSorter adapter from ASM commons package makes it real easy. But in reality methods with more then 4 arguments is a rare case. Anyhow it is still much simpler and more solid then doing full blown dataflow analysis at runtime.

ASM’s org.objectweb.asm.tree.analysis provides facility for data flow analysis, e.g. you can use SourceInterpreter to track what instructions produced values on each variable and stack slots. See ASM User Guide for more details.

If I understand your question properly, I have achieved the same as what you are wanting to do but in a different way.

Using ASM event driven byte code modification, I first of all renamed someMethod( arg, arg, arg ) to copyOf_someMethod( arg, arg, arg ). Then I created a new method called someMethod( arg, arg, arg ) which did some processing and then called copyOf_someMethod( arg, arg, arg ).

I did the method renaming in the visitMethod(..) method of the ClassVisitor I implemented:

MethodVisitor methodVisitor =
    super.visitMethod(
        methodAccess, "copyOf_" + methodName, methodDesc,
            methodSignature, methodExceptions );

return methodVisitor;

In the visitMethod(..) I also stored all the method signature details in class variables ready to be used in the visitEnd() method.

I actually stored the method details in a MethodDetail object and placed it in a queue:

private Queue<MethodDetail> methodDetails = new LinkedList<MethodDetail>();

I created the new implementation of someMethod( arg, arg, arg ) using the visitEnd() method of the ClassVisitor I implemented. I used ASMFier to generate the code to put in the visitEnd() method. The implementation made use of the details I stored previouslyin the visitMethod(..). The new implementation did some processing and then called copyOf_someMethod(). In the visitEnd() method I popped all the MethodDetail of the queue and for each MethodDetail called ASM code that I had previously generated by ASMFier.

Using this design I had created a proxy for a method which did some processing and then called the original method. Note that the original method had been renamed to copyOf_someMethod(..). Note also that I provided a new implementation for the original method which acted as the proxy.

To support multiple arguments I used ASMFier to generate different code for 1 arg, 2 arg, 3 arg, e.t.c. I supported up to 7 arguments and throw a Unsupported Exception if the method being proxied had more than 7 arguments. In the visitEnd(..) method I called different code (that had been generated by ASMFier) depending on how many method arguments the original method had.

I used a javaagent to intercept the class loading and modify the bytes.

As I am new to ASM, maybe I did not understand your question properly – however if your question was about creating a proxy that does some processing and then calls the original method then my solution works. It did not seem to be slow. Class load up time for the class having its methods being proxied was not that much more slower than without byte code modification. The runtime speed of the introduced code was not slow, ASM code generated by ASMFier appears to be very fast.

Cheers

Look into org.objectweb.asm.tree.analysis. The SourceIterpreter should give you the instructions which put a value onto the stack.