Example #1
0
        public void createMethod(MethodBase realMethod)
        {
            if (realMethodToNewMethod.ContainsKey(realMethod))
            {
                return;
            }
            var newMethodInfo = new NewMethodInfo(realMethod, newMethodInfos.Count, getDelegateMethodName(realMethod), getDelegateMethodName(realMethod));

            newMethodInfos.Add(newMethodInfo);
            delegateNameToNewMethodInfo[newMethodInfo.delegateMethodName]  = newMethodInfo;
            delegateNameToNewMethodInfo[newMethodInfo.rewrittenMethodName] = newMethodInfo;
            realMethodToNewMethod[realMethod] = newMethodInfo;

            var moduleInfo = Resolver.loadAssembly(realMethod.Module);
            var methodInfo = moduleInfo.getMethod(realMethod);

            if (!methodInfo.hasInstructions())
            {
                throw new ApplicationException(string.Format("Method {0} ({1:X8}) has no body", methodInfo.methodDef, methodInfo.methodDef.MDToken.Raw));
            }

            var codeGenerator = new CodeGenerator(this, newMethodInfo.delegateMethodName);

            codeGenerator.setMethodInfo(methodInfo);
            newMethodInfo.delegateType = codeGenerator.DelegateType;

            var blocks = new Blocks(methodInfo.methodDef);

            foreach (var block in blocks.MethodBlocks.getAllBlocks())
            {
                update(block, newMethodInfo);
            }

            IList <Instruction>      allInstructions;
            IList <ExceptionHandler> allExceptionHandlers;

            blocks.getCode(out allInstructions, out allExceptionHandlers);
            newMethodInfo.delegateInstance = codeGenerator.generate(allInstructions, allExceptionHandlers);
        }
Example #2
0
        public void CreateMethod(MethodBase realMethod)
        {
            if (realMethodToNewMethod.ContainsKey(realMethod))
            {
                return;
            }
            var newMethodInfo = new NewMethodInfo(realMethod, newMethodInfos.Count, GetDelegateMethodName(realMethod), GetDelegateMethodName(realMethod));

            newMethodInfos.Add(newMethodInfo);
            delegateNameToNewMethodInfo[newMethodInfo.delegateMethodName]  = newMethodInfo;
            delegateNameToNewMethodInfo[newMethodInfo.rewrittenMethodName] = newMethodInfo;
            realMethodToNewMethod[realMethod] = newMethodInfo;

            var moduleInfo = Resolver.LoadAssembly(realMethod.Module);
            var methodInfo = moduleInfo.GetMethod(realMethod);

            if (!methodInfo.HasInstructions())
            {
                throw new ApplicationException($"Method {methodInfo.methodDef} ({methodInfo.methodDef.MDToken.Raw:X8}) has no body");
            }

            var codeGenerator = new CodeGenerator(this, newMethodInfo.delegateMethodName);

            codeGenerator.SetMethodInfo(methodInfo);
            newMethodInfo.delegateType = codeGenerator.DelegateType;

            var blocks = new Blocks(methodInfo.methodDef);

            foreach (var block in blocks.MethodBlocks.GetAllBlocks())
            {
                Update(block, newMethodInfo);
            }

            blocks.GetCode(out var allInstructions, out var allExceptionHandlers);
            newMethodInfo.delegateInstance = codeGenerator.Generate(allInstructions, allExceptionHandlers);
        }
Example #3
0
        void update(Block block, NewMethodInfo currentMethodInfo)
        {
            var instrs = block.Instructions;

            for (int i = 0; i < instrs.Count; i++)
            {
                var instr = instrs[i];
                if (instr.OpCode == OpCodes.Newobj)
                {
                    var ctor             = (IMethod)instr.Operand;
                    var ctorTypeFullName = ctor.DeclaringType.FullName;
                    if (ctorTypeFullName == "System.Diagnostics.StackTrace")
                    {
                        insertLoadThis(block, i + 1);
                        insertCallOurMethod(block, i + 2, "static_rtFixStackTrace");
                        i += 2;
                        continue;
                    }
                    else if (ctorTypeFullName == "System.Diagnostics.StackFrame")
                    {
                        insertLoadThis(block, i + 1);
                        insertCallOurMethod(block, i + 2, "static_rtFixStackFrame");
                        i += 2;
                        continue;
                    }
                }

                if (instr.OpCode == OpCodes.Call || instr.OpCode == OpCodes.Callvirt)
                {
                    var calledMethod = (IMethod)instr.Operand;
                    if (calledMethod.DeclaringType.DefinitionAssembly.IsCorLib())
                    {
                        var calledMethodFullName = calledMethod.FullName;
                        if (calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetAssembly(System.Type)")
                        {
                            block.replace(i, 1, OpCodes.Nop.ToInstruction());
                            insertLoadThis(block, i + 1);
                            insertCallOurMethod(block, i + 2, "static_rtGetAssembly_TypeArg");
                            i += 2;
                            continue;
                        }
                        else if (calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetCallingAssembly()" ||
                                 calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetEntryAssembly()" ||
                                 calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetExecutingAssembly()")
                        {
                            block.replace(i, 1, OpCodes.Nop.ToInstruction());
                            insertLoadThis(block, i + 1);
                            block.insert(i + 2, OpCodes.Ldc_I4.ToInstruction(currentMethodInfo.delegateIndex));
                            insertCallOurMethod(block, i + 3, "rtGetAssembly");
                            i += 3;
                            continue;
                        }
                    }

                    var method = Resolver.getMethod((IMethod)instr.Operand);
                    if (method != null)
                    {
                        createMethod(method.methodBase);
                        var newMethodInfo = realMethodToNewMethod[method.methodBase];

                        block.replace(i, 1, OpCodes.Nop.ToInstruction());
                        int n = i + 1;

                        // Pop all pushed args to a temp array
                        var mparams = getParameters(method.methodDef);
                        if (mparams.Count > 0)
                        {
                            block.insert(n++, OpCodes.Ldc_I4.ToInstruction(mparams.Count));
                            var objectType = method.methodDef.DeclaringType.Module.CorLibTypes.Object;
                            block.insert(n++, OpCodes.Newarr.ToInstruction(objectType));
                            block.insert(n++, create(OpCodes.Stloc, new Operand(Operand.Type.TempObjArray)));

                            for (int j = mparams.Count - 1; j >= 0; j--)
                            {
                                var argType = mparams[j];
                                if (argType.RemovePinnedAndModifiers().IsValueType)
                                {
                                    block.insert(n++, OpCodes.Box.ToInstruction(((TypeDefOrRefSig)argType).TypeDefOrRef));
                                }
                                block.insert(n++, create(OpCodes.Stloc, new Operand(Operand.Type.TempObj)));
                                block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObjArray)));
                                block.insert(n++, OpCodes.Ldc_I4.ToInstruction(j));
                                block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObj)));
                                block.insert(n++, OpCodes.Stelem_Ref.ToInstruction());
                            }
                        }

                        // Push delegate instance
                        insertLoadThis(block, n++);
                        block.insert(n++, OpCodes.Ldc_I4.ToInstruction(newMethodInfo.delegateIndex));
                        insertCallOurMethod(block, n++, "rtGetDelegateInstance");
                        block.insert(n++, create(OpCodes.Castclass, new Operand(Operand.Type.ReflectionType, newMethodInfo.delegateType)));

                        // Push all popped args
                        if (mparams.Count > 0)
                        {
                            for (int j = 0; j < mparams.Count; j++)
                            {
                                block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObjArray)));
                                block.insert(n++, OpCodes.Ldc_I4.ToInstruction(j));
                                block.insert(n++, OpCodes.Ldelem_Ref.ToInstruction());
                                var argType = mparams[j];
                                if (argType.RemovePinnedAndModifiers().IsValueType)
                                {
                                    block.insert(n++, OpCodes.Unbox_Any.ToInstruction(((TypeDefOrRefSig)argType).TypeDefOrRef));
                                }
                                else
                                {
                                    // Don't cast it to its correct type. This will sometimes cause
                                    // an exception in some EF obfuscated assembly since we'll be
                                    // trying to cast a System.Reflection.AssemblyName type to some
                                    // other type.
                                    // block.insert(n++, Instruction.Create(OpCodes.Castclass, argType.ToTypeDefOrRef()));
                                }
                            }
                        }

                        insertLoadThis(block, n++);
                        block.insert(n++, create(OpCodes.Call, new Operand(Operand.Type.NewMethod, method.methodBase)));
                        i = n - 1;
                        continue;
                    }
                }
            }
        }
        void update(Block block, NewMethodInfo currentMethodInfo)
        {
            var instrs = block.Instructions;
            for (int i = 0; i < instrs.Count; i++) {
                var instr = instrs[i];
                if (instr.OpCode == OpCodes.Newobj) {
                    var ctor = (IMethod)instr.Operand;
                    var ctorTypeFullName = ctor.DeclaringType.FullName;
                    if (ctorTypeFullName == "System.Diagnostics.StackTrace") {
                        insertLoadThis(block, i + 1);
                        insertCallOurMethod(block, i + 2, "static_rtFixStackTrace");
                        i += 2;
                        continue;
                    }
                    else if (ctorTypeFullName == "System.Diagnostics.StackFrame") {
                        insertLoadThis(block, i + 1);
                        insertCallOurMethod(block, i + 2, "static_rtFixStackFrame");
                        i += 2;
                        continue;
                    }
                }

                if (instr.OpCode == OpCodes.Call || instr.OpCode == OpCodes.Callvirt) {
                    var calledMethod = (IMethod)instr.Operand;
                    if (calledMethod.DeclaringType.DefinitionAssembly.IsCorLib()) {
                        var calledMethodFullName = calledMethod.FullName;
                        if (calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetAssembly(System.Type)") {
                            block.replace(i, 1, OpCodes.Nop.ToInstruction());
                            insertLoadThis(block, i + 1);
                            insertCallOurMethod(block, i + 2, "static_rtGetAssembly_TypeArg");
                            i += 2;
                            continue;
                        }
                        else if (calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetCallingAssembly()" ||
                                calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetEntryAssembly()" ||
                                calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetExecutingAssembly()") {
                            block.replace(i, 1, OpCodes.Nop.ToInstruction());
                            insertLoadThis(block, i + 1);
                            block.insert(i + 2, OpCodes.Ldc_I4.ToInstruction(currentMethodInfo.delegateIndex));
                            insertCallOurMethod(block, i + 3, "rtGetAssembly");
                            i += 3;
                            continue;
                        }
                    }

                    var method = Resolver.getMethod((IMethod)instr.Operand);
                    if (method != null) {
                        createMethod(method.methodBase);
                        var newMethodInfo = realMethodToNewMethod[method.methodBase];

                        block.replace(i, 1, OpCodes.Nop.ToInstruction());
                        int n = i + 1;

                        // Pop all pushed args to a temp array
                        var mparams = getParameters(method.methodDef);
                        if (mparams.Count > 0) {
                            block.insert(n++, OpCodes.Ldc_I4.ToInstruction(mparams.Count));
                            var objectType = method.methodDef.DeclaringType.Module.CorLibTypes.Object;
                            block.insert(n++, OpCodes.Newarr.ToInstruction(objectType));
                            block.insert(n++, create(OpCodes.Stloc, new Operand(Operand.Type.TempObjArray)));

                            for (int j = mparams.Count - 1; j >= 0; j--) {
                                var argType = mparams[j];
                                if (argType.RemovePinnedAndModifiers().IsValueType)
                                    block.insert(n++, OpCodes.Box.ToInstruction(((TypeDefOrRefSig)argType).TypeDefOrRef));
                                block.insert(n++, create(OpCodes.Stloc, new Operand(Operand.Type.TempObj)));
                                block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObjArray)));
                                block.insert(n++, OpCodes.Ldc_I4.ToInstruction(j));
                                block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObj)));
                                block.insert(n++, OpCodes.Stelem_Ref.ToInstruction());
                            }
                        }

                        // Push delegate instance
                        insertLoadThis(block, n++);
                        block.insert(n++, OpCodes.Ldc_I4.ToInstruction(newMethodInfo.delegateIndex));
                        insertCallOurMethod(block, n++, "rtGetDelegateInstance");
                        block.insert(n++, create(OpCodes.Castclass, new Operand(Operand.Type.ReflectionType, newMethodInfo.delegateType)));

                        // Push all popped args
                        if (mparams.Count > 0) {
                            for (int j = 0; j < mparams.Count; j++) {
                                block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObjArray)));
                                block.insert(n++, OpCodes.Ldc_I4.ToInstruction(j));
                                block.insert(n++, OpCodes.Ldelem_Ref.ToInstruction());
                                var argType = mparams[j];
                                if (argType.RemovePinnedAndModifiers().IsValueType)
                                    block.insert(n++, OpCodes.Unbox_Any.ToInstruction(((TypeDefOrRefSig)argType).TypeDefOrRef));
                                else {
                                    // Don't cast it to its correct type. This will sometimes cause
                                    // an exception in some EF obfuscated assembly since we'll be
                                    // trying to cast a System.Reflection.AssemblyName type to some
                                    // other type.
                                    // block.insert(n++, Instruction.Create(OpCodes.Castclass, argType.ToTypeDefOrRef()));
                                }
                            }
                        }

                        insertLoadThis(block, n++);
                        block.insert(n++, create(OpCodes.Call, new Operand(Operand.Type.NewMethod, method.methodBase)));
                        i = n - 1;
                        continue;
                    }
                }
            }
        }
        public void createMethod(MethodBase realMethod)
        {
            if (realMethodToNewMethod.ContainsKey(realMethod))
                return;
            var newMethodInfo = new NewMethodInfo(realMethod, newMethodInfos.Count, getDelegateMethodName(realMethod), getDelegateMethodName(realMethod));
            newMethodInfos.Add(newMethodInfo);
            delegateNameToNewMethodInfo[newMethodInfo.delegateMethodName] = newMethodInfo;
            delegateNameToNewMethodInfo[newMethodInfo.rewrittenMethodName] = newMethodInfo;
            realMethodToNewMethod[realMethod] = newMethodInfo;

            var moduleInfo = Resolver.loadAssembly(realMethod.Module);
            var methodInfo = moduleInfo.getMethod(realMethod);
            if (!methodInfo.hasInstructions())
                throw new ApplicationException(string.Format("Method {0} ({1:X8}) has no body", methodInfo.methodDef, methodInfo.methodDef.MDToken.Raw));

            var codeGenerator = new CodeGenerator(this, newMethodInfo.delegateMethodName);
            codeGenerator.setMethodInfo(methodInfo);
            newMethodInfo.delegateType = codeGenerator.DelegateType;

            var blocks = new Blocks(methodInfo.methodDef);
            foreach (var block in blocks.MethodBlocks.getAllBlocks())
                update(block, newMethodInfo);

            IList<Instruction> allInstructions;
            IList<ExceptionHandler> allExceptionHandlers;
            blocks.getCode(out allInstructions, out allExceptionHandlers);
            newMethodInfo.delegateInstance = codeGenerator.generate(allInstructions, allExceptionHandlers);
        }
Example #6
0
        void update(Block block, NewMethodInfo currentMethodInfo)
        {
            var instrs = block.Instructions;

            for (int i = 0; i < instrs.Count; i++)
            {
                var instr = instrs[i];
                if (instr.OpCode == OpCodes.Newobj)
                {
                    var ctor = (MethodReference)instr.Operand;
                    if (MemberReferenceHelper.verifyType(ctor.DeclaringType, "mscorlib", "System.Diagnostics.StackTrace"))
                    {
                        insertLoadThis(block, i + 1);
                        insertCallOurMethod(block, i + 2, "static_rtFixStackTrace");
                        i += 2;
                        continue;
                    }
                    else if (MemberReferenceHelper.verifyType(ctor.DeclaringType, "mscorlib", "System.Diagnostics.StackFrame"))
                    {
                        insertLoadThis(block, i + 1);
                        insertCallOurMethod(block, i + 2, "static_rtFixStackFrame");
                        i += 2;
                        continue;
                    }
                }

                if (instr.OpCode == OpCodes.Call || instr.OpCode == OpCodes.Callvirt)
                {
                    var calledMethod = (MethodReference)instr.Operand;
                    if (DotNetUtils.isSameAssembly(calledMethod.DeclaringType, "mscorlib"))
                    {
                        if (calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetAssembly(System.Type)")
                        {
                            block.replace(i, 1, Instruction.Create(OpCodes.Nop));
                            insertLoadThis(block, i + 1);
                            insertCallOurMethod(block, i + 2, "static_rtGetAssembly_TypeArg");
                            i += 2;
                            continue;
                        }
                        else if (calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetCallingAssembly()" ||
                                 calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetEntryAssembly()" ||
                                 calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetExecutingAssembly()")
                        {
                            block.replace(i, 1, Instruction.Create(OpCodes.Nop));
                            insertLoadThis(block, i + 1);
                            block.insert(i + 2, Instruction.Create(OpCodes.Ldc_I4, currentMethodInfo.delegateIndex));
                            insertCallOurMethod(block, i + 3, "rtGetAssembly");
                            i += 3;
                            continue;
                        }
                    }

                    var method = Resolver.getMethod((MethodReference)instr.Operand);
                    if (method != null)
                    {
                        createMethod(method.methodBase);
                        var newMethodInfo = realMethodToNewMethod[method.methodBase];

                        block.replace(i, 1, Instruction.Create(OpCodes.Nop));
                        int n = i + 1;

                        // Pop all pushed args to a temp array
                        var mparams = getParameters(method.methodDefinition);
                        if (mparams.Count > 0)
                        {
                            block.insert(n++, Instruction.Create(OpCodes.Ldc_I4, mparams.Count));
                            var objectType = method.methodDefinition.Module.TypeSystem.Object;
                            block.insert(n++, Instruction.Create(OpCodes.Newarr, objectType));
                            block.insert(n++, create(OpCodes.Stloc, new Operand(Operand.Type.TempObjArray)));

                            for (int j = mparams.Count - 1; j >= 0; j--)
                            {
                                var argType = mparams[j];
                                if (argType.IsValueType)
                                {
                                    block.insert(n++, Instruction.Create(OpCodes.Box, argType));
                                }
                                block.insert(n++, create(OpCodes.Stloc, new Operand(Operand.Type.TempObj)));
                                block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObjArray)));
                                block.insert(n++, Instruction.Create(OpCodes.Ldc_I4, j));
                                block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObj)));
                                block.insert(n++, Instruction.Create(OpCodes.Stelem_Ref));
                            }
                        }

                        // Push delegate instance
                        insertLoadThis(block, n++);
                        block.insert(n++, Instruction.Create(OpCodes.Ldc_I4, newMethodInfo.delegateIndex));
                        insertCallOurMethod(block, n++, "rtGetDelegateInstance");
                        block.insert(n++, create(OpCodes.Castclass, new Operand(Operand.Type.ReflectionType, newMethodInfo.delegateType)));

                        // Push all popped args
                        if (mparams.Count > 0)
                        {
                            for (int j = 0; j < mparams.Count; j++)
                            {
                                block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObjArray)));
                                block.insert(n++, Instruction.Create(OpCodes.Ldc_I4, j));
                                block.insert(n++, Instruction.Create(OpCodes.Ldelem_Ref));
                                var argType = mparams[j];
                                if (argType.IsValueType)
                                {
                                    block.insert(n++, Instruction.Create(OpCodes.Unbox_Any, argType));
                                }
                                else
                                {
                                    // Don't cast it to its correct type. This will sometimes cause
                                    // an exception in some EF obfuscated assembly since we'll be
                                    // trying to cast a System.Reflection.AssemblyName type to some
                                    // other type.
                                    // block.insert(n++, Instruction.Create(OpCodes.Castclass, argType));
                                }
                            }
                        }

                        insertLoadThis(block, n++);
                        block.insert(n++, create(OpCodes.Call, new Operand(Operand.Type.NewMethod, method.methodBase)));
                        i = n - 1;
                        continue;
                    }
                }
            }
        }
Example #7
0
        void update(Block block, NewMethodInfo currentMethodInfo)
        {
            var instrs = block.Instructions;
            for (int i = 0; i < instrs.Count; i++) {
                var instr = instrs[i];
                if (instr.OpCode == OpCodes.Newobj) {
                    var ctor = (MethodReference)instr.Operand;
                    if (MemberReferenceHelper.verifyType(ctor.DeclaringType, "mscorlib", "System.Diagnostics.StackTrace")) {
                        insertLoadThis(block, i + 1);
                        insertCallOurMethod(block, i + 2, "static_rtFixStackTrace");
                        i += 2;
                        continue;
                    }
                    else if (MemberReferenceHelper.verifyType(ctor.DeclaringType, "mscorlib", "System.Diagnostics.StackFrame")) {
                        insertLoadThis(block, i + 1);
                        insertCallOurMethod(block, i + 2, "static_rtFixStackFrame");
                        i += 2;
                        continue;
                    }
                }

                if (instr.OpCode == OpCodes.Call || instr.OpCode == OpCodes.Callvirt) {
                    var calledMethod = (MethodReference)instr.Operand;
                    if (DotNetUtils.isSameAssembly(calledMethod.DeclaringType, "mscorlib")) {
                        if (calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetAssembly(System.Type)") {
                            block.replace(i, 1, Instruction.Create(OpCodes.Nop));
                            insertLoadThis(block, i + 1);
                            insertCallOurMethod(block, i + 2, "static_rtGetAssembly_TypeArg");
                            i += 2;
                            continue;
                        }
                        else if (calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetCallingAssembly()" ||
                                calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetEntryAssembly()" ||
                                calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetExecutingAssembly()") {
                            block.replace(i, 1, Instruction.Create(OpCodes.Nop));
                            insertLoadThis(block, i + 1);
                            block.insert(i + 2, Instruction.Create(OpCodes.Ldc_I4, currentMethodInfo.delegateIndex));
                            insertCallOurMethod(block, i + 3, "rtGetAssembly");
                            i += 3;
                            continue;
                        }
                    }

                    var method = Resolver.getMethod((MethodReference)instr.Operand);
                    if (method != null) {
                        createMethod(method.methodBase);
                        var newMethodInfo = realMethodToNewMethod[method.methodBase];

                        block.replace(i, 1, Instruction.Create(OpCodes.Nop));
                        int n = i + 1;

                        // Pop all pushed args to a temp array
                        var mparams = getParameters(method.methodDefinition);
                        if (mparams.Count > 0) {
                            block.insert(n++, Instruction.Create(OpCodes.Ldc_I4, mparams.Count));
                            var objectType = method.methodDefinition.Module.TypeSystem.Object;
                            block.insert(n++, Instruction.Create(OpCodes.Newarr, objectType));
                            block.insert(n++, create(OpCodes.Stloc, new Operand(Operand.Type.TempObjArray)));

                            for (int j = mparams.Count - 1; j >= 0; j--) {
                                var argType = mparams[j];
                                if (argType.IsValueType)
                                    block.insert(n++, Instruction.Create(OpCodes.Box, argType));
                                block.insert(n++, create(OpCodes.Stloc, new Operand(Operand.Type.TempObj)));
                                block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObjArray)));
                                block.insert(n++, Instruction.Create(OpCodes.Ldc_I4, j));
                                block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObj)));
                                block.insert(n++, Instruction.Create(OpCodes.Stelem_Ref));
                            }
                        }

                        // Push delegate instance
                        insertLoadThis(block, n++);
                        block.insert(n++, Instruction.Create(OpCodes.Ldc_I4, newMethodInfo.delegateIndex));
                        insertCallOurMethod(block, n++, "rtGetDelegateInstance");
                        block.insert(n++, create(OpCodes.Castclass, new Operand(Operand.Type.ReflectionType, newMethodInfo.delegateType)));

                        // Push all popped args
                        if (mparams.Count > 0) {
                            for (int j = 0; j < mparams.Count; j++) {
                                block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObjArray)));
                                block.insert(n++, Instruction.Create(OpCodes.Ldc_I4, j));
                                block.insert(n++, Instruction.Create(OpCodes.Ldelem_Ref));
                                var argType = mparams[j];
                                if (argType.IsValueType)
                                    block.insert(n++, Instruction.Create(OpCodes.Unbox_Any, argType));
                                else {
                                    // Don't cast it to its correct type. This will sometimes cause
                                    // an exception in some EF obfuscated assembly since we'll be
                                    // trying to cast a System.Reflection.AssemblyName type to some
                                    // other type.
                                    // block.insert(n++, Instruction.Create(OpCodes.Castclass, argType));
                                }
                            }
                        }

                        insertLoadThis(block, n++);
                        block.insert(n++, create(OpCodes.Call, new Operand(Operand.Type.NewMethod, method.methodBase)));
                        i = n - 1;
                        continue;
                    }
                }
            }
        }