Advertisement
LaPanthere

CecilImporter

Jan 31st, 2014
511
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.29 KB | None | 0 0
  1. using Mono.Cecil;
  2. using Mono.Cecil.Cil;
  3. using System;
  4. using System.Runtime.CompilerServices;
  5. using Mono.Collections.Generic;
  6.  
  7. namespace Tutorial4Code
  8. {
  9.     public class CecilImporter
  10.     {
  11.         public delegate TResult Func<TIn, TResult>(TIn param);
  12.         public CecilImporter(ModuleDefinition targetModule)
  13.         {
  14.             this.TargetModule = targetModule;
  15.         }
  16.  
  17.         public FieldDefinition CreateImportedField(TypeDefinition declaringType, FieldDefinition targetField)
  18.         {
  19.             FieldDefinition definition = new FieldDefinition(targetField.Name, targetField.Attributes, this.ImportTypeReference(declaringType, targetField.FieldType));
  20.             if (definition.HasConstant)
  21.             {
  22.                 definition.Constant = targetField.Constant;
  23.             }
  24.             return definition;
  25.         }
  26.  
  27.         public MethodDefinition CreateImportedMethod(TypeDefinition declaringType, MethodDefinition targetMethod)
  28.         {
  29.             MethodDefinition definition = new MethodDefinition(targetMethod.Name, targetMethod.Attributes, this.ImportTypeReference(declaringType, targetMethod.ReturnType));
  30.             if (targetMethod.HasParameters)
  31.             {
  32.                 foreach (ParameterDefinition definition2 in targetMethod.Parameters)
  33.                 {
  34.                     ParameterDefinition item = new ParameterDefinition(definition2.Name, definition2.Attributes, this.ImportTypeReference(declaringType, definition2.ParameterType));
  35.                     definition.Parameters.Add(item);
  36.                 }
  37.             }
  38.             return definition;
  39.         }
  40.  
  41.         public MethodBody CreateImportedMethodBody(TypeDefinition declaringType, MethodDefinition newMethod, MethodBody originalBody)
  42.         {
  43.             MethodBody body = new MethodBody(newMethod);
  44.             ILProcessor iLProcessor = body.GetILProcessor();
  45.             if (originalBody.HasVariables)
  46.             {
  47.                 foreach (VariableDefinition definition in originalBody.Variables)
  48.                 {
  49.                     body.Variables.Add(new VariableDefinition(this.ImportTypeReference(declaringType, definition.VariableType)));
  50.                 }
  51.             }
  52.             for (int i = 0; i < originalBody.Instructions.Count; i++)
  53.             {
  54.                 Instruction instruction = originalBody.Instructions[i];
  55.                 object operand = instruction.Operand;
  56.                 if (operand != null)
  57.                 {
  58.                     if (operand is TypeReference)
  59.                     {
  60.                         iLProcessor.Emit(instruction.OpCode, this.ImportTypeReference(declaringType, operand as TypeReference));
  61.                     }
  62.                     else if (operand is MethodReference)
  63.                     {
  64.                         iLProcessor.Emit(instruction.OpCode, this.ImportMethodReference(declaringType, operand as MethodReference));
  65.                     }
  66.                     else if (operand is FieldReference)
  67.                     {
  68.                         iLProcessor.Emit(instruction.OpCode, this.ImportFieldReference(declaringType, operand as FieldReference));
  69.                     }
  70.                     else
  71.                     {
  72.                         iLProcessor.Append(instruction);
  73.                     }
  74.                 }
  75.                 else
  76.                 {
  77.                     iLProcessor.Append(instruction);
  78.                 }
  79.             }
  80.             if (originalBody.HasExceptionHandlers)
  81.             {
  82.                 foreach (ExceptionHandler handler in originalBody.ExceptionHandlers)
  83.                 {
  84.                     ExceptionHandler item = new ExceptionHandler(handler.HandlerType)
  85.                     {
  86.                         TryStart = this.GetInstructionByOffset(body, handler.TryStart.Offset),
  87.                         TryEnd = this.GetInstructionByOffset(body, handler.TryEnd.Offset),
  88.                         HandlerStart = this.GetInstructionByOffset(body, handler.HandlerStart.Offset),
  89.                         HandlerEnd = this.GetInstructionByOffset(body, handler.HandlerEnd.Offset)
  90.                     };
  91.                     if (item.FilterStart != null)
  92.                     {
  93.                         item.FilterStart = this.GetInstructionByOffset(body, handler.FilterStart.Offset);
  94.                     }
  95.                     if (handler.CatchType != null)
  96.                     {
  97.                         item.CatchType = this.ImportTypeReference(declaringType, handler.CatchType);
  98.                     }
  99.                     body.ExceptionHandlers.Add(item);
  100.                 }
  101.             }
  102.             return body;
  103.         }
  104.  
  105.         public TypeDefinition CreateImportedType(TypeDefinition targetType, string ns = "")
  106.         {
  107.             TypeDefinition declaringType = null;
  108.             if (ns == "")
  109.             {
  110.                 declaringType = new TypeDefinition(targetType.Namespace, targetType.Name, targetType.Attributes);
  111.             }
  112.             else
  113.             {
  114.                 declaringType = new TypeDefinition(ns, targetType.Name, targetType.Attributes);
  115.             }
  116.  
  117.             if (targetType.HasFields)
  118.             {
  119.                 foreach (FieldDefinition definition2 in targetType.Fields)
  120.                 {
  121.                     declaringType.Fields.Add(this.CreateImportedField(declaringType, definition2));
  122.                 }
  123.             }
  124.             if (targetType.HasMethods)
  125.             {
  126.                 foreach (MethodDefinition definition3 in targetType.Methods)
  127.                 {
  128.                     declaringType.Methods.Add(this.CreateImportedMethod(declaringType, definition3));
  129.                 }
  130.                 for (int i = 0; i < declaringType.Methods.Count; i++)
  131.                 {
  132.                     if (targetType.Methods[i].HasBody)
  133.                     {
  134.                         declaringType.Methods[i].Body = this.CreateImportedMethodBody(declaringType, declaringType.Methods[i], targetType.Methods[i].Body);
  135.                     }
  136.                 }
  137.             }
  138.             if (targetType.BaseType != null)
  139.             {
  140.                 declaringType.BaseType = this.ImportTypeReference(declaringType, targetType.BaseType);
  141.             }
  142.             if (targetType.HasInterfaces)
  143.             {
  144.                 foreach (TypeReference reference in targetType.Interfaces)
  145.                 {
  146.                     declaringType.Interfaces.Add(this.ImportTypeReference(declaringType, reference));
  147.                 }
  148.             }
  149.             return declaringType;
  150.         }
  151.  
  152.         private Instruction GetInstructionByOffset(MethodBody body, int offset)
  153.         {
  154.             return Extensions.FirstOrDefault<Instruction>(body.Instructions, i => i.Offset == offset);
  155.         }
  156.  
  157.         private FieldReference ImportFieldReference(TypeDefinition declaringType, FieldReference targetFieldRef)
  158.         {
  159.             Func<FieldDefinition, bool> condition = null;
  160.             if (declaringType.HasFields)
  161.             {
  162.                 if (condition == null)
  163.                 {
  164.                     condition = f => f.Name == targetFieldRef.Name;
  165.                 }
  166.                 FieldDefinition definition = Extensions.FirstOrDefault<FieldDefinition>(declaringType.Fields, condition);
  167.                 if (definition != null)
  168.                 {
  169.                     return definition;
  170.                 }
  171.             }
  172.             return this.TargetModule.Import(targetFieldRef);
  173.         }
  174.  
  175.         private MethodReference ImportMethodReference(TypeDefinition declaringType, MethodReference targetMethodRef)
  176.         {
  177.             Func<MethodDefinition, bool> condition = null;
  178.             if (declaringType.HasMethods)
  179.             {
  180.                 if (condition == null)
  181.                 {
  182.                     condition = m => m.Name == targetMethodRef.Name;
  183.                 }
  184.                 MethodDefinition definition = Extensions.FirstOrDefault<MethodDefinition>(declaringType.Methods, condition);
  185.                 if (definition != null)
  186.                 {
  187.                     return definition;
  188.                 }
  189.             }
  190.             return this.TargetModule.Import(targetMethodRef);
  191.         }
  192.  
  193.         private TypeReference ImportTypeReference(TypeDefinition declaringType, TypeReference targetTypeRef)
  194.         {
  195.             if (declaringType.FullName == targetTypeRef.FullName)
  196.             {
  197.                 return declaringType;
  198.             }
  199.             return this.TargetModule.Import(targetTypeRef);
  200.         }
  201.  
  202.         public string Author
  203.         {
  204.             get
  205.             {
  206.                 return "TheUnkownProgrammer:theunknownprogrammer@hotmail.com";
  207.             }
  208.         }
  209.  
  210.         public string Description
  211.         {
  212.             get
  213.             {
  214.                 return " A trimmed version of CecilImporter. Full version is used in my obfuscator which is private.";
  215.             }
  216.         }
  217.  
  218.         public ModuleDefinition TargetModule { get; private set; }
  219.     }
  220.  
  221.     public static class Extensions
  222.     {
  223.         public static T FirstOrDefault<T>(Collection<T> array, CecilImporter.Func<T, bool> condition)
  224.         {
  225.             foreach (T local in array)
  226.             {
  227.                 if (condition(local))
  228.                 {
  229.                     return local;
  230.                 }
  231.             }
  232.             return default(T);
  233.         }
  234.     }
  235. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement