代码注入不适用于 .Net 中的 MSCorLib 2.x

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

在我们的 .Net 应用程序中,我们想要跟踪通过 .Net 代码打开的文件。任何正在打开的文件,执行调用总是通过 mscorlib 中可用的内部实例方法 FileStrem.Init(...) 传递。

为了将我们的监控代码注入任何 .Net 方法,我们使用 Microsoft 提供的 ICorProfiler API 在 C++ 中构建了一个框架。它所做的只是在模块加载完成后,从加载模块的目标方法中读取现有 IL,使用 IL 构建自定义代码并将其注入目标方法。

这个框架工作正常。我们能够将我们的监控代码注入到许多方法中,包括 mscorlib for .Net 4.x 中的 FileStream.Init(...) 方法。但是相同的注入代码不会在 .Net 中被调用 2.x.

我们能够将代码注入任何 .Net DLL,除了 mscorlib for .Net 2.x。代码被正确注入,但没有被调用。我在注入代码后验证了 FileStream.Init(...) 的IL;我可以看到我的代码存在。但是,不确定为什么它没有被调用。然而,相同的代码适用于 FileStream.Init(...) for .Net 4.x 的文件。

这是通过 IL 注入的示例 C++ 代码 -

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

知道为什么它在 .Net 的 mscorlib 中不起作用 2.x?

如果方法的主体被 ngen-ed 图像覆盖,则不能替换它(mscorlib 通常是 ngen-ed)。您可能正在使用 COR_PRF_DISABLE_ALL_NGEN_IMAGES 标志来禁用 ngen 图像,但该标志直到 .NET 4 才引入,因此不适用于 .NET 2。

在 .NET 2 的日子里,常见的解决方案是使用 COR_PRF_USE_PROFILE_IMAGES 并希望机器没有在启用分析支持的情况下生成任何 ngen 图像。