private static void CreateDynamicMethods(Type type, MethodInfo handling) { MethodInfo[] _mets = type.GetMethods(); foreach (MethodInfo _met in _mets) { if (_met.DeclaringType == type) { VirtualProxyHooker.CreateDynamicMethod(_met, handling, VirtualProxyHooker.CreateDynamicType()); } } }
public static object Handle(object obj, string moduleid, int typeid, int methodid, object[] s) { if (VirtualProxyHooker.ProcessInvoke != null) { Module m = ResolveModule(moduleid); VirtualProxyInvoker invoke = new VirtualProxyInvoker(obj, m, _types[string.Format("{0}.{1}", moduleid, typeid)] , _methods[string.Format("{0}.{1}", moduleid, methodid)], s); VirtualProxyHooker.ProcessInvoke(invoke); return(invoke.ResultValue); } return(null); }
private static MethodInfo Create(MethodInfo method, MethodInfo handing) { lock (_looker) { MethodInfo mi; if (_mms.TryGetValue(method, out mi)) { return(mi); } TypeBuilder tb = VirtualProxyHooker.CreateDynamicType(); mi = VirtualProxyHooker.CreateDynamicMethod(method, handing, tb); _mms.Add(method, mi); return(mi); } }
static VirtualProxyHooker() { VirtualProxyHooker._methods = new Dictionary <string, MethodInfo>(); VirtualProxyHooker._types = new Dictionary <string, Type>(); VirtualProxyHooker._mms = new Dictionary <MethodInfo, MethodInfo>(); VirtualProxyHooker._modules = new Dictionary <string, Module>(); MethodInfo[] ms = typeof(VirtualProxyHooker).GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static); Func <Type, MethodInfo> mi = (type) => ms.First(i => { var s = i.GetParameters(); if (s.Length < 5) { return(false); } return(s[4].ParameterType == type); }); _onHandle = mi(typeof(object[])); VirtualProxyHooker.DynamicModule = VirtualProxyHooker.CreateDynamicModule(); }
private static MethodInfo CreateDynamicMethod(MethodInfo method, MethodInfo handling, TypeBuilder builder) { ParameterInfo[] s = method.GetParameters(); MethodBuilder proxy = builder.DefineMethod(builder.Name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, method.ReturnType, VirtualProxyHooker.GetDynamicParameterType(s)); proxy.SetCustomAttribute(new CustomAttributeBuilder(typeof(SecurityCriticalAttribute). GetConstructor(Type.EmptyTypes), new object[0])); proxy.SetCustomAttribute(new CustomAttributeBuilder(typeof(SecuritySafeCriticalAttribute). GetConstructor(Type.EmptyTypes), new object[0])); ILGenerator il = proxy.GetILGenerator(); il.DeclareLocal(typeof(object[])); il.DeclareLocal(typeof(object)); if (method.ReturnType != typeof(void)) { il.DeclareLocal(method.ReturnType); } il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ldc_I4, s.Length); il.Emit(OpCodes.Newarr, typeof(object)); il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Stloc_1); if (!method.IsStatic) { Label rva = il.DefineLabel(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Ceq); il.Emit(OpCodes.Brtrue, rva); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Stloc_1); il.MarkLabel(rva); } for (int o = -1, i = (method.IsStatic ? 0 : 1), n = (method.IsStatic ? s.Length - 1 : s.Length); i <= n; i++) { o = (i - 1); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ldc_I4, o); il.Emit(OpCodes.Ldarg, i); il.Emit(OpCodes.Box, s[o].ParameterType); il.Emit(OpCodes.Stelem_Ref); } string moduleid = method.Module.ModuleVersionId.ToString(); string typeid = string.Format("{0}.{1}", moduleid, method.DeclaringType.MetadataToken); string methodid = string.Format("{0}.{1}", moduleid, method.MetadataToken); il.Emit(OpCodes.Ldloc_1); il.Emit(OpCodes.Ldstr, moduleid); il.Emit(OpCodes.Ldc_I4, method.DeclaringType.MetadataToken); il.Emit(OpCodes.Ldc_I4, method.MetadataToken); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Call, handling); if (method.ReturnType == typeof(void)) { il.Emit(OpCodes.Pop); } else { il.Emit(OpCodes.Unbox_Any, method.ReturnType); il.Emit(OpCodes.Stloc_1); il.Emit(OpCodes.Ldloc_1); } il.Emit(OpCodes.Ret); if (!_modules.ContainsKey(moduleid)) { _modules.Add(moduleid, method.Module); } if (!_types.ContainsKey(typeid)) { _types.Add(typeid, method.DeclaringType); } if (!_methods.ContainsKey(methodid)) { _methods.Add(methodid, method); } return(builder.CreateType().GetMethod(builder.Name)); }
private void AddHook() { lock (this) { if (_properties == null) { _properties = new Dictionary <PropertyInfo, PropertyHookContext>(); Func <MethodInfo, MethodSource> addHook = (mi) => { if (mi == null || !mi.IsPublic) { return(null); } MethodSource source = MethodSource.From(mi); MethodInfo pointcut = VirtualProxyHooker.Create(mi); source.AddHook(pointcut); return(source); }; foreach (PropertyInfo property in this.DeclaringType.GetProperties()) { PropertyHookContext context = new PropertyHookContext(); context.PropertyInfo = property; context.GetMethodInfo = property.GetGetMethod(); context.SetMethodInfo = property.GetSetMethod(); MethodSource source = addHook(context.GetMethodInfo); context.GetMethodSource = source; source = addHook(context.SetMethodInfo); context.SetMethodSource = source; if (context.GetMethodSource != null) { _map.Add(context.GetMethodInfo, context); } if (context.SetMethodSource != null) { _map.Add(context.SetMethodInfo, context); } if (context.GetMethodSource != null || context.SetMethodSource != null) { _properties.Add(property, context); } } } else { Action <MethodSource> resume = (source) => { if (source != null) { source.Resume(); } }; foreach (PropertyHookContext context in _properties.Values) { resume(context.SetMethodSource); resume(context.GetMethodSource); } } } }