Advertisement
LaPanthere

Tutorial 3: Creating Types, Methods and Instructions

Jan 31st, 2014
273
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.22 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Mono.Cecil;
  6. using Mono.Cecil.Cil;
  7. using Mono.Collections.Generic;
  8.  
  9. namespace Tutorial3Code
  10. {
  11.     class Program
  12.     {
  13.         static void Main(string[] args)
  14.         {
  15.             // Loads the assembly from the start arguments
  16.             AssemblyDefinition asm = AssemblyDefinition.ReadAssembly(args[0]);
  17.  
  18.             // Iterates through the assembly's modules, aspects of the program
  19.             foreach (ModuleDefinition mod in asm.Modules)
  20.             {
  21.                 // Insert a random typedefinition that we've made
  22.                 mod.Types.Add(createType());
  23.  
  24.                 // Create the new method and store it as a variable
  25.                 MethodDefinition newMtd = createMethod(mod);
  26.  
  27.                 // Lets add the new method to the module entrypoint declaring type
  28.                 mod.EntryPoint.DeclaringType.Methods.Add(newMtd);
  29.  
  30.                 // Iterate through the entrypoint's instruction
  31.                 for (int i = 0; i < mod.EntryPoint.Body.Instructions.Count; i++)
  32.                 {
  33.                     // Assign an instruction to the current iteration
  34.                     Instruction inst = mod.EntryPoint.Body.Instructions[i];
  35.  
  36.                     // The opcode Ret (return) symbolizes the end of a method in most cases, sometimes its used to return a value in a function as a way of escaping the method
  37.                     if (inst.OpCode == OpCodes.Ret)
  38.                     {
  39.                         // Assign the ILProcessor, which is a handy tool for instruction manipulation
  40.                         ILProcessor ilp = mod.EntryPoint.Body.GetILProcessor();
  41.                        
  42.                         // Insert an instruction before the end of the method which calls our special method
  43.                         ilp.InsertBefore(inst, Instruction.Create(OpCodes.Call, newMtd));
  44.  
  45.                         // We don't need to iterate through the instructions anymore
  46.                         break;
  47.                     }
  48.                 }
  49.             }
  50.            
  51.             // Write the file to disk
  52.             asm.Write(@"C:\Tut\messageboxInjection.exe");
  53.         }
  54.  
  55.         static MethodDefinition createMethod(ModuleDefinition mod)
  56.         {
  57.             // Defines a new method, it isn't added to anything yet so no one knows it exists. It has a type of void and is static and public.
  58.             MethodDefinition newMethod = new MethodDefinition("Test", MethodAttributes.Private | MethodAttributes.Static, mod.Import(typeof(void)));
  59.  
  60.             // Defines a new Collection of Instructions, we use collections over lists because it is recommended and Mono.Cecil.Collections.Generic is there for use!
  61.             Collection<Instruction> newInsts = new Collection<Instruction>();
  62.  
  63.             // Add a ldstr to the stack
  64.             newInsts.Add(Instruction.Create(OpCodes.Ldstr, "Hello There!"));
  65.  
  66.             // Call the writeline method of Console, output will be as following, "Console.WriteLine("Hello There");"
  67.             newInsts.Add(Instruction.Create(OpCodes.Call, mod.Import(typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String) }))));
  68.  
  69.             // Because our program didn't have a "ReadLine()" at the end it didn't hold its place, lets add one so we can read what it says
  70.             newInsts.Add(Instruction.Create(OpCodes.Call, mod.Import(typeof(Console).GetMethod("ReadLine", Type.EmptyTypes))));
  71.  
  72.             // Pops the stack because the method return type is a void
  73.             newInsts.Add(Instruction.Create(OpCodes.Pop));
  74.  
  75.             // Returns nothing
  76.             newInsts.Add(Instruction.Create(OpCodes.Ret));
  77.  
  78.  
  79.             foreach (Instruction inst in newInsts)
  80.             {
  81.                 // Add that array to the methods Instructions
  82.                 newMethod.Body.Instructions.Add(inst);
  83.             }
  84.  
  85.             return newMethod;
  86.         }
  87.  
  88.         static TypeDefinition createType()
  89.         {
  90.             TypeDefinition newType = new TypeDefinition("MyNamespace", "MyTypeName", TypeAttributes.Class);
  91.             return newType;
  92.         }
  93.  
  94.         static void Log(string text)
  95.         {
  96.             Console.WriteLine(text);
  97.         }
  98.     }
  99. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement