是否可以即时修补 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封装底层程序集,这样就简洁多了。
如果代码的作者认为它不是错误,那么它可能出于您不理解的原因而存在,并且可能是任意数量的错误修复的一部分。
最近发现一个架构师常用的.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封装底层程序集,这样就简洁多了。
如果代码的作者认为它不是错误,那么它可能出于您不理解的原因而存在,并且可能是任意数量的错误修复的一部分。