Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否可以在运行中修补dotnet函数_C#_.net_.net Assembly_Reverse Engineering - Fatal编程技术网

C# 是否可以在运行中修补dotnet函数

C# 是否可以在运行中修补dotnet函数,c#,.net,.net-assembly,reverse-engineering,C#,.net,.net Assembly,Reverse Engineering,最近我发现一个经常使用.net程序的架构师错误地实现了一个函数。因此,我成功地使用ILSpy和Reflexil以静态方式修改二进制文件来修补它。然而,令人恼火的是,当新的次要版本发布时,您需要对其进行修补并再次删除StrongNameCheck。(顺便说一句,作者认为这是一个特性而不是一个bug) 希望该程序完全支持将程序集作为插件。我的目标是公共类中的一个公共非静态成员函数,它可以被插件直接调用。是否有一种方法可以动态地修补功能 我通常在非托管C++中使用一些APIHOK技巧,但DOTNET确

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

希望该程序完全支持将程序集作为插件。我的目标是公共类中的一个公共非静态成员函数,它可以被插件直接调用。是否有一种方法可以动态地修补功能


我通常在非托管C++中使用一些APIHOK技巧,但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

不要伪造补丁代码。将该功能添加到代码库并调用该函数。或者编写一个封装底层程序集的适配器类,这要整洁得多


如果代码的作者认为它不是一个bug,那么它可能是因为您不理解的原因而存在的,并且可能是许多bug修复的一部分。

我从未使用过这个,但是。。。请参阅第1章了解包装的适配器类。总的来说,这篇文章是对的!非常感谢。在非常特定的情况下,这实际上是性能下降。修补程序涉及某些算法中的替换。但我同意这是真的,修补代码可能会导致未知的错误。谢谢。您已经提出了一种自动修改二进制文件的方法,我认为它还可以(因为我对Mono.Cecil真的不太了解)。