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

   1 /*
   2 mcs samples.cs
   3 mono sample.exe
   4 */
   5 public class Acme{
   6     public int Add(int arg1,int arg2){
   7       return arg1 + arg2;  
   8     }
   9 }
  10 
  11 public class Sample{
  12     public static void Main(string []args){
  13       new Acme().Add(4,9);  
  14     }
  15 }

Program to rewrite the sample program

   1 /*
   2 mcs rewrite.cs /r:Mono.Cecil.dll
   3 mono rewrite.exe 
   4 */
   5 using Mono.Cecil;
   6 using Mono.Cecil.Cil;
   7 
   8 public class RewriteIL{
   9   public static void Main(string []args){
  10     AssemblyDefinition ad = AssemblyDefinition.ReadAssembly("sample.exe");
  11     
  12     foreach(TypeDefinition td in ad.MainModule.Types){
  13       
  14       foreach(MethodDefinition md  in td.Methods){
  15         
  16         if(md.Name=="Add"){
  17           System.Console.WriteLine(td+"."+md);
  18 
  19           System.Console.WriteLine("Original IL Code:");
  20           foreach(Instruction inst in md.Body.Instructions){
  21             System.Console.WriteLine(inst);
  22           }
  23 
  24           var il = md.Body.GetILProcessor();
  25           var format = il.Create(OpCodes.Ldstr,"Add( {0}, {1} )");
  26           var arg1 = il.Create (OpCodes.Ldarg_1);
  27           var arg2 = il.Create (OpCodes.Ldarg_2);
  28 
  29           TypeReference typeint32 = md.Module.Import(typeof(System.Int32) );
  30           var boxarg1 = il.Create (OpCodes.Box,typeint32);
  31           var boxarg2 = il.Create (OpCodes.Box,typeint32);
  32 
  33           MethodReference writelinemr = md.Module.Import( typeof(System.Console).GetMethod("WriteLine", new [] { typeof (string) }));
  34           MethodReference stringformatmr = md.Module.Import( typeof(System.String).GetMethod("Format", 
  35           new [] { typeof (string) , typeof(object),typeof(object) }));
  36 
  37           var callwriteline = il.Create(OpCodes.Call,writelinemr);
  38           var callstringformat = il.Create(OpCodes.Call,stringformatmr);
  39 
  40           // insert the IL code in reversed order, at top of the method.
  41           // "normal" order would be ldarg.2 call ldarg.1 call ...
  42           il.InsertBefore (md.Body.Instructions[0], callwriteline);
  43           il.InsertBefore (md.Body.Instructions[0], callstringformat);
  44           il.InsertBefore (md.Body.Instructions[0], boxarg2);      
  45           il.InsertBefore (md.Body.Instructions[0], arg2);
  46           il.InsertBefore (md.Body.Instructions[0], boxarg1);      
  47           il.InsertBefore (md.Body.Instructions[0], arg1);
  48           il.InsertBefore (md.Body.Instructions[0], format);
  49 
  50           System.Console.WriteLine("New IL Code:");
  51           foreach(Instruction inst in md.Body.Instructions) {
  52             System.Console.WriteLine(inst);
  53           }
  54 
  55         }
  56       }
  57       
  58     }
  59 
  60     ad.Write("sampleRewrite.exe");
  61   }
  62 }

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

CSharp/MonoCecil (last edited 2015-03-12 21:40:28 by 54)