Announcements

Intercepting BCL method calls with CodeCop

Hi Folks! This week I want to show something that you might think impossible. Using CodeCop to intercept BCL method calls at runtime.

The reason why I say you might have this assumption is because if you heard me talking on .NETRocks!, I said that CodeCop does runtime IL rewriting thus cannot intercept methods on NGEN assemblies as these are ahead of time compiled to native code.

Well I didn’t mentioned it but actually there is a way to deal with this. It’s like that old saying, if Mohammed can’t go to the mountain, the mountain will go to Mohammed!“. Fortunately the CLR allows us to disable loading NGEN images and force JIT compilation on these assemblies.

This is actually very easy to achieve, let’s create a new Console Application (framework 4.0 or onwards) and quickly override the Path.GetTempPath() static method. I will be using the Fluent API instead of JSON for this, but you can chose whatever you prefer.

Install CodeCop nuget package by typing:
install-package codecop

Add the ZapDisable setting to your App.config file to force jitting to occur on NGEN assemblies.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
  </startup>
  <runtime>
    <ZapDisable enabled="1" />
  </runtime>
</configuration>

Finally paste this code inside Main to override our target method, making it return the string “bananas” instead of the machine’s %Temp% directory.

// Tell CodeCop to use the Fluent API instead of JSON
Cop.AsFluent();

// Get our target method via reflection
var getTempPathMethod = typeof (Path).GetMethods()[9];

// Override it using CodeCop's Override extension method
getTempPathMethod.Override(c =>
{
  return "bananas";
});

// Tell CodeCop to do its magic
Cop.Intercept();

// Call the target method, it will output "bananas"
Console.WriteLine(Path.GetTempPath());

Console.ReadKey();

And the end result:

output

Power at your fingertips! But that’s not all, as this is a live interception process you can keep changing the method for as long as you like. Let’s change the code to make it output the string “orages” after the string “bananas”.

// Tell CodeCop to use the Fluent API instead of JSON
Cop.AsFluent();

// Get our target method via reflection
var getTempPathMethod = typeof (Path).GetMethods()[9];

// Override it using CodeCop's Override extension method
getTempPathMethod.Override(c =>
{
  return "bananas";
});

// Tell CodeCop to do its magic
Cop.Intercept();

// Call the target method, it will output "bananas"
Console.WriteLine(Path.GetTempPath());

getTempPathMethod.Override(c =>
{
  return "oranges";
});

// Tell CodeCop to do its magic again
Cop.Intercept();

// Call the target method, it will output "oranges"
Console.WriteLine(Path.GetTempPath());

Console.ReadKey();

Here’s the output:

output2

Magically Delicious, right?

Well this was the candy I wanted to give you this week but before I leave I just want to tell you that if you want to know more about CodeCop make sure you subscribe to our 5-Day Free Email Course via the widget at our site.

For full product and API description you can visit the wiki page or use the YouTube channel for weekly video tutorials.

See you around!

Free Email Updates
Get the latest content first.
100% Privacy. No spam.

Liked it? Please Share.

Leave a Reply

Your email address will not be published. Required fields are marked *