11

In C++ I would get the address of the function and overwrite the first few bytes to a jmp to my function, do some stuff, restore the original bytes, and call the original function.

Can I do something like this in C#?

Avery3R
  • 3,027
  • 4
  • 24
  • 34

3 Answers3

9

The .NET Profiler API is the closest "Microsoft-approved" way of intercepting methods at runtime. As already mentioned, this is somewhat difficult to implement and I am not aware of a library that makes this easy to implement using purely managed code.

While researching options for this myself a few months ago, I stumbled on CLR Method Injection, which is an article with source code explaining how to intercept methods at runtime. I considered using this myself, and even had the sample project working, but ultimately concluded that I needed more than method interception and would need a different solution. However, this approach directly answers your question.

Lastly, what I ended up doing was developing Afterthought as an open source alternative to PostSharp, which runs as a post-compile step and allows you to modify existing methods to call other code, or replace the method implementations altogether. I am working right now on a new fluid syntax, which I will include a sample of now to provide an example to help you see how this AOP approach would meet your needs:

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

In this case while amending an existing type with a Sum method I am introducing code before and after the method to measure the execution time. After running Afterthought against the original compiled class, the resulting Sum method would have calls to these lambda expressions (the C# compiler just turns them into static methods) before and after the method body. I could have just as easily called Implement and replaced the entire method implementation.

I hope one of these approaches meets your needs. In my case, I went the AOP route because I wanted to do more than interception, such as implementing interfaces, adding new methods/properties, etc. I also wanted something that would not introduce dependencies at runtime or concerns about stability or performance in the runtime environment--compile-time processing is just safer and easier to test.

Jamie Thomas
  • 1,513
  • 1
  • 10
  • 16
  • Would afterthought work if the function I'm hooking is in another assembly, that I dont have the sourcecode for? – Avery3R May 30 '11 at 05:09
  • Yes. Afterthought works a bit differently from PostSharp in that it allows you to create amendments (like above--a code description of your changes) in one assembly and target another assembly to apply the changes to. Take a look at the [Logging Example](https://github.com/vc3/Afterthought/tree/master/Examples/Logging). It describes the amendments in the Logging.Amender assembly, which are then applied to the Logging.UnitTest.Target assembly. This also has the benefit of allowing you to modify an assembly without establishing a reference to Afterthought itself--making it just a tool. – Jamie Thomas May 30 '11 at 11:45
  • Does Afterthought uses the .NET Profiler interception? I am looking for a tool that does that – orellabac Jul 29 '17 at 06:58
  • Afterthought looks very interesting, but is practically abandoned :(. – Zero3 Mar 15 '18 at 18:20
2

Do you want to hook at runtime or do you want to patch the binary?

To hook at runtime you can use the profiling api(relatively difficult): http://msdn.microsoft.com/en-us/magazine/cc188743.aspx

To hook at compiletime you can use an IL rewriter, such as PostSharp.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
  • I want to hook at runtime, but the profiling API looks like it's in C++, I want to hook a C# function from C# – Avery3R May 29 '11 at 19:01
  • Sounds problematic since you're manipulating the very jitter you need to compile your own C# code. Perhaps a managed wrapper and multiple app domains can help. But that sounds like more trouble than mixing native C/C++ with C#. – CodesInChaos May 29 '11 at 19:12
1

The technique you're looking for is called AOP - Aspect Oriented Programming. You can find several frameworks for C# if you goggle a little.

Update: You can find plenty of links and info in this question: Built-in AOP in C# - is it on the way?

Community
  • 1
  • 1
Dan Byström
  • 9,067
  • 5
  • 38
  • 68
  • I've googled and I cant find anything, can you point me in the right direction? – Avery3R May 29 '11 at 18:46
  • None of this looks like what I want, I'm looking for a way to intercept a function whenever it is called and run my own code, and the optionally run the original code – Avery3R May 29 '11 at 18:53
  • Yes, that's exactly what AOP is used for! – Dan Byström May 29 '11 at 18:55
  • That, of course, depends on the framework you use. In PostSharp, for example, you can do it like this: http://www.sharpcrafters.com/solutions/logging – Dan Byström May 29 '11 at 19:34