在 C++ 中,我会获取函数的地址并将前几个字节覆盖为我的函数的 jmp,做一些事情,恢复原始字节,然后调用原始函数。
我可以在 C# 中做这样的事情吗?
最佳答案
.NET Profiler API 是最接近“Microsoft 认可”的运行时拦截方法的方法。如前所述,这有点难以实现,而且我不知道有哪个库可以使用纯托管代码轻松实现这一点。
几个月前,当我自己研究这个选项时,我偶然发现了 CLR Method Injection ,这是一篇带有源代码的文章,解释了如何在运行时拦截方法。我考虑过自己使用它,甚至让示例项目运行起来,但最终得出结论,我需要的不仅仅是方法拦截,还需要一个不同的解决方案。但是,这种方法直接回答了您的问题。
最后,我最终做的是开发 Afterthought作为 PostSharp 的开源替代品,它作为编译后步骤运行,允许您修改现有方法以调用其他代码,或完全替换方法实现。我现在正在研究一种新的流畅语法,我将在其中包含一个示例,以提供一个示例来帮助您了解这种 AOP 方法如何满足您的需求:
Methods
.Named("Sum")
.WithParams<int[]>()
.Before((T instance, ref int[] values)
=> { var s = new Stopwatch(); s.Start(); return s; })
.After((instance, stopwatch, values)
=> instance.Result = (int)stopwatch.ElapsedMilliseconds);
在这种情况下,在使用 Sum
方法修改现有类型时,我在该方法前后引入了代码以测量执行时间。在对原始编译类运行 Afterthought 之后,生成的 Sum 方法将在方法主体前后调用这些 lambda 表达式(C# 编译器只是将它们转换为静态方法)。我可以很容易地调用 Implement
并替换整个方法实现。
我希望其中一种方法能满足您的需求。在我的例子中,我选择了 AOP 路线,因为我想做的不仅仅是拦截,例如实现接口(interface)、添加新方法/属性等。我还想要一些不会在运行时引入依赖性或不关心稳定性或性能的东西运行时环境——编译时处理更安全,更容易测试。
关于c# - 有没有办法在 C# 中 Hook 托管函数,就像在 C++ 中 Hook 非托管函数一样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6169552/