代码之家  ›  专栏  ›  技术社区  ›  Keyu Gan

是否可以动态修补dotnet函数

  •  2
  • Keyu Gan  · 技术社区  · 8 年前

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

    希望该程序完全支持作为插件的程序集。我的目标是 公共类中的公共非静态成员函数 可以由插件直接调用。是否有方法修补功能 在飞行中 ?

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

    2 回复  |  直到 8 年前
        1
  •  4
  •   Mohsen Sarkar Alex    8 年前

    是的,你可以通过代码注入来实现。但你需要了解一些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
    
        2
  •  1
  •   Adam Carr    8 年前

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

    如果代码的作者认为这不是一个bug,那么它可能存在于您不理解的原因中,并且可能是任何数量的bug修复的一部分。