Search code examples
c#cilmono.cecil

Inject method using Mono.Cecil?


I want to inject one method using Mono.Cecil.

My code is like this:

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

I want to replace the code like:

return getCpu();

So i write :

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);
}

But it didn't work.

I'm confused with IL. Someone can help me? Many thanks.


Solution

  • It's depend on the original method but maybe you need to add:

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

    Also, check that injectMethod is a valid method reference.

    Now, to inject the method, this should work:

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

    Note, that you emit call and not callvirt, is this on purpose? Because if injectMethod is not a static method, in most cases you need to emit callvirt.