Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using Mono.Cecil;
- using Mono.Cecil.Cil;
- class MethodProcessor {
- readonly MethodBody body;
- readonly MethodDefinition method;
- readonly ModuleDefinition module;
- ILProcessor il;
- VariableDefinition reflection_parameters;
- public MethodProcessor (MethodDefinition method)
- {
- this.method = method;
- this.body = method.Body;
- this.module = method.Module;
- }
- ILProcessor GetILProcessor ()
- {
- if (il != null)
- return il;
- return il = body.GetILProcessor ();
- }
- VariableDefinition GetReflectionParameters ()
- {
- if (reflection_parameters != null)
- return reflection_parameters;
- reflection_parameters = new VariableDefinition (module.Import (typeof (System.Reflection.ParameterInfo [])));
- body.Variables.Add (reflection_parameters);
- body.InitLocals = true;
- var il = GetILProcessor ();
- var instructions = new [] {
- il.Create (OpCodes.Ldtoken, method),
- il.Create (OpCodes.Call, ImportGetMethodFromHandle ()),
- il.Create (OpCodes.Callvirt, module.Import (typeof (System.Reflection.MethodBase).GetMethod ("GetParameters"))),
- il.Create (OpCodes.Stloc, reflection_parameters),
- };
- il.InsertBefore (body.Instructions [0], instructions);
- return reflection_parameters;
- }
- MethodReference ImportGetMethodFromHandle ()
- {
- return module.Import (typeof (System.Reflection.MethodBase).GetMethod ("GetMethodFromHandle", new [] { typeof (RuntimeMethodHandle) }));
- }
- MethodReference ImportGetFieldFromHandle ()
- {
- return module.Import (typeof (System.Reflection.FieldInfo).GetMethod ("GetFieldFromHandle", new [] { typeof (RuntimeFieldHandle) }));
- }
- TypeReference ImportMethodInfo ()
- {
- return method.Module.Import (typeof (System.Reflection.MethodInfo));
- }
- public void Run ()
- {
- foreach (var instruction in body.Instructions.ToArray ()) {
- MethodReference reference;
- if (!IsMethodCall (instruction, out reference))
- continue;
- if (!IsOfMethod (reference))
- continue;
- switch (reference.DeclaringType.Name) {
- case "Parameter":
- ProcessParameter (instruction);
- break;
- case "Property":
- ProcessProperty (instruction);
- break;
- case "Method":
- ProcessMethod (instruction);
- break;
- case "Field":
- ProcessField (instruction);
- break;
- case "Event":
- ProcessEvent (instruction);
- break;
- }
- }
- }
- static bool IsOfMethod (MethodReference reference)
- {
- return reference.Name == "Of";
- }
- static bool IsMethodCall (Instruction instruction, out MethodReference reference)
- {
- reference = null;
- if (instruction.OpCode.FlowControl != FlowControl.Call)
- return false;
- reference = instruction.Operand as MethodReference;
- return reference != null;
- }
- void ProcessParameter (Instruction instruction)
- {
- var load_arg = instruction.Previous;
- var il = GetILProcessor ();
- var instructions = new [] {
- il.Create (OpCodes.Ldloc, GetReflectionParameters ()),
- il.Create (OpCodes.Ldc_I4, GetParameter (load_arg, method).Index),
- il.Create (OpCodes.Ldelem_Ref),
- };
- il.InsertBefore (load_arg, instructions);
- il.Remove (load_arg);
- il.Remove (instruction);
- }
- static ParameterDefinition GetParameter (Instruction instruction, MethodDefinition method)
- {
- int index;
- switch (instruction.OpCode.Code) {
- case Code.Ldarg:
- return (ParameterDefinition) instruction.Operand;
- case Code.Ldarg_0:
- case Code.Ldarg_S:
- index = 0;
- break;
- case Code.Ldarg_1:
- index = 1;
- break;
- case Code.Ldarg_2:
- index = 2;
- break;
- default:
- throw new NotSupportedException ();
- }
- if (method.HasThis)
- index--;
- return method.Parameters [index];
- }
- void ProcessProperty (Instruction instruction)
- {
- var call_get = instruction.Previous;
- var load_subject = call_get.Previous;
- var getter = (MethodReference) call_get.Operand;
- var call_property = (MethodReference) instruction.Operand;
- var il = GetILProcessor ();
- var instructions = new [] {
- il.Create (OpCodes.Ldtoken, getter),
- il.Create (OpCodes.Call, ImportGetMethodFromHandle ()),
- il.Create (OpCodes.Castclass, ImportMethodInfo ()),
- il.Create (OpCodes.Call, call_property.DeclaringType.Resolve ().Methods.First (m => m.Name == "Of" && m.Parameters.Count > 0 && m.Parameters [0].ParameterType.Name == "MethodInfo")),
- };
- il.InsertBefore (load_subject, instructions);
- il.Remove (load_subject);
- il.Remove (call_get);
- il.Remove (instruction);
- }
- void ProcessMethod (Instruction instruction)
- {
- var new_delegate = instruction.Previous;
- var ld_ftn = new_delegate.Previous;
- var ld_this = ld_ftn.Previous;
- var il = GetILProcessor ();
- var instructions = new [] {
- il.Create (OpCodes.Ldtoken, ld_ftn.Operand as MethodReference),
- il.Create (OpCodes.Call, ImportGetMethodFromHandle ()),
- il.Create (OpCodes.Castclass, ImportMethodInfo ()),
- };
- il.InsertBefore (ld_this, instructions);
- il.Remove (ld_this);
- il.Remove (ld_ftn);
- il.Remove (new_delegate);
- il.Remove (instruction);
- }
- void ProcessField (Instruction instruction)
- {
- var load_field = instruction.Previous;
- var load_this = IsStatic (load_field.OpCode) ? load_field.Previous : null;
- var il = GetILProcessor ();
- var instructions = new [] {
- il.Create (OpCodes.Ldtoken, load_field.Operand as FieldReference),
- il.Create (OpCodes.Call, ImportGetFieldFromHandle ()),
- };
- il.InsertBefore (load_this ?? load_field, instructions);
- if (load_this != null)
- il.Remove (load_this);
- il.Remove (load_field);
- il.Remove (instruction);
- }
- static bool IsStatic (OpCode code)
- {
- return code == OpCodes.Ldsfld;
- }
- void ProcessEvent (Instruction instruction)
- {
- var call_event = (MethodReference) instruction.Operand;
- var load_field = instruction.Previous;
- var load_this = IsStatic (load_field.OpCode) ? load_field.Previous : null;
- var il = GetILProcessor ();
- var instructions = new [] {
- il.Create (OpCodes.Ldtoken, load_field.Operand as FieldReference),
- il.Create (OpCodes.Call, ImportGetFieldFromHandle ()),
- il.Create (OpCodes.Call, call_event.DeclaringType.Resolve ().Methods.First (m => m.Name == "Of" && m.Parameters.Count > 0 && m.Parameters [0].ParameterType.Name == "FieldInfo")),
- };
- il.InsertBefore (load_this ?? load_field, instructions);
- if (load_this != null)
- il.Remove (load_this);
- il.Remove (load_field);
- il.Remove (instruction);
- }
- }
- static class ILProcessorRocks {
- public static void InsertBefore (this ILProcessor il, Instruction target, IEnumerable<Instruction> instructions)
- {
- foreach (var instruction in instructions)
- il.InsertBefore (target, instruction);
- }
- }
- class Program {
- static void Main (string [] args)
- {
- var module = ModuleDefinition.ReadModule (args [0]);
- foreach (var type in module.Types) {
- foreach (var method in type.Methods) {
- if (!method.HasBody)
- continue;
- var processor = new MethodProcessor (method);
- processor.Run ();
- }
- }
- module.Write (args [0]);
- }
- }
Add Comment
Please, Sign In to add comment