Deathmax

Untitled

May 28th, 2011
431
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.80 KB | None | 0 0
  1. using System;
  2. using Mono.Cecil;
  3. using Mono.Cecil.Cil;
  4.  
  5. namespace CustomFieldsInjection
  6. {
  7.     public partial class Injector
  8.     {
  9.         public static void MethodInjection(string assemblyFilename,
  10. string typeName, string methodName)
  11.         {
  12.             AssemblyDefinition assembly = AssemblyFactory.GetAssembly
  13. (assemblyFilename);
  14.             //      Compared to Reflection, Cecil doesn`t use a
  15. AppDomain here,
  16.             //      which also allows us to load incomplete or CAS-
  17. prohibited assemblies.
  18.  
  19.             //Load the debugger symbols file
  20. //            assembly.MainModule.LoadSymbols();
  21.  
  22.             //      Next we'd like to define our new Method. A method
  23. in Cecil consists of
  24.             //      the return type the signature and the body (code).
  25.  
  26.             //Get a TypeReference for the return Type
  27.             TypeReference returnTypeReference =
  28. assembly.MainModule.Import(typeof(void));
  29.  
  30.             //Define Method signature "public static void" methodName
  31.             MethodDefinition methodDefinition = new MethodDefinition(
  32.                 methodName, MethodAttributes.Public |
  33. MethodAttributes.Static,
  34.                 returnTypeReference);
  35.  
  36.             //      Now we got our method but it hasn`t got any code
  37. in it`s body.
  38.             //      The new method will write a message outputString
  39. to the Console.
  40.  
  41.             //Push string onto the stack
  42.             Instruction instruction1 =
  43. methodDefinition.Body.CilWorker.Create(OpCodes.Nop);
  44.  
  45.             //Push string onto the stack
  46.             Instruction instruction2 =
  47. methodDefinition.Body.CilWorker.Create(OpCodes.Ldstr, methodName);
  48.  
  49.             //Import external method reference to Console.WriteLine()
  50.             MethodReference writeline = assembly.MainModule.Import(
  51.                 typeof(Console).GetMethod("WriteLine", new Type[]
  52. { typeof(string) }));
  53.  
  54.             //      We need to generate the defined code and append it
  55. to our new method Body
  56.  
  57.             //Generate stack-push
  58.             methodDefinition.Body.CilWorker.Append(instruction1);
  59.             methodDefinition.Body.CilWorker.Append(instruction2);
  60.  
  61.             //Generate call to WriteLine()
  62.             methodDefinition.Body.CilWorker.InsertAfter(
  63.                 instruction2, methodDefinition.Body.CilWorker.Create
  64. (OpCodes.Call, writeline));
  65.  
  66.             //Generate return
  67.             methodDefinition.Body.CilWorker.Append
  68. (methodDefinition.Body.CilWorker.Create(OpCodes.Ret));
  69.  
  70.             //      That done, we need to inject the generated Method
  71. into the assembly
  72.  
  73.             assembly.MainModule.Inject(methodDefinition,
  74. assembly.MainModule.Types[typeName]);
  75.  
  76.             //      At last we need to modify Main to call our new
  77. Method
  78.  
  79.             //Get Method reference with name like methodName,
  80.             MethodReference methodReference = null;
  81.  
  82.             //Get all the methods of typeName
  83.             foreach (MethodDefinition method in
  84. assembly.MainModule.Types[typeName].Methods)
  85.             {
  86.                 if (method.Name == methodName)
  87.                 {
  88.                     methodReference = assembly.MainModule.Import
  89. (method);
  90.                     break;
  91.                 }
  92.             }
  93.  
  94.             //Create call to the reference
  95.             Instruction callTest =
  96. methodDefinition.Body.CilWorker.Create(OpCodes.Call, methodReference);
  97.  
  98.             if (assembly.EntryPoint != null)
  99.             {
  100.                 //Insert reference
  101.                 assembly.EntryPoint.Body.CilWorker.InsertBefore
  102. (assembly.EntryPoint.Body.Instructions[0], callTest);
  103.             }
  104.  
  105.             //Save the debugger symbols file
  106. //            assembly.MainModule.SaveSymbols();
  107.  
  108.             //Save the patched assembly back to disk
  109.             AssemblyFactory.SaveAssembly(assembly, assemblyFilename);
  110.         }
  111.     }
  112. }
Advertisement
Add Comment
Please, Sign In to add comment