简体   繁体   中英

Mono.Cecil: Log method's entry and exit point

I am writing a program that can change the IL of target program to log method's entry and exit point. I am using Mono.Cecil I want this program to insert log statements in the beginning and end of the target method.

I tried a basic program as sample.

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.***********");
    }
}

Source program.

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

When I run my source program to change the IL of target program, I am getting following error message.

System.InvalidProgramException: Common Language Runtime detected an invalid program. at CecilDemoTarget.Target.Run() at CecilDemoTarget.Program.Main(String[] args).

I believe the issue is that you're calling instance method without specifying this .

To fix this, you have two choices:

  • Make LogEntry static .
  • Load this on the evaluation stack by adding the ldarg.0 instruction before the call .

To verify that what I'm saying is correct and to diagnose similar issues in the future, you can run Peverify on the modified assembly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM