2

I was wondering if it was possible to dynamically inject a function parameter at runtime. For e.g. I have a class with two overloaded methods say

Class C1
{
    public static void Func1(object o)
    {
    }

    public static void Func1()
    {
    }       
}

Class C2
{

    public void Func1()
    {
       C1.Func1();
    }
}

Now, is it possible to dynamically replace the call to Func1() with a call to the overloaded method C1.Func1(object o) passing in either 'this' or the type object as the parameter.

So, in affect when I call C1.Func1(), my code should call C1.Func1(this);

2
  • I am guessing he wants to intercept/shunt an already compiled piece of code to which he does not have source code access, but knows publics. Commented Feb 9, 2010 at 18:53
  • 1
    One way would be to decompile the exe to MSIL, make the changes and recompile it. Commented Feb 9, 2010 at 18:55

5 Answers 5

3

I am assuming that by "dynamic" you mean a post-compile time solution, but not necessarily at runtime. The latter would be more challenging but could be done. For the former it's rather easy if you know some IL. I note that C2.Func1 compiles to something like

.method public hidebysig instance void Func1() cil managed {
    call void SomeNamespace.C1::Func1() 
    ret 
}

which you can easily replace with

.method public hidebysig instance void Func1() cil managed {
    ldarg.0
    call void SomeNamespace.C1::Func1(object)
    ret 
}

This is because argument zero in an instance method is always the this reference for the current instance and we can push it on the stack with the instruction ldarg.0. Moreover, we simply replace the signature of the method that we are invoking from the parameterless method to the method accepting a single object as a parameter.

You can easily decompile to IL using ildasm and recompile using ilasm.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Jason, that certainly works, however could you explain a bit more about the other option that you suggested, i.e. at runtime, would that mean using the Profiler API as suggested by Am?
2

You can use an extension method:

public static class C1Extensions
{
    public static void Func1(this C1 o)
    {
        // ...
    }
}

public class C1
{
    public void Foo()
    {
       this.Func1();
    }
}

1 Comment

+1, was just about to post the same thing, however, still requires the "this" keyword to call it.
1

Several options:

  1. Decompile the binary to MSIL, do the changes manually and recompile it.
  2. User the .NET profiling API to inject code, here is an [article] discussing it.
  3. Similar issue code-injection-with-c

The code injection would be to intercept the function without the argument, and recall the function with an argument.

Comments

0

As your method is static there is no way of obtaining the calling object.

Your options are to either make your methods non static and create a C1 object, or, pass the C2 (this) object in as a parameter.

Comments

0

Have you thought about using extension methods to do this?

public static class C1WrappingExtensions {
    public static void Func1(this object instance) {
        C1.Func(instance);
    }
}

// Now you can just call Func1() on any object...
var me = new Whatever();
me.Func1();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.