0

正如标题所说,我想用 Mono.Cecil 调用该方法,但我不知道该怎么做。

4

1 回答 1

1

如何注入方法调用Mono.Cecil

  1. 读取目标程序集。
  2. 找到注入方法调用所需的点。所需的点是方法体中的指令,其中包含堆栈上注入方法的所有参数。
  3. 找到注入的方法。
  4. 生成调用此方法的指令。
  5. 在所需点之后插入生成的指令(来自权利要求 2)。
  6. 重写目标程序集。

注入 Convert.ToSingle(string) 调用的代码示例:

目标方法

namespace YourTargetNamespace
{
    public class YourTargetClass
    {
        public Single YourTargetMethod()
        {
            var str = "1";
            return 0; //Convert.ToSingle(str);
        }
    }
}

在不同的程序集中注入代码和测试

    [Test]
    public void InjectConverToSingleTest()
    {
        InjectConverToSingle();

        var engine = new YourTargetClass();
        Assert.That(engine.YourTargetMethod(), Is.EqualTo(1.0f));
    }

    public void InjectConverToSingle()
    {
        const string assemblyName = "YourTargetAssembly.dll";
        var assemble = AssemblyDefinition.ReadAssembly(assemblyName);
        var type = assemble.MainModule.GetType("YourTargetNamespace.YourTargetClass");
        var method = type.Methods.First(m => m.Name == "YourTargetMethod");
        var il = method.Body.GetILProcessor();
        var requiredPoint = method.Body.Instructions
            .First(instruction => instruction.OpCode.Code == Code.Ldstr &&
                                  (string)instruction.Operand == "1");

        var convertInstruction = CreateConvertInstruction(assemble.MainModule);
        il.InsertAfter(requiredPoint, convertInstruction);
        il.InsertAfter(convertInstruction, Instruction.Create(OpCodes.Ret));
        assemble.Write(assemblyName);
    }

    public Instruction CreateConvertInstruction(ModuleDefinition module)
    {
        var typeConvert = module.Import(typeof(Convert));
        var methodToSingle = typeConvert.Resolve()
            .Methods.First(method => method.Name == "ToSingle" &&
                                     method.Parameters.Count == 1 &&
                                     method.Parameters[0].ParameterType.FullName == module.TypeSystem.String.FullName);
        var importedMethodToSingle = module.Import(methodToSingle);

        return Instruction.Create(OpCodes.Call, importedMethodToSingle);
    }
于 2013-09-23T11:06:45.813 回答