2010-02-09 36 views
2

我想知道是否可以在运行时动态注入函数参数。对于例如我有两个重载方法的类说向c中的函数调用动态注入参数#

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

    public static void Func1() 
    { 
    }  
} 

Class C2 
{ 

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

现在,是有可能与给重载方法C1.Func1(对象o)的呼叫动态地替换调用FUNC1()传递在任一“这个”或者类型对象作为参数。因此,在我调用C1.Func1()时,我的代码应该调用C1.Func1(this);

+0

我猜他想拦截/分流已经编译的代码片段,但他没有源代码访问权限,但知道公众。 – 2010-02-09 18:53:26

+1

一种方法是将exe反编译到MSIL,进行更改并重新编译它。 – Amirshk 2010-02-09 18:55:08

回答

3

我假设“动态”是指后编译时解决方案,但不一定在运行时。后者会更具挑战性,但可以完成。对于前者来说,如果你知道一些IL就相当容易。我注意到,C2.Func1编译成类似

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

,你可以轻松地与

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

更换。这是因为,参数零的实例方法始终是当前实例的this参考,我们可以推它在与指令ldarg.0的堆栈上。此外,我们只是简单地将我们所调用的方法的签名从无参数方法替换为接受单个object作为参数的方法。

您可以使用ildasm轻松地反编译为IL,并使用ilasm重新编译。

+0

谢谢杰森,这当然有用,但是你能否更详细地解释一下你提出的另一个选项,即在运行时,是否意味着使用Am建议的Profiler API? – ilias 2010-02-10 09:21:40

1

有几个选项:

  1. 反编译二进制MSIL,手工做的修改并重新编译。
  2. 用户.NET剖析API注入代码,这里是一个[文章]讨论它。
  3. 类似问题code-injection-with-c

的代码注入将是拦截功能,无需论证,并召回有一个参数的函数。

0

由于您的方法是静态的,因此无法获取调用对象。

你的选择是让你的方法非静态并创建一个C1对象,或者将C2(this)对象作为参数传入。

2

您可以使用扩展方法:

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

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

打我30秒... – 2010-02-09 19:05:12

+0

+1,即将发布相同的内容,但仍需要使用“this”关键字来调用它。 – 2010-02-09 19:05:32

0

你有没有想过使用扩展方法来做到这一点?

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();