= Mono Cecil =
Cecil is a library written by Jb Evain to generate and inspect programs and libraries in the ECMA CIL format. It has full support for generics, and support some debugging symbol format.

http://www.mono-project.com/Cecil

http://www.mono-project.com/Cecil:FAQ

https://github.com/jbevain/cecil/wiki/Importing

Download Cecil assembly http://obfuscar.googlecode.com/svn-history/r83/trunk/ThirdParty/Mono/Mono.Cecil.dll

== IL Code rewriting ==
Sample program to change with Mono.Cecil
{{{#!highlight csharp
/*
mcs samples.cs
mono sample.exe
*/
public class Acme{
    public int Add(int arg1,int arg2){
      return arg1 + arg2;  
    }
}

public class Sample{
    public static void Main(string []args){
      new Acme().Add(4,9);  
    }
}
}}}

Program to rewrite the sample program
{{{#!highlight csharp

/*
mcs rewrite.cs /r:Mono.Cecil.dll
mono rewrite.exe 
*/
using Mono.Cecil;
using Mono.Cecil.Cil;

public class RewriteIL{
  public static void Main(string []args){
    AssemblyDefinition ad = AssemblyDefinition.ReadAssembly("sample.exe");
    
    foreach(TypeDefinition td in ad.MainModule.Types){
      
      foreach(MethodDefinition md  in td.Methods){
	
	if(md.Name=="Add"){
	  System.Console.WriteLine(td+"."+md);

          System.Console.WriteLine("Original IL Code:");
	  foreach(Instruction inst in md.Body.Instructions){
	    System.Console.WriteLine(inst);
	  }

          var il = md.Body.GetILProcessor();
          var format = il.Create(OpCodes.Ldstr,"Add( {0}, {1} )");
          var arg1 = il.Create (OpCodes.Ldarg_1);
          var arg2 = il.Create (OpCodes.Ldarg_2);

          TypeReference typeint32 = md.Module.Import(typeof(System.Int32) );
          var boxarg1 = il.Create (OpCodes.Box,typeint32);
          var boxarg2 = il.Create (OpCodes.Box,typeint32);

	  MethodReference writelinemr = md.Module.Import( typeof(System.Console).GetMethod("WriteLine", new [] { typeof (string) }));
	  MethodReference stringformatmr = md.Module.Import( typeof(System.String).GetMethod("Format", 
          new [] { typeof (string) , typeof(object),typeof(object) }));

          var callwriteline = il.Create(OpCodes.Call,writelinemr);
          var callstringformat = il.Create(OpCodes.Call,stringformatmr);

          // insert the IL code in reversed order, at top of the method.
          // "normal" order would be ldarg.2 call ldarg.1 call ...
          il.InsertBefore (md.Body.Instructions[0], callwriteline);
          il.InsertBefore (md.Body.Instructions[0], callstringformat);
	  il.InsertBefore (md.Body.Instructions[0], boxarg2);      
	  il.InsertBefore (md.Body.Instructions[0], arg2);
	  il.InsertBefore (md.Body.Instructions[0], boxarg1);      
	  il.InsertBefore (md.Body.Instructions[0], arg1);
	  il.InsertBefore (md.Body.Instructions[0], format);

          System.Console.WriteLine("New IL Code:");
	  foreach(Instruction inst in md.Body.Instructions) {
	    System.Console.WriteLine(inst);
	  }

	}
      }
      
    }

    ad.Write("sampleRewrite.exe");
  }
}
}}}

In the rewritten program the arguments for the Add method will appear on the console.