是否可以即时修补 dotnet 函数

Is it possible to patch a dotnet function on the fly

最近发现一个架构师常用的.net程序实现了一个功能错误。因此,我使用 ILSpy 和 Reflexil 以修改二进制文件的静态方式 成功地 修补了它 。但是,令人恼火的是,当新的次要版本发布时,您需要对其进行修补并再次删除 StrongNameCheck。 (顺便说一句,作者认为这是一个功能而不是错误)

希望该程序完全支持程序集作为插件。而我的目标是 a public in a public class 的非静态成员函数,可以被插件直接调用。有没有办法即时修补函数 ?

我通常在非托管 C++ 中使用一些 APIHook 技巧,但 dotnet 确实是另一回事。在这种情况下,我希望修改在我的程序集卸载后仍然有效(因此更类似于补丁,而不是挂钩)。

是的,您可以通过代码注入来做到这一点。但是您需要了解一些 MSIL。还有一个名为 Mono.Cecil 的库。

这是一个示例代码

        Console.WriteLine("> INJECTING INTO 12345.EXE..." + Environment.NewLine);
        AssemblyDefinition asm = AssemblyDefinition.ReadAssembly(@"C:\dummy.exe");
        var writeLineMethod = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });
        var writeLineRef = asm.MainModule.Import(writeLineMethod);
        var pStartMethod = typeof(Process).GetMethod("Start", new Type[] { typeof(string) });
        var pStartRef = asm.MainModule.Import(pStartMethod);

        foreach (var typeDef in asm.MainModule.Types)
        {
            foreach (var method in typeDef.Methods) 
            {
                //Let's push a string using the Ldstr Opcode to the stack
                method.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Ldstr, "INJECTED!"));

                //We add the call to the Console.WriteLine() method. It will read from the stack
                method.Body.Instructions.Insert(1, Instruction.Create(OpCodes.Call, writeLineRef));

                //We push the path of the executable you want to run to the stack
                method.Body.Instructions.Insert(2, Instruction.Create(OpCodes.Ldstr, @"calc.exe"));

                //Adding the call to the Process.Start() method, It will read from the stack
                method.Body.Instructions.Insert(3, Instruction.Create(OpCodes.Call, pStartRef));

                //Removing the value from stack with pop
                method.Body.Instructions.Insert(4, Instruction.Create(OpCodes.Pop));
            }
        }
        asm.Write("12345.exe"); //Now we just save the new assembly

不要修改补丁代码。将功能添加到您的代码库并调用该函数。或者写一个适配器class封装底层程序集,这样就简洁多了。

如果代码的作者认为它不是错误,那么它可能出于您不理解的原因而存在,并且可能是任意数量的错误修复的一部分。