Mono.Cecil:记录方法的进入和退出点

时间:2017-03-16 10:55:13

标签: c# .net mono.cecil

我正在编写一个程序,可以将目标程序的IL更改为log方法的进入和退出点。 我正在使用 Mono.Cecil 我希望这个程序在目标方法的开头和结尾插入日志语句。

我尝试了一个基本程序作为样本。

public class Target
{
    // My target method. 
    public void Run()
    {
        Console.WriteLine("Run method body");
    }

    // This is my log method, which i want to call in begining of Run() method. 
    public void LogEntry()
    {
        System.Console.WriteLine("******Entered in RUN method.***********");
    }
}

源程序。

public class Sample 
{
    private readonly string _targetFileName;
    private readonly ModuleDefinition _module;

    public ModuleDefinition TargetModule { get { return _module; } }

    public Sample(string targetFileName)
    {
        _targetFileName = targetFileName;

        // Read the module with default parameters
        _module = ModuleDefinition.ReadModule(_targetFileName);
    }

    public void Run()
    {

        // Retrive the target class. 
        var targetType = _module.Types.Single(t => t.Name == "Target");

        // Retrieve the target method.
        var runMethod = targetType.Methods.Single(m => m.Name == "Run");

        // Get a ILProcessor for the Run method
        var processor = runMethod.Body.GetILProcessor();

        // get log entry method ref to create instruction
        var logEntryMethodReference = targetType.Methods.Single(m => m.Name == "LogEntry");

        var newInstruction = processor.Create(OpCodes.Call, logEntryMethodReference);

        var firstInstruction = runMethod.Body.Instructions[0];

        processor.InsertBefore(firstInstruction, newInstruction);

        // Write the module with default parameters
        _module.Write(_targetFileName);
    }
}

当我运行源程序来更改目标程序的IL时, 我收到以下错误消息。

System.InvalidProgramException:公共语言运行时检测到无效程序。    在CecilDemoTarget.Target.Run()    在CecilDemoTarget.Program.Main(String [] args)。

1 个答案:

答案 0 :(得分:0)

我认为问题在于您正在调用实例方法而未指定this

要解决此问题,您有两种选择:

  • 制作LogEntry static
  • this之前添加ldarg.0指令,在评估堆栈上加载call

要验证我所说的内容是否正确并在将来诊断类似问题,您可以在修改后的程序集上运行Peverify。