Метод Inject с использованием Mono.Cecil?

Я хочу ввести один метод, используя 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);
}

Но это не сработало.

Я путаюсь с ИЛ. Кто-нибудь может мне помочь? Большое спасибо.


person jeri neal    schedule 29.11.2016    source источник
comment
Как именно не получилось? Что оно делает? Вы пытались запустить peverify на модифицированной сборке?   -  person svick    schedule 29.11.2016


Ответы (1)


Это зависит от исходного метода, но, возможно, вам нужно добавить:

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

Также убедитесь, что injectMethod является действительной ссылкой на метод.

Теперь, чтобы внедрить метод, это должно работать:

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

Обратите внимание, что вы испускаете call, а не callvirt, это специально? Потому что, если injectMethod не является статическим методом, в большинстве случаев вам нужно испустить callvirt.

person Dudi Keleti    schedule 29.11.2016