2017-03-16 86 views
0

我寫一個程序,可以改變目標程序的IL記錄方法的進入和退出點。 我使用Mono.Cecil能 我想這個程序插入到目標方法的開始和結束日誌語句。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(字串[] args)。

回答

0

我認爲問題是,我們在調用實例方法不指定this

爲了解決這個問題,你有兩個選擇:

  • LogEntrystatic
  • 評價棧的裝入thiscall之前添加ldarg.0指令。

要驗證我說的是否正確並在將來診斷類似問題,可以在修改的程序集上運行Peverify。

+0

完成。謝謝@svick – Krishnan