Ejemplo n.º 1
0
        TypeDef GetKeyAttr(RPContext ctx)
        {
            if (keyAttrs == null)
            {
                keyAttrs = new Tuple <TypeDef, Func <int, int> > [0x10];
            }

            int index = ctx.Random.NextInt32(keyAttrs.Length);

            if (keyAttrs[index] == null)
            {
                TypeDef rtType       = ctx.Context.Registry.GetService <IRuntimeService>().GetRuntimeType("DotProtect.Runtime.RefProxyKey");
                TypeDef injectedAttr = InjectHelper.Inject(rtType, ctx.Module);
                injectedAttr.Name      = ctx.Name.RandomName();
                injectedAttr.Namespace = string.Empty;

                Expression expression, inverse;
                var        var    = new Variable("{VAR}");
                var        result = new Variable("{RESULT}");

                ctx.DynCipher.GenerateExpressionPair(
                    ctx.Random,
                    new VariableExpression {
                    Variable = var
                }, new VariableExpression {
                    Variable = result
                },
                    ctx.Depth, out expression, out inverse);

                var expCompiled = new DMCodeGen(typeof(int), new[] { Tuple.Create("{VAR}", typeof(int)) })
                                  .GenerateCIL(expression)
                                  .Compile <Func <int, int> >();

                MethodDef ctor = injectedAttr.FindMethod(".ctor");
                MutationHelper.ReplacePlaceholder(ctor, arg => {
                    var invCompiled = new List <Instruction>();
                    new CodeGen(arg, ctor, invCompiled).GenerateCIL(inverse);
                    return(invCompiled.ToArray());
                });
                keyAttrs[index] = Tuple.Create(injectedAttr, expCompiled);

                ctx.Module.AddAsNonNestedType(injectedAttr);

                foreach (IDnlibDef def in injectedAttr.FindDefinitions())
                {
                    if (def.Name == "GetHashCode")
                    {
                        ctx.Name.MarkHelper(def, ctx.Marker, ctx.Protection);
                        ((MethodDef)def).Access = MethodAttributes.Public;
                    }
                    else
                    {
                        ctx.Name.MarkHelper(def, ctx.Marker, ctx.Protection);
                    }
                }
            }
            return(keyAttrs[index].Item1);
        }
Ejemplo n.º 2
0
        public Instruction[] EmitDecode(MethodDef init, RPContext ctx, Instruction[] arg)
        {
            Tuple <MethodDef, Func <int, int> > key = GetKey(ctx, init);

            var repl = new List <Instruction>();

            repl.AddRange(arg);
            repl.Add(Instruction.Create(OpCodes.Call, key.Item1));
            return(repl.ToArray());
        }
Ejemplo n.º 3
0
        static ITypeDefOrRef Import(RPContext ctx, TypeDef typeDef)
        {
            ITypeDefOrRef retTypeRef = new Importer(ctx.Module, ImporterOptions.TryToUseTypeDefs).Import(typeDef);

            if (typeDef.Module != ctx.Module && ctx.Context.Modules.Contains((ModuleDefMD)typeDef.Module))
            {
                ctx.Name.AddReference(typeDef, new TypeRefReference((TypeRef)retTypeRef, typeDef));
            }
            return(retTypeRef);
        }
Ejemplo n.º 4
0
        public Instruction[] EmitDecode(MethodDef init, RPContext ctx, Instruction[] arg)
        {
            Tuple <Expression, Func <int, int> > key = GetKey(ctx, init);

            var invCompiled = new List <Instruction>();

            new CodeGen(arg, ctx.Method, invCompiled).GenerateCIL(key.Item1);
            init.Body.MaxStack += (ushort)ctx.Depth;
            return(invCompiled.ToArray());
        }
Ejemplo n.º 5
0
        Tuple <Expression, Func <int, int> > GetKey(RPContext ctx, MethodDef init)
        {
            Tuple <Expression, Func <int, int> > ret;

            if (!keys.TryGetValue(init, out ret))
            {
                Func <int, int> keyFunc;
                Expression      inverse;
                Compile(ctx, init.Body, out keyFunc, out inverse);
                keys[init] = ret = Tuple.Create(inverse, keyFunc);
            }
            return(ret);
        }
Ejemplo n.º 6
0
        Tuple <MethodDef, Func <int, int> > GetKey(RPContext ctx, MethodDef init)
        {
            Tuple <MethodDef, Func <int, int> > ret;

            if (!keys.TryGetValue(init, out ret))
            {
                Func <int, int> keyFunc;
                MethodDef       native;
                Compile(ctx, out keyFunc, out native);
                keys[init] = ret = Tuple.Create(native, keyFunc);
            }
            return(ret);
        }
Ejemplo n.º 7
0
        static int?TraceBeginning(RPContext ctx, int index, int argCount)
        {
            if (ctx.BranchTargets.Contains(ctx.Body.Instructions[index]))
            {
                return(null);
            }

            int currentStack = argCount;
            int currentIndex = index;

            while (currentStack > 0)
            {
                currentIndex--;
                Instruction currentInstr = ctx.Body.Instructions[currentIndex];

                // Disrupt stack analysis :/ Used by array initializer
                if (currentInstr.OpCode == OpCodes.Pop || currentInstr.OpCode == OpCodes.Dup)
                {
                    return(null);
                }

                // No branch instr.
                switch (currentInstr.OpCode.FlowControl)
                {
                case FlowControl.Call:
                case FlowControl.Break:
                case FlowControl.Meta:
                case FlowControl.Next:
                    break;

                default:
                    return(null);
                }

                int push, pop;
                currentInstr.CalculateStackUsage(out push, out pop);
                currentStack += pop;
                currentStack -= push;

                // No branch target
                if (ctx.BranchTargets.Contains(currentInstr) && currentStack != 0)
                {
                    return(null);
                }
            }
            if (currentStack < 0)
            {
                return(null);
            }
            return(currentIndex);
        }
Ejemplo n.º 8
0
        InitMethodDesc GetInitMethod(RPContext ctx, IRPEncoding encoding)
        {
            InitMethodDesc[] initDescs;
            if (!inits.TryGetValue(encoding, out initDescs))
            {
                inits[encoding] = initDescs = new InitMethodDesc[ctx.InitCount];
            }

            int index = ctx.Random.NextInt32(initDescs.Length);

            if (initDescs[index] == null)
            {
                TypeDef   rtType         = ctx.Context.Registry.GetService <IRuntimeService>().GetRuntimeType("DotProtect.Runtime.RefProxyStrong");
                MethodDef injectedMethod = InjectHelper.Inject(rtType.FindMethod("Initialize"), ctx.Module);
                ctx.Module.GlobalType.Methods.Add(injectedMethod);

                injectedMethod.Access = MethodAttributes.PrivateScope;
                injectedMethod.Name   = ctx.Name.RandomName();
                ctx.Name.SetCanRename(injectedMethod, false);
                ctx.Marker.Mark(injectedMethod, ctx.Protection);

                var desc = new InitMethodDesc {
                    Method = injectedMethod
                };

                // Field name has five bytes, each bytes has different order & meaning
                int[] order = Enumerable.Range(0, 5).ToArray();
                ctx.Random.Shuffle(order);
                desc.OpCodeIndex = order[4];

                desc.TokenNameOrder = new int[4];
                Array.Copy(order, 0, desc.TokenNameOrder, 0, 4);
                desc.TokenByteOrder = Enumerable.Range(0, 4).Select(x => x * 8).ToArray();
                ctx.Random.Shuffle(desc.TokenByteOrder);

                var keyInjection = new int[9];
                Array.Copy(desc.TokenNameOrder, 0, keyInjection, 0, 4);
                Array.Copy(desc.TokenByteOrder, 0, keyInjection, 4, 4);
                keyInjection[8] = desc.OpCodeIndex;
                MutationHelper.InjectKeys(injectedMethod, Enumerable.Range(0, 9).ToArray(), keyInjection);

                // Encoding
                MutationHelper.ReplacePlaceholder(injectedMethod, arg => { return(encoding.EmitDecode(injectedMethod, ctx, arg)); });
                desc.Encoding = encoding;

                initDescs[index] = desc;
            }
            return(initDescs[index]);
        }
Ejemplo n.º 9
0
        void ProcessInvoke(RPContext ctx, int instrIndex, int argBeginIndex)
        {
            Instruction instr  = ctx.Body.Instructions[instrIndex];
            var         target = (IMethod)instr.Operand;

            MethodSig sig          = CreateProxySignature(ctx, target, instr.OpCode.Code == Code.Newobj);
            TypeDef   delegateType = GetDelegateType(ctx, sig);

            Tuple <Code, IMethod, IRPEncoding> key = Tuple.Create(instr.OpCode.Code, target, ctx.EncodingHandler);
            Tuple <FieldDef, MethodDef>        proxy;

            if (!fields.TryGetValue(key, out proxy))
            {
                // Create proxy field
                proxy       = new Tuple <FieldDef, MethodDef>(CreateField(ctx, delegateType), null);
                fields[key] = proxy;
            }

            // Insert field load & replace instruction
            if (argBeginIndex == instrIndex)
            {
                ctx.Body.Instructions.Insert(instrIndex + 1,
                                             new Instruction(OpCodes.Call, delegateType.FindMethod("Invoke")));
                instr.OpCode  = OpCodes.Ldsfld;
                instr.Operand = proxy.Item1;
            }
            else
            {
                Instruction argBegin = ctx.Body.Instructions[argBeginIndex];
                ctx.Body.Instructions.Insert(argBeginIndex + 1,
                                             new Instruction(argBegin.OpCode, argBegin.Operand));
                argBegin.OpCode  = OpCodes.Ldsfld;
                argBegin.Operand = proxy.Item1;

                instr.OpCode  = OpCodes.Call;
                instr.Operand = delegateType.FindMethod("Invoke");
            }

            var targetDef = target.ResolveMethodDef();

            if (targetDef != null)
            {
                ctx.Context.Annotations.Set(targetDef, ReferenceProxyProtection.Targeted, ReferenceProxyProtection.Targeted);
            }
        }
Ejemplo n.º 10
0
        void Compile(RPContext ctx, out Func <int, int> expCompiled, out MethodDef native)
        {
            var var    = new Variable("{VAR}");
            var result = new Variable("{RESULT}");

            CorLibTypeSig int32 = ctx.Module.CorLibTypes.Int32;

            native = new MethodDefUser(ctx.Context.Registry.GetService <INameService>().RandomName(), MethodSig.CreateStatic(int32, int32), MethodAttributes.PinvokeImpl | MethodAttributes.PrivateScope | MethodAttributes.Static);
            native.ImplAttributes = MethodImplAttributes.Native | MethodImplAttributes.Unmanaged | MethodImplAttributes.PreserveSig;
            ctx.Module.GlobalType.Methods.Add(native);

            ctx.Context.Registry.GetService <IMarkerService>().Mark(native, ctx.Protection);
            ctx.Context.Registry.GetService <INameService>().SetCanRename(native, false);

            x86Register?reg;
            var         codeGen = new x86CodeGen();
            Expression  expression, inverse;

            do
            {
                ctx.DynCipher.GenerateExpressionPair(
                    ctx.Random,
                    new VariableExpression {
                    Variable = var
                }, new VariableExpression {
                    Variable = result
                },
                    ctx.Depth, out expression, out inverse);

                reg = codeGen.GenerateX86(inverse, (v, r) => { return(new[] { x86Instruction.Create(x86OpCode.POP, new x86RegisterOperand(r)) }); });
            } while (reg == null);

            byte[] code = CodeGenUtils.AssembleCode(codeGen, reg.Value);

            expCompiled = new DMCodeGen(typeof(int), new[] { Tuple.Create("{VAR}", typeof(int)) })
                          .GenerateCIL(expression)
                          .Compile <Func <int, int> >();

            nativeCodes.Add(Tuple.Create(native, code, (MethodBody)null));
            if (!addedHandler)
            {
                ctx.Context.CurrentModuleWriterListener.OnWriterEvent += InjectNativeCode;
                addedHandler = true;
            }
        }
Ejemplo n.º 11
0
        static RPContext ParseParameters(ModuleDef module, DotProtectContext context, ProtectionParameters parameters, RPStore store)
        {
            var ret = new RPContext();

            ret.Depth     = parameters.GetParameter(context, module, "depth", 3);
            ret.InitCount = parameters.GetParameter(context, module, "initCount", 0x10);

            ret.Random    = store.random;
            ret.Module    = module;
            ret.Context   = context;
            ret.Marker    = context.Registry.GetService <IMarkerService>();
            ret.DynCipher = context.Registry.GetService <IDynCipherService>();
            ret.Name      = context.Registry.GetService <INameService>();

            ret.Delegates = store.delegates;

            return(ret);
        }
Ejemplo n.º 12
0
        public Instruction[] EmitDecode(MethodDef init, RPContext ctx, Instruction[] arg)
        {
            Tuple <int, int> key = GetKey(ctx.Random, init);
            var ret = new List <Instruction>();

            if (ctx.Random.NextBoolean())
            {
                ret.Add(Instruction.Create(OpCodes.Ldc_I4, key.Item1));
                ret.AddRange(arg);
            }
            else
            {
                ret.AddRange(arg);
                ret.Add(Instruction.Create(OpCodes.Ldc_I4, key.Item1));
            }
            ret.Add(Instruction.Create(OpCodes.Mul));
            return(ret.ToArray());
        }
Ejemplo n.º 13
0
        protected static MethodSig CreateProxySignature(RPContext ctx, IMethod method, bool newObj)
        {
            ModuleDef module = ctx.Module;

            if (newObj)
            {
                Debug.Assert(method.MethodSig.HasThis);
                Debug.Assert(method.Name == ".ctor");
                TypeSig[] paramTypes = method.MethodSig.Params.Select(type => {
                    if (ctx.TypeErasure && type.IsClassSig && method.MethodSig.HasThis)
                    {
                        return(module.CorLibTypes.Object);
                    }
                    return(type);
                }).ToArray();

                TypeSig retType;
                if (ctx.TypeErasure)                 // newobj will not be used with value types
                {
                    retType = module.CorLibTypes.Object;
                }
                else
                {
                    TypeDef declType = method.DeclaringType.ResolveTypeDefThrow();
                    retType = Import(ctx, declType).ToTypeSig();
                }
                return(MethodSig.CreateStatic(retType, paramTypes));
            }
            else
            {
                IEnumerable <TypeSig> paramTypes = method.MethodSig.Params.Select(type => {
                    if (ctx.TypeErasure && type.IsClassSig && method.MethodSig.HasThis)
                    {
                        return(module.CorLibTypes.Object);
                    }
                    return(type);
                });
                if (method.MethodSig.HasThis && !method.MethodSig.ExplicitThis)
                {
                    TypeDef declType = method.DeclaringType.ResolveTypeDefThrow();
                    if (ctx.TypeErasure && !declType.IsValueType)
                    {
                        paramTypes = new[] { module.CorLibTypes.Object }
                    }
Ejemplo n.º 14
0
        void Compile(RPContext ctx, CilBody body, out Func <int, int> expCompiled, out Expression inverse)
        {
            var var    = new Variable("{VAR}");
            var result = new Variable("{RESULT}");

            Expression expression;

            ctx.DynCipher.GenerateExpressionPair(
                ctx.Random,
                new VariableExpression {
                Variable = var
            }, new VariableExpression {
                Variable = result
            },
                ctx.Depth, out expression, out inverse);

            expCompiled = new DMCodeGen(typeof(int), new[] { Tuple.Create("{VAR}", typeof(int)) })
                          .GenerateCIL(expression)
                          .Compile <Func <int, int> >();
        }
Ejemplo n.º 15
0
        FieldDef CreateField(RPContext ctx, TypeDef delegateType)
        {
            // Details will be filled in during metadata writing
            TypeDef randomType;

            do
            {
                randomType = ctx.Module.Types[ctx.Random.NextInt32(ctx.Module.Types.Count)];
            } while (randomType.HasGenericParameters || randomType.IsGlobalModuleType || randomType.IsDelegate());

            TypeSig fieldType = new CModOptSig(randomType, delegateType.ToTypeSig());

            var field = new FieldDefUser("", new FieldSig(fieldType), FieldAttributes.Static | FieldAttributes.Assembly);

            field.CustomAttributes.Add(new CustomAttribute(GetKeyAttr(ctx).FindInstanceConstructors().First()));
            delegateType.Fields.Add(field);

            ctx.Marker.Mark(field, ctx.Protection);
            ctx.Name.SetCanRename(field, false);

            return(field);
        }
Ejemplo n.º 16
0
        public override void Finalize(RPContext ctx)
        {
            foreach (var field in fields)
            {
                InitMethodDesc init = GetInitMethod(ctx, field.Key.Item3);
                byte           opKey;
                do
                {
                    // No zero bytes
                    opKey = ctx.Random.NextByte();
                } while (opKey == (byte)field.Key.Item1);

                TypeDef delegateType = field.Value.Item1.DeclaringType;

                MethodDef cctor = delegateType.FindOrCreateStaticConstructor();
                cctor.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Call, init.Method));
                cctor.Body.Instructions.Insert(0, Instruction.CreateLdcI4(opKey));
                cctor.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Ldtoken, field.Value.Item1));

                fieldDescs.Add(new FieldDesc {
                    Field    = field.Value.Item1,
                    OpCode   = field.Key.Item1,
                    Method   = field.Key.Item2,
                    OpKey    = opKey,
                    InitDesc = init
                });
            }

            foreach (TypeDef delegateType in ctx.Delegates.Values)
            {
                MethodDef cctor = delegateType.FindOrCreateStaticConstructor();
                ctx.Marker.Mark(cctor, ctx.Protection);
                ctx.Name.SetCanRename(cctor, false);
            }

            ctx.Context.CurrentModuleWriterOptions.MetaDataOptions.Flags |= MetaDataFlags.PreserveExtraSignatureData;
            ctx.Context.CurrentModuleWriterListener.OnWriterEvent        += EncodeField;
            encodeCtx = ctx;
        }
Ejemplo n.º 17
0
        MethodDef CreateBridge(RPContext ctx, TypeDef delegateType, FieldDef field, MethodSig sig)
        {
            var method = new MethodDefUser(ctx.Name.RandomName(), sig);

            method.Attributes     = MethodAttributes.PrivateScope | MethodAttributes.Static;
            method.ImplAttributes = MethodImplAttributes.Managed | MethodImplAttributes.IL;

            method.Body = new CilBody();
            method.Body.Instructions.Add(Instruction.Create(OpCodes.Ldsfld, field));
            for (int i = 0; i < method.Parameters.Count; i++)
            {
                method.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg, method.Parameters[i]));
            }
            method.Body.Instructions.Add(Instruction.Create(OpCodes.Call, delegateType.FindMethod("Invoke")));
            method.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));

            delegateType.Methods.Add(method);

            ctx.Context.Registry.GetService <IMarkerService>().Mark(method, ctx.Protection);
            ctx.Name.SetCanRename(method, false);

            return(method);
        }
Ejemplo n.º 18
0
        RPContext ParseParameters(MethodDef method, DotProtectContext context, ProtectionParameters parameters, RPStore store)
        {
            var ret = new RPContext();

            ret.Mode         = parameters.GetParameter(context, method, "mode", Mode.Mild);
            ret.Encoding     = parameters.GetParameter(context, method, "encoding", EncodingType.Normal);
            ret.InternalAlso = parameters.GetParameter(context, method, "internal", false);
            ret.TypeErasure  = parameters.GetParameter(context, method, "typeErasure", false);
            ret.Depth        = parameters.GetParameter(context, method, "depth", 3);

            ret.Module        = method.Module;
            ret.Method        = method;
            ret.Body          = method.Body;
            ret.BranchTargets = new HashSet <Instruction>(
                method.Body.Instructions
                .Select(instr => instr.Operand as Instruction)
                .Concat(method.Body.Instructions
                        .Where(instr => instr.Operand is Instruction[])
                        .SelectMany(instr => (Instruction[])instr.Operand))
                .Where(target => target != null));

            ret.Protection = (ReferenceProxyProtection)Parent;
            ret.Random     = store.random;
            ret.Context    = context;
            ret.Marker     = context.Registry.GetService <IMarkerService>();
            ret.DynCipher  = context.Registry.GetService <IDynCipherService>();
            ret.Name       = context.Registry.GetService <INameService>();

            ret.Delegates = store.delegates;

            switch (ret.Mode)
            {
            case Mode.Mild:
                ret.ModeHandler = store.mild ?? (store.mild = new MildMode());
                break;

            case Mode.Strong:
                ret.ModeHandler = store.strong ?? (store.strong = new StrongMode());
                break;

            default:
                throw new UnreachableException();
            }

            switch (ret.Encoding)
            {
            case EncodingType.Normal:
                ret.EncodingHandler = store.normal ?? (store.normal = new NormalEncoding());
                break;

            case EncodingType.Expression:
                ret.EncodingHandler = store.expression ?? (store.expression = new ExpressionEncoding());
                break;

            case EncodingType.x86:
                ret.EncodingHandler = store.x86 ?? (store.x86 = new x86Encoding());

                if ((context.CurrentModule.Cor20HeaderFlags & ComImageFlags.ILOnly) != 0)
                {
                    context.CurrentModuleWriterOptions.Cor20HeaderOptions.Flags &= ~ComImageFlags.ILOnly;
                }
                break;

            default:
                throw new UnreachableException();
            }

            return(ret);
        }
Ejemplo n.º 19
0
        void ProcessMethod(RPContext ctx)
        {
            for (int i = 0; i < ctx.Body.Instructions.Count; i++)
            {
                Instruction instr = ctx.Body.Instructions[i];
                if (instr.OpCode.Code == Code.Call || instr.OpCode.Code == Code.Callvirt || instr.OpCode.Code == Code.Newobj)
                {
                    var operand = (IMethod)instr.Operand;
                    var def     = operand.ResolveMethodDef();

                    if (def != null && ctx.Context.Annotations.Get <object>(def, ReferenceProxyProtection.TargetExcluded) != null)
                    {
                        return;
                    }

                    // Call constructor
                    if (instr.OpCode.Code != Code.Newobj && operand.Name == ".ctor")
                    {
                        continue;
                    }
                    // Internal reference option
                    if (operand is MethodDef && !ctx.InternalAlso)
                    {
                        continue;
                    }
                    // No generic methods
                    if (operand is MethodSpec)
                    {
                        continue;
                    }
                    // No generic types / array types
                    if (operand.DeclaringType is TypeSpec)
                    {
                        continue;
                    }
                    // No varargs
                    if (operand.MethodSig.ParamsAfterSentinel != null &&
                        operand.MethodSig.ParamsAfterSentinel.Count > 0)
                    {
                        continue;
                    }
                    TypeDef declType = operand.DeclaringType.ResolveTypeDefThrow();
                    // No delegates
                    if (declType.IsDelegate())
                    {
                        continue;
                    }
                    // No instance value type methods
                    if (declType.IsValueType && operand.MethodSig.HasThis)
                    {
                        continue;
                    }
                    // No prefixed call
                    if (i - 1 >= 0 && ctx.Body.Instructions[i - 1].OpCode.OpCodeType == OpCodeType.Prefix)
                    {
                        continue;
                    }

                    ctx.ModeHandler.ProcessCall(ctx, i);
                }
            }
        }
Ejemplo n.º 20
0
        public int Encode(MethodDef init, RPContext ctx, int value)
        {
            Tuple <MethodDef, Func <int, int> > key = GetKey(ctx, init);

            return(key.Item2(value));
        }
Ejemplo n.º 21
0
        void ProcessBridge(RPContext ctx, int instrIndex)
        {
            Instruction instr  = ctx.Body.Instructions[instrIndex];
            var         target = (IMethod)instr.Operand;

            TypeDef declType = target.DeclaringType.ResolveTypeDefThrow();

            if (!declType.Module.IsILOnly)             // Reflection doesn't like mixed mode modules.
            {
                return;
            }
            if (declType.IsGlobalModuleType)             // Reflection doesn't like global methods too.
            {
                return;
            }

            Tuple <Code, IMethod, IRPEncoding> key = Tuple.Create(instr.OpCode.Code, target, ctx.EncodingHandler);
            Tuple <FieldDef, MethodDef>        proxy;

            if (fields.TryGetValue(key, out proxy))
            {
                if (proxy.Item2 != null)
                {
                    instr.OpCode  = OpCodes.Call;
                    instr.Operand = proxy.Item2;
                    return;
                }
            }
            else
            {
                proxy = new Tuple <FieldDef, MethodDef>(null, null);
            }

            MethodSig sig          = CreateProxySignature(ctx, target, instr.OpCode.Code == Code.Newobj);
            TypeDef   delegateType = GetDelegateType(ctx, sig);

            // Create proxy field
            if (proxy.Item1 == null)
            {
                proxy = new Tuple <FieldDef, MethodDef>(
                    CreateField(ctx, delegateType),
                    proxy.Item2);
            }

            // Create proxy bridge
            Debug.Assert(proxy.Item2 == null);

            proxy = new Tuple <FieldDef, MethodDef>(
                proxy.Item1,
                CreateBridge(ctx, delegateType, proxy.Item1, sig));

            fields[key] = proxy;

            // Replace instruction
            instr.OpCode  = OpCodes.Call;
            instr.Operand = proxy.Item2;

            var targetDef = target.ResolveMethodDef();

            if (targetDef != null)
            {
                ctx.Context.Annotations.Set(targetDef, ReferenceProxyProtection.Targeted, ReferenceProxyProtection.Targeted);
            }
        }
Ejemplo n.º 22
0
 public override void Finalize(RPContext ctx)
 {
 }
Ejemplo n.º 23
0
        public override void ProcessCall(RPContext ctx, int instrIndex)
        {
            Instruction invoke = ctx.Body.Instructions[instrIndex];
            var         target = (IMethod)invoke.Operand;

            // Value type proxy is not supported in mild mode.
            if (target.DeclaringType.ResolveTypeDefThrow().IsValueType)
            {
                return;
            }
            // Skipping visibility is not supported in mild mode.
            if (!target.ResolveThrow().IsPublic&& !target.ResolveThrow().IsAssembly)
            {
                return;
            }

            Tuple <Code, TypeDef, IMethod> key = Tuple.Create(invoke.OpCode.Code, ctx.Method.DeclaringType, target);
            MethodDef proxy;

            if (!proxies.TryGetValue(key, out proxy))
            {
                MethodSig sig = CreateProxySignature(ctx, target, invoke.OpCode.Code == Code.Newobj);

                proxy                = new MethodDefUser(ctx.Name.RandomName(), sig);
                proxy.Attributes     = MethodAttributes.PrivateScope | MethodAttributes.Static;
                proxy.ImplAttributes = MethodImplAttributes.Managed | MethodImplAttributes.IL;
                ctx.Method.DeclaringType.Methods.Add(proxy);

                // Fix peverify --- Non-virtual call to virtual methods must be done on this pointer
                if (invoke.OpCode.Code == Code.Call && target.ResolveThrow().IsVirtual)
                {
                    proxy.IsStatic = false;
                    sig.HasThis    = true;
                    sig.Params.RemoveAt(0);
                }

                ctx.Marker.Mark(proxy, ctx.Protection);
                ctx.Name.Analyze(proxy);
                ctx.Name.SetCanRename(proxy, false);

                proxy.Body = new CilBody();
                for (int i = 0; i < proxy.Parameters.Count; i++)
                {
                    proxy.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg, proxy.Parameters[i]));
                }
                proxy.Body.Instructions.Add(Instruction.Create(invoke.OpCode, target));
                proxy.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));

                proxies[key] = proxy;
            }

            invoke.OpCode = OpCodes.Call;
            if (ctx.Method.DeclaringType.HasGenericParameters)
            {
                var genArgs = new GenericVar[ctx.Method.DeclaringType.GenericParameters.Count];
                for (int i = 0; i < genArgs.Length; i++)
                {
                    genArgs[i] = new GenericVar(i);
                }

                invoke.Operand = new MemberRefUser(
                    ctx.Module,
                    proxy.Name,
                    proxy.MethodSig,
                    new GenericInstSig((ClassOrValueTypeSig)ctx.Method.DeclaringType.ToTypeSig(), genArgs).ToTypeDefOrRef());
            }
            else
            {
                invoke.Operand = proxy;
            }

            var targetDef = target.ResolveMethodDef();

            if (targetDef != null)
            {
                ctx.Context.Annotations.Set(targetDef, ReferenceProxyProtection.Targeted, ReferenceProxyProtection.Targeted);
            }
        }
Ejemplo n.º 24
0
 public abstract void Finalize(RPContext ctx);
Ejemplo n.º 25
0
        public int Encode(MethodDef init, RPContext ctx, int value)
        {
            Tuple <int, int> key = GetKey(ctx.Random, init);

            return(value * key.Item2);
        }
Ejemplo n.º 26
0
 public abstract void ProcessCall(RPContext ctx, int instrIndex);