正如标题所说,我想用 Mono.Cecil 调用该方法,但我不知道该怎么做。
问问题
441 次
1 回答
1
如何注入方法调用Mono.Cecil
:
- 读取目标程序集。
- 找到注入方法调用所需的点。所需的点是方法体中的指令,其中包含堆栈上注入方法的所有参数。
- 找到注入的方法。
- 生成调用此方法的指令。
- 在所需点之后插入生成的指令(来自权利要求 2)。
- 重写目标程序集。
注入 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 回答