예제 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MethodBodyRewriterParameters"/> class.
        /// </summary>
        /// <param name="IL">The CilWorker that is responsible for the current method body.</param>
        /// <param name="oldInstructions">The value indicating the list of old instructions in the current method body.</param>
        /// <param name="interceptionDisabled">The value that determines whether or not interception is disabled.</param>
        /// <param name="invocationInfo">The local variable that will store the <see cref="IInvocationInfo"/> instance.</param>
        /// <param name="returnValue">The value indicating the local variable that will store the return value.</param>
        /// <param name="methodReplacementProvider">The <see cref="IMethodReplacementProvider"/> instance.</param>
        /// <param name="aroundInvokeProvider">The <see cref="IAroundInvokeProvider"/> instance.</param>
        /// <param name="classMethodReplacementProvider">The class-level<see cref="IMethodReplacementProvider"/> instance.</param>
        /// <param name="getMethodReplacementProviderMethod">The functor that resolves the GetMethodReplacementProvider method.</param>
        /// <param name="registryType">The interception registry type that will be responsible for handling class-level interception events.</param>
        public MethodBodyRewriterParameters(CilWorker IL, IEnumerable <Instruction> oldInstructions,
                                            VariableDefinition interceptionDisabled,
                                            VariableDefinition invocationInfo,
                                            VariableDefinition returnValue,
                                            VariableDefinition methodReplacementProvider,
                                            VariableDefinition aroundInvokeProvider,
                                            VariableDefinition classMethodReplacementProvider,
                                            Func <ModuleDefinition, MethodReference> getMethodReplacementProviderMethod,
                                            Type registryType)
        {
            if (methodReplacementProvider.VariableType.FullName != typeof(IMethodReplacementProvider).FullName)
            {
                throw new ArgumentException("methodReplacementProvider");
            }

            if (aroundInvokeProvider.VariableType.FullName != typeof(IAroundInvokeProvider).FullName)
            {
                throw new ArgumentException("aroundInvokeProvider");
            }

            _cilWorker                          = IL;
            _oldInstructions                    = oldInstructions;
            _interceptionDisabled               = interceptionDisabled;
            _invocationInfo                     = invocationInfo;
            _returnValue                        = returnValue;
            _methodReplacementProvider          = methodReplacementProvider;
            _aroundInvokeProvider               = aroundInvokeProvider;
            _classMethodReplacementProvider     = classMethodReplacementProvider;
            _getMethodReplacementProviderMethod = getMethodReplacementProviderMethod;
            _registryType                       = registryType;
        }
예제 #2
0
 /// <summary>
 /// Emits the IL instructions to obtain an <see cref="IInterceptor"/> instance for the proxy type.
 /// </summary>
 /// <param name="IL">The <see cref="CilWorker"/> responsible for emitting the method body.</param>
 /// <param name="proxyType">The proxy type.</param>
 /// <param name="getInterceptorMethod">The getter method for the interceptor.</param>
 protected virtual void EmitGetInterceptorInstruction(CilWorker IL, TypeReference proxyType,
                                                      MethodReference getInterceptorMethod)
 {
     IL.Emit(OpCodes.Ldarg_0);
     IL.Emit(OpCodes.Isinst, proxyType);
     IL.Emit(OpCodes.Callvirt, getInterceptorMethod);
 }
예제 #3
0
        public void Emit(CilWorker IL)
        {
            var module         = IL.GetModule();
            var modifiableType = module.ImportType <IModifiableType>();
            var getInterceptionDisabledMethod = module.ImportMethod <IModifiableType>("get_IsInterceptionDisabled");

            if (!_hostMethod.HasThis)
            {
                IL.Emit(OpCodes.Ldc_I4_0);
                IL.Emit(OpCodes.Stloc, _interceptionDisabled);
                return;
            }

            var skipLabel = IL.Create(OpCodes.Nop);

            // var interceptionDisabled = this.IsInterceptionDisabled;
            IL.Emit(OpCodes.Ldarg_0);
            IL.Emit(OpCodes.Isinst, modifiableType);
            IL.Emit(OpCodes.Brfalse, skipLabel);

            IL.Emit(OpCodes.Ldarg_0);
            IL.Emit(OpCodes.Isinst, modifiableType);
            IL.Emit(OpCodes.Callvirt, getInterceptionDisabledMethod);
            IL.Emit(OpCodes.Stloc, _interceptionDisabled);

            IL.Append(skipLabel);
        }
예제 #4
0
        /// <summary>
        /// Rewrites a target method using the given CilWorker.
        /// </summary>
        /// <param name="method">The target method.</param>
        /// <param name="IL">The CilWorker that will be used to rewrite the target method.</param>
        /// <param name="oldInstructions">The original instructions from the target method body.</param>
        public void Rewrite(MethodDefinition method, CilWorker IL, IEnumerable <Instruction> oldInstructions)
        {
            if (!ShouldRewrite(method))
            {
                return;
            }

            var declaringType = method.DeclaringType;

            var body = IL.GetBody();

            body.InitLocals = true;

            var module = declaringType.Module;

            // Interfaces and Enums cannot be modified
            if (declaringType.IsInterface || declaringType.IsEnum)
            {
                return;
            }

            ImportReferences(module);

            AddLocals(method);

            if (!_modifiedTypes.Contains(declaringType))
            {
                AddAdditionalMembers(declaringType);
                _modifiedTypes.Add(declaringType);
            }

            RewriteMethodBody(method, IL, oldInstructions);
        }
        private static TypeDefinition GetFactoryMapType(IAssembly assembly)
        {
            foreach (TypeDefinition type in assembly.Types)
            {
                if (type.FullName == FactoryMapTypeNamespace + '.' + FactoryMapTypeName)
                {
                    assembly.Types.Remove(type);
                    break;
                }
            }

            // Now we create the actual type and stuff...
            TypeReference   objectType = assembly.Import(typeof(Object));
            MethodReference objectCtor = assembly.Import(typeof(Object).GetConstructor(new Type[0]));

            TypeDefinition mapType = new TypeDefinition(FactoryMapTypeName, FactoryMapTypeNamespace, TypeAttributes.Public, objectType);

            mapType.Interfaces.Add(assembly.Import(typeof(IRuntimeFactoryInformation)));

            MethodDefinition defaultCtor = new MethodDefinition(".ctor", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, assembly.Import(typeof(void)));
            CilWorker        worker      = defaultCtor.Body.CilWorker;

            worker.Append(worker.Create(OpCodes.Ldarg_0));
            worker.Append(worker.Create(OpCodes.Call, objectCtor));
            worker.Append(worker.Create(OpCodes.Ret));
            mapType.Constructors.Add(defaultCtor);
            return(mapType);
        }
예제 #6
0
 private void EmitInterceptorCall(CilWorker IL)
 {
     // var result = replacement.Intercept(info);
     IL.Emit(OpCodes.Ldloc, _replacement);
     IL.Emit(OpCodes.Ldloc, _invocationInfo);
     IL.Emit(OpCodes.Callvirt, _intercept);
 }
예제 #7
0
        private static void GetMethodReplacementInstance(MethodDefinition method,
                                                         CilWorker IL,
                                                         VariableDefinition methodReplacement,
                                                         VariableDefinition methodReplacementProvider, VariableDefinition invocationInfo)
        {
            var declaringType = method.DeclaringType;
            var module        = declaringType.Module;
            var pushInstance  = method.HasThis ? IL.Create(OpCodes.Ldarg_0) : IL.Create(OpCodes.Ldnull);

            var getReplacement = module.ImportMethod <IMethodReplacementProvider>("GetMethodReplacement");

            IL.Emit(OpCodes.Ldloc, methodReplacementProvider);

            var skipGetMethodReplacement = IL.Create(OpCodes.Nop);

            IL.Emit(OpCodes.Brfalse, skipGetMethodReplacement);
            IL.Emit(OpCodes.Ldloc, methodReplacementProvider);

            IL.Append(pushInstance);
            IL.Emit(OpCodes.Ldloc, invocationInfo);
            IL.Emit(OpCodes.Callvirt, getReplacement);
            IL.Emit(OpCodes.Stloc, methodReplacement);

            IL.Append(skipGetMethodReplacement);
        }
예제 #8
0
 private void AddOriginalInstructions(CilWorker IL, IEnumerable <Instruction> oldInstructions)
 {
     foreach (Instruction instruction in oldInstructions)
     {
         IL.Append(instruction);
     }
 }
예제 #9
0
        /// <summary>
        /// Saves the current <see cref="IExceptionHandlerInfo"/> instance.
        /// </summary>
        /// <param name="targetMethod">The target method.</param>
        /// <param name="emitter">The <see cref="IEmitInvocationInfo"/> instance that will emit the current method context.</param>
        private void SaveExceptionInfo(MethodDefinition targetMethod, IEmitInvocationInfo emitter)
        {
            CilWorker        IL     = targetMethod.GetILGenerator();
            ModuleDefinition module = IL.GetModule();

            emitter.Emit(targetMethod, targetMethod, _invocationInfo);
            IL.Emit(OpCodes.Ldloc, _exception);
            IL.Emit(OpCodes.Ldloc, _invocationInfo);

            MethodReference exceptionInfoConstructor = module.ImportConstructor <ExceptionHandlerInfo>(
                typeof(Exception),
                typeof(IInvocationInfo));

            IL.Emit(OpCodes.Newobj, exceptionInfoConstructor);
            IL.Emit(OpCodes.Stloc, _exceptionInfo);

            TypeReference returnType = targetMethod.ReturnType.ReturnType;

            if (returnType == _voidType || _returnValue == null)
            {
                return;
            }

            // exceptionInfo.ReturnValue = returnValue;
            MethodReference setReturnValue = module.ImportMethod <IExceptionHandlerInfo>("set_ReturnValue");

            IL.Emit(OpCodes.Ldloc, _exceptionInfo);
            IL.Emit(OpCodes.Ldloc, _returnValue);
            IL.Emit(OpCodes.Callvirt, setReturnValue);
        }
예제 #10
0
        private static void Emit(CilWorker IL, ModuleDefinition module,
                                 VariableDefinition surroundingImplementation,
                                 VariableDefinition invocationInfo,
                                 VariableDefinition returnValue)
        {
            var skipInvoke = IL.Create(OpCodes.Nop);

            var skipPrint = IL.Create(OpCodes.Nop);

            IL.Emit(OpCodes.Ldloc, surroundingImplementation);
            IL.Emit(OpCodes.Brtrue, skipPrint);

            IL.Append(skipPrint);
            IL.Emit(OpCodes.Ldloc, surroundingImplementation);
            IL.Emit(OpCodes.Brfalse, skipInvoke);

            var aroundInvoke = module.ImportMethod <IAfterInvoke>("AfterInvoke");

            IL.Emit(OpCodes.Ldloc, surroundingImplementation);
            IL.Emit(OpCodes.Ldloc, invocationInfo);
            IL.Emit(OpCodes.Ldloc, returnValue);
            IL.Emit(OpCodes.Callvirt, aroundInvoke);

            IL.Append(skipInvoke);
        }
예제 #11
0
        /// <summary>
        /// Rewrites a target method using the given CilWorker.
        /// </summary>
        /// <param name="method">The target method.</param>
        /// <param name="IL">The CilWorker that will be used to rewrite the target method.</param>
        /// <param name="oldInstructions">The original instructions from the target method body.</param>
        public void Rewrite(MethodDefinition method, CilWorker IL, IEnumerable <Instruction> oldInstructions)
        {
            var declaringType = method.DeclaringType;
            var module        = declaringType.Module;

            // Interfaces and Enums cannot be modified
            if (declaringType.IsInterface || declaringType.IsEnum)
            {
                return;
            }

            ImportReferences(module);

            AddLocals(method);

            if (!_modifiedTypes.Contains(declaringType))
            {
                AddAdditionalMembers(declaringType);
                _modifiedTypes.Add(declaringType);
            }

            var newInstructions = new Queue <Instruction>();

            foreach (var instruction in oldInstructions)
            {
                // Intercept only the load field and the load static field instruction
                if (!ShouldReplace(instruction, method))
                {
                    IL.Append(instruction);
                    continue;
                }

                Replace(instruction, method, IL);
            }
        }
예제 #12
0
        public void AddEmptyMethod(MethodElement me)
        {
            //	Console.WriteLine("\t" + me.Name);

            TypeReference    returnType = _resolver.ForceResolve(me.ReturnType);
            MethodDefinition newMethod  = new MethodDefinition(me.Name, MethodAttributes.Public, returnType);

            foreach (ParameterElement pe in me.Parameters)
            {
                TypeReference       paramType = _resolver.ForceResolve(pe.Type);
                ParameterDefinition param     = new ParameterDefinition(paramType);
                param.Name = pe.Name;

                //	Console.WriteLine("\t\t" + param.Name + " :: " + param.ParameterType);

                newMethod.Parameters.Add(param);
            }

            Type            exceptionType = typeof(NotImplementedException);
            MethodReference cons          = _type.Module.Import(exceptionType.GetConstructor(new Type[] {}));

            CilWorker worker = newMethod.Body.CilWorker;

            worker.Append(worker.Create(OpCodes.Nop));
            worker.Append(worker.Create(OpCodes.Newobj, cons));
            worker.Append(worker.Create(OpCodes.Throw));

            _type.Methods.Add(newMethod);
        }
예제 #13
0
 public MethodContext(CilWorker worker, VariableDefinition currentArguments, MethodReference currentMethod, VariableDefinition currentArgument)
 {
     CilWorker        = worker;
     CurrentArguments = currentArguments;
     CurrentMethod    = currentMethod;
     CurrentArgument  = currentArgument;
 }
예제 #14
0
        /// <summary>
        /// Pushes the current <paramref name="method"/> onto the stack.
        /// </summary>
        /// <param name="IL">The <see cref="CilWorker"/> that will be used to create the instructions.</param>
        /// <param name="method">The method that represents the <see cref="MethodInfo"/> that will be pushed onto the stack.</param>
        /// <param name="module">The module that contains the host method.</param>
        public static void PushMethod(this CilWorker IL, MethodReference method, ModuleDefinition module)
        {
            var getMethodFromHandle = module.ImportMethod <MethodBase>("GetMethodFromHandle",
                                                                       typeof(RuntimeMethodHandle),
                                                                       typeof(RuntimeTypeHandle));

            var declaringType = method.DeclaringType;

            // Instantiate the generic type before determining
            // the current method
            if (declaringType.GenericParameters.Count > 0)
            {
                var genericType = new GenericInstanceType(declaringType);
                foreach (GenericParameter parameter in declaringType.GenericParameters)
                {
                    genericType.GenericArguments.Add(parameter);
                }

                declaringType = genericType;
            }


            IL.Emit(OpCodes.Ldtoken, method);
            IL.Emit(OpCodes.Ldtoken, declaringType);
            IL.Emit(OpCodes.Call, getMethodFromHandle);
        }
예제 #15
0
        /// <summary>
        /// Obtains the module that contains the current <see cref="CilWorker"/>.
        /// </summary>
        /// <param name="IL">The <see cref="CilWorker"/> responsible for the method body.</param>
        /// <returns>The host module.</returns>
        public static ModuleDefinition GetModule(this CilWorker IL)
        {
            var method        = IL.GetMethod();
            var declaringType = method.DeclaringType;

            return(declaringType.Module);
        }
예제 #16
0
        /// <summary>
        /// Obtains the method definition that contains the current <see cref="CilWorker"/>.
        /// </summary>
        /// <param name="IL">The <see cref="CilWorker"/> responsible for the method body.</param>
        /// <returns>A method definition.</returns>
        public static MethodDefinition GetMethod(this CilWorker IL)
        {
            var body         = IL.GetBody();
            var targetMethod = body.Method;

            return(targetMethod);
        }
예제 #17
0
        /// <summary>
        /// Stores the <paramref name="param">current parameter value</paramref>
        /// into the array of method <paramref name="arguments"/>.
        /// </summary>
        /// <param name="IL">The <see cref="CilWorker"/> that will be used to create the instructions.</param>
        /// <param name="arguments">The local variable that will store the method arguments.</param>
        /// <param name="index">The array index that indicates where the parameter value will be stored in the array of arguments.</param>
        /// <param name="param">The current argument value being stored.</param>
        private static void PushParameter(this CilWorker IL, int index, VariableDefinition arguments,
                                          ParameterDefinition param)
        {
            var parameterType = param.ParameterType;

            IL.Emit(OpCodes.Ldloc, arguments);
            IL.Emit(OpCodes.Ldc_I4, index);

            // Zero out the [out] parameters
            if (param.IsOut || param.IsByRef())
            {
                IL.Emit(OpCodes.Ldnull);
                IL.Emit(OpCodes.Stelem_Ref);
                return;
            }

            IL.Emit(OpCodes.Ldarg, param);

            if (parameterType.IsValueType || parameterType is GenericParameter)
            {
                IL.Emit(OpCodes.Box, param.ParameterType);
            }

            IL.Emit(OpCodes.Stelem_Ref);
        }
예제 #18
0
 private void EmitCreateInstance(CilWorker IL)
 {
     // T instance = this.Activator.CreateInstance(context);
     IL.Emit(OpCodes.Ldloc, _currentActivator);
     IL.Emit(OpCodes.Ldloc, _methodContext);
     IL.Emit(OpCodes.Callvirt, _createInstance);
 }
예제 #19
0
        protected override void Replace(Instruction oldInstruction, MethodDefinition hostMethod,
                                        CilWorker IL)
        {
            var targetMethod = (MethodReference)oldInstruction.Operand;

            var callOriginalMethod = IL.Create(OpCodes.Nop);
            var returnType         = targetMethod.ReturnType.ReturnType;
            var endLabel           = IL.Create(OpCodes.Nop);
            var module             = hostMethod.DeclaringType.Module;

            // Create the stack that will hold the method arguments
            IL.Emit(OpCodes.Newobj, _stackCtor);
            IL.Emit(OpCodes.Stloc, _currentArguments);

            SaveInvocationInfo(IL, targetMethod, module, returnType);

            var getInterceptionDisabled = new GetInterceptionDisabled(hostMethod, _interceptionDisabled);

            getInterceptionDisabled.Emit(IL);

            var surroundMethodBody = new SurroundMethodBody(_methodReplacementProvider, _aroundInvokeProvider,
                                                            _invocationInfo, _interceptionDisabled, _returnValue, typeof(AroundInvokeMethodCallRegistry));

            surroundMethodBody.AddProlog(IL);
            // Use the MethodReplacementProvider attached to the
            // current host instance
            Replace(IL, oldInstruction, targetMethod, hostMethod, endLabel, callOriginalMethod);

            IL.Append(endLabel);

            surroundMethodBody.AddEpilog(IL);
        }
        public void StoreFactoryMap(IAssembly assembly, FactoryMap factoryMap)
        {
            MethodInfo      getTypeFromHandleReflect = typeof(Type).GetMethod("GetTypeFromHandle", new Type[] { typeof(RuntimeTypeHandle) });
            MethodReference getTypeFromHandle        = assembly.Import(getTypeFromHandleReflect);
            TypeReference   systemType          = assembly.Import(typeof(Type));
            TypeReference   arrayOfTypes        = assembly.Import(typeof(Type[]));
            TypeReference   arrayOfArrayOfTypes = assembly.Import(typeof(Type[][]));

            // Now we create the actual type and stuff...
            TypeDefinition   mapType            = GetFactoryMapType(assembly);
            MethodDefinition getFactoriesMethod = new MethodDefinition(FactoryMapMethodName, MethodAttributes.Public, arrayOfArrayOfTypes);

            getFactoriesMethod.IsVirtual = true;
            mapType.Methods.Add(getFactoriesMethod);

            getFactoriesMethod.Body.Variables.Add(new VariableDefinition("map", 0, getFactoriesMethod, arrayOfArrayOfTypes));
            getFactoriesMethod.Body.Variables.Add(new VariableDefinition("row", 1, getFactoriesMethod, arrayOfTypes));
            getFactoriesMethod.Body.InitLocals = true;

            CilWorker      worker    = getFactoriesMethod.Body.CilWorker;
            List <Factory> factories = new List <Factory>(factoryMap.Factories);

            worker.Append(worker.Create(OpCodes.Nop));
            worker.Append(worker.Create(OpCodes.Ldc_I4, factories.Count));
            worker.Append(worker.Create(OpCodes.Newarr, arrayOfTypes));
            worker.Append(worker.Create(OpCodes.Stloc_0));
            worker.Append(worker.Create(OpCodes.Ldloc_0));

            int index = 0;

            foreach (Factory factory in factories)
            {
                worker.Append(worker.Create(OpCodes.Ldc_I4, index));

                worker.Append(worker.Create(OpCodes.Ldc_I4, 2));
                worker.Append(worker.Create(OpCodes.Newarr, systemType));
                worker.Append(worker.Create(OpCodes.Stloc_1));

                worker.Append(worker.Create(OpCodes.Ldloc_1));
                worker.Append(worker.Create(OpCodes.Ldc_I4_0));
                worker.Append(worker.Create(OpCodes.Ldtoken, factory.ObjectType));
                worker.Append(worker.Create(OpCodes.Call, getTypeFromHandle));
                worker.Append(worker.Create(OpCodes.Stelem_Ref));

                worker.Append(worker.Create(OpCodes.Ldloc_1));
                worker.Append(worker.Create(OpCodes.Ldc_I4_1));
                worker.Append(worker.Create(OpCodes.Ldtoken, factory.FactoryType));
                worker.Append(worker.Create(OpCodes.Call, getTypeFromHandle));
                worker.Append(worker.Create(OpCodes.Stelem_Ref));

                worker.Append(worker.Create(OpCodes.Ldloc_1));
                worker.Append(worker.Create(OpCodes.Stelem_Ref));
                index++;
                worker.Append(worker.Create(OpCodes.Ldloc_0));
            }

            worker.Append(worker.Create(OpCodes.Ret));
            assembly.Inject(mapType);
        }
예제 #21
0
        private void IgnoreLocal(CilWorker IL, VariableDefinition targetVariable, ModuleDefinition module)
        {
            IL.Emit(OpCodes.Ldloc, targetVariable);

            var addInstance = module.Import(typeof(IgnoredInstancesRegistry).GetMethod("AddInstance"));

            IL.Emit(OpCodes.Call, addInstance);
        }
예제 #22
0
        public Instruction CreateConditionalBranch()
        {
            Instruction branch      = CilWorker.Create(OpCodes.Nop);
            Instruction instruction = CilWorker.Create(OpCodes.Brtrue, branch);

            instruction.Next = CilWorker.Create(OpCodes.Nop);
            return(instruction);
        }
예제 #23
0
        /// <summary>
        /// Emits a Console.WriteLine call to using the current CilWorker that will only be called if the contents
        /// of the target variable are null at runtime.
        /// </summary>
        /// <param name="IL">The target CilWorker.</param>
        /// <param name="text">The text that will be written to the console.</param>
        /// <param name="targetVariable">The target variable that will be checked for null at runtime.</param>
        public static void EmitWriteLineIfNull(this CilWorker IL, string text, VariableDefinition targetVariable)
        {
            var skipWrite = IL.Create(OpCodes.Nop);

            IL.Emit(OpCodes.Ldloc, targetVariable);
            IL.Emit(OpCodes.Brtrue, skipWrite);
            IL.EmitWriteLine(text);
            IL.Append(skipWrite);
        }
예제 #24
0
        /// <summary>
        /// Rewrites the instructions in the target method body.
        /// </summary>
        /// <param name="method">The target method.</param>
        /// <param name="IL">The <see cref="CilWorker"/> instance that represents the method body.</param>
        /// <param name="oldInstructions">The IL instructions of the original method body.</param>
        protected override void RewriteMethodBody(MethodDefinition method, CilWorker IL,
                                                  IEnumerable <Instruction> oldInstructions)
        {
            if (IsExcluded(method))
            {
                AddOriginalInstructions(IL, oldInstructions);
                return;
            }

            VariableDefinition interceptionDisabled      = method.AddLocal <bool>();
            VariableDefinition invocationInfo            = method.AddLocal <IInvocationInfo>();
            VariableDefinition aroundInvokeProvider      = method.AddLocal <IAroundInvokeProvider>();
            VariableDefinition methodReplacementProvider = method.AddLocal <IMethodReplacementProvider>();


            VariableDefinition returnValue = method.AddLocal <object>();
            VariableDefinition classMethodReplacementProvider = method.AddLocal <IMethodReplacementProvider>();

            Func <ModuleDefinition, MethodReference> getInstanceMethodReplacementProviderMethod =
                module => module.Import(typeof(IMethodReplacementHost).GetMethod("get_MethodBodyReplacementProvider"));

            var parameters = new MethodBodyRewriterParameters(IL,
                                                              oldInstructions,
                                                              interceptionDisabled,
                                                              invocationInfo, returnValue,
                                                              methodReplacementProvider,
                                                              aroundInvokeProvider,
                                                              classMethodReplacementProvider,
                                                              getInstanceMethodReplacementProviderMethod,
                                                              typeof(AroundMethodBodyRegistry));

            var emitter = new InvocationInfoEmitter(true);

            IInstructionEmitter getMethodReplacementProvider =
                new GetMethodReplacementProvider(methodReplacementProvider, method,
                                                 getInstanceMethodReplacementProviderMethod);

            IInstructionEmitter getInterceptionDisabled           = new GetInterceptionDisabled(parameters);
            ISurroundMethodBody surroundMethodBody                = new SurroundMethodBody(parameters, "AroundMethodBodyProvider");
            IInstructionEmitter getClassMethodReplacementProvider = new GetClassMethodReplacementProvider(parameters,
                                                                                                          module =>
                                                                                                          module.Import(
                                                                                                              typeof(
                                                                                                                  MethodBodyReplacementProviderRegistry
                                                                                                                  ).
                                                                                                              GetMethod
                                                                                                                  ("GetProvider")));
            IInstructionEmitter addMethodReplacement = new AddMethodReplacementImplementation(parameters);

            var rewriter = new InterceptAndSurroundMethodBody(emitter, getInterceptionDisabled, surroundMethodBody,
                                                              getMethodReplacementProvider,
                                                              getClassMethodReplacementProvider, addMethodReplacement,
                                                              parameters);

            // Determine whether or not the method should be intercepted
            rewriter.Rewrite(method, IL, oldInstructions);
        }
예제 #25
0
        public void StartCilWork()
        {
            if (this.asm != null)
            {
                foreach (TypeDefinition type in this.asm.MainModule.Types)
                {
                    if (type.Name != "<Module>")
                    {
                        foreach (MethodDefinition method in type.Methods)
                        {
                            if (this.Filter.Contains(method.Name))
                            {
                                CilWorker worker = method.Body.CilWorker;
                                string    s      = string.Concat("Code added in: ", method.Name);

                                // Import StreamWriter constructor.
                                ConstructorInfo   ci      = typeof(StreamWriter).GetConstructor(new Type[] { typeof(string) });
                                VariableReference streamw = asm.MainModule.Import(ci);
                                streamw.Name = "sw";

                                // Get streamw's methods. WriteLine and Flush
                                this.writeLine = streamw.GetType().GetMethod("WriteLine", new Type[] { typeof(string) });
                                this.flush     = streamw.GetType().GetMethod("Flush");

                                // Create a MSIL instructions.
                                Instruction fileName   = worker.Create(OpCodes.Ldstr, "debug-methods.log");
                                Instruction insertText = worker.Create(OpCodes.Ldstr, s);

                                // Create the streamwriter variable:
                                Instruction createVar = worker.Create(OpCodes.Newobj, streamw);

                                // CIL Instruction for calling StreamWriter.WriteLine()
                                Instruction callWriteLine = worker.Create(OpCodes.Call, this.writeLine);

                                // CIL Instruction for calling StreamWriter.Flush()
                                Instruction callFlush = worker.Create(OpCodes.Call, this.flush);

                                // Get the first instruction of the method.
                                Instruction ins = method.Body.Instructions[0];

                                // Insert instructions to method body.
                                method.Body.CilWorker.InsertBefore(ins, fileName);
                                worker.InsertAfter(fileName, createVar);
                                worker.InsertAfter(createVar, insertText);
                                worker.InsertAfter(insertText, writeLine);
                                worker.InsertAfter(writeLine, flush);
                            }
                        }
                    }
                    asm.MainModule.Import(type);
                }
                // Save the modified assembly.
                AssemblyFactory.SaveAssembly(this.asm, this.Path);
                Console.WriteLine("Deep Logging enabled");
            }
        }
예제 #26
0
        /// <summary>
        /// Emits the call to the <see cref="IAfterInvoke"/> instance.
        /// </summary>
        /// <param name="IL">The <see cref="CilWorker"/> that points to the current method body.</param>
        public void Emit(CilWorker IL)
        {
            var module = IL.GetModule();

            // instanceAroundInvoke.AfterInvoke(info, returnValue);
            Emit(IL, module, _surroundingImplementation, _invocationInfo, _returnValue);

            // classAroundInvoke.AfterInvoke(info, returnValue);
            Emit(IL, module, _surroundingClassImplementation, _invocationInfo, _returnValue);
        }
예제 #27
0
        public Instruction CreateSwitchBranch()
        {
            Instruction branch1     = CilWorker.Create(OpCodes.Nop);
            Instruction branch2     = CilWorker.Create(OpCodes.Nop);
            Instruction branch3     = CilWorker.Create(OpCodes.Nop);
            Instruction instruction = CilWorker.Create(OpCodes.Switch, new Instruction[] { branch1, branch2, branch3 });

            instruction.Next = CilWorker.Create(OpCodes.Nop);
            return(instruction);
        }
예제 #28
0
        private static void InvokeInterceptor(ModuleDefinition module, CilWorker IL,
                                              VariableDefinition methodReplacement, TypeReference returnType, VariableDefinition invocationInfo)
        {
            var interceptMethod = module.ImportMethod <IInterceptor>("Intercept");

            IL.Emit(OpCodes.Ldloc, methodReplacement);
            IL.Emit(OpCodes.Ldloc, invocationInfo);
            IL.Emit(OpCodes.Callvirt, interceptMethod);
            IL.PackageReturnValue(module, returnType);
        }
예제 #29
0
        /// <summary>
        /// Pushes a <paramref name="Type"/> instance onto the stack.
        /// </summary>
        /// <param name="IL">The <see cref="CilWorker"/> that will be used to create the instructions.</param>
        /// <param name="type">The type that represents the <see cref="Type"/> that will be pushed onto the stack.</param>
        /// <param name="module">The module that contains the host method.</param>
        public static void PushType(this CilWorker IL, TypeReference type, ModuleDefinition module)
        {
            var getTypeFromHandle = module.ImportMethod <Type>("GetTypeFromHandle", typeof(RuntimeTypeHandle));

            // Instantiate the generic type before pushing it onto the stack
            var declaringType = GetDeclaringType(type);

            IL.Emit(OpCodes.Ldtoken, declaringType);
            IL.Emit(OpCodes.Call, getTypeFromHandle);
        }
예제 #30
0
        public void codeBlock_CallToMethod(MethodDefinition targetMethod, MethodInfo methodToCall)
        {
            CilWorker cliWorker      = targetMethod.Body.CilWorker;
            var       lsInstructions = new List <Instruction>
            {
                cliWorker.Create(OpCodes.Call, getMethodReference(methodToCall))
            };

            CecilOpCodeUtils.addInstructionsToMethod_InsertAtEnd(targetMethod, lsInstructions);
        }