Search code examples
.net.net-2.0code-injectionclr-profiling-api

Code injection does not work with MSCorLib in .Net 2.x


In our .Net application, we want to keep track of a file that is getting opened through .Net Code. Any file that is getting opened, execution call always pass through an internal instance method FileStrem.Init(...) which available in mscorlib.

To inject our monitoring code into any .Net method, we have built a framework in C++ using ICorProfiler APIs provided by Microsoft. All it does is that on module load finished, read the existing IL from target method from the loaded module, build custom code using IL and inject it into the target method.

This framework works fine. We are able to inject our monitoring code into many methods including FileStream.Init(...) method in mscorlib for .Net 4.x. But the same injected code does not get invoked in .Net 2.x.

We are able to inject our code into any .Net DLL except mscorlib for .Net 2.x. Code is getting injected properly, but not getting invoked. I have verified the IL of FileStream.Init(...) after injecting the code; I can see my code is present. But, not sure why it is not getting invoked. However the same code works file with FileStream.Init(...) for .Net 4.x.

Here is the sample C++ code to inject through IL -

// Read existing IL
ModuleID modId = 0x2030202; // module id of mscorlib
mdToken tkMethodId = 0x2492333; // Method token for FileStream.Init(...)
LPCBYTE methodBodyIL;
pICorProfilerInfo->GetILFunctionBody(modId, tkMethodId, &methodBodyIL, NULL)

// build monitoring IL and inject it into the bytes read from FileStream.Init
InjectCode(&methodBodyIL)

// Update the injected method back to mscorlib in memory
pICorProfilerInfo->SetILFunctionBody(modId, tkMethodId, methodBodyIL)

Any idea why it is not working in mscorlib for .Net 2.x?


Solution

  • You cant replace the body of a method if its covered by an ngen-ed image (mscorlib is normally ngen-ed). You might be using the COR_PRF_DISABLE_ALL_NGEN_IMAGES flag to disable ngen images, but that flag wasn't introduced until .NET 4 and so won't work for .NET 2.

    In the .NET 2 days the common solution was to use COR_PRF_USE_PROFILE_IMAGES and hope the machine didn't have any ngen images generated with profiling support enabled.