【问题标题】:Inject method using Mono.Cecil?使用 Mono.Cecil 注入方法?
【发布时间】:2017-04-12 22:34:24
【问题描述】:

我想使用 Mono.Cecil 注入一种方法。

我的代码是这样的:

var worker = method.Body.GetILProcessor();
method.Body.Instructions.Clear();//Clear Old code

我想替换如下代码:

return getCpu();

所以我写:

List<Instruction> listStep = new List<Instruction>();
//listStep.Add(worker.Create(OpCodes.Nop));
//listStep.Add(worker.Create(OpCodes.Ldarg_0));
listStep.Add(worker.Create(OpCodes.Call,injectMethod));
//listStep.Add(worker.Create(OpCodes.Stloc_0));
//listStep.Add(worker.Create(OpCodes.Ldloc_0));
//listStep.Add(worker.Create(OpCodes.Br_S));
//listStep.Add(worker.Create(OpCodes.Stloc_1));
//listStep.Add(worker.Create(OpCodes.Ldloc_1));
listStep.Add(worker.Create(OpCodes.Ret));

foreach (var item in listStep)
{
    worker.Append(item);
}

但是没有用。

我对 IL 感到困惑。有人可以帮助我吗?非常感谢。

【问题讨论】:

  • 到底是怎么回事?它有什么作用?您是否尝试过在修改后的程序集上运行 peverify?

标签: c# cil mono.cecil


【解决方案1】:

这取决于原始方法,但可能需要添加:

method.Body.Variables.Clear();
method.Body.ExceptionHandlers.Clear();

另外,检查injectMethod 是一个有效的方法引用。

现在,要注入方法,这应该可以工作:

worker.Emit(Opcodes.Call, injectMethod);
worker.Emit(Opcodes.Ret);

请注意,您发出的是call 而不是callvirt,这是故意的吗?因为如果injectMethod不是静态方法,in most cases你需要发出callvirt

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-19
    • 1970-01-01
    • 1970-01-01
    • 2012-09-27
    • 2011-05-21
    • 1970-01-01
    • 2011-12-27
    相关资源
    最近更新 更多