Beispiel #1
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);
		}
Beispiel #2
0
        protected static TypeDef GetDelegateType(RPContext ctx, MethodSig sig)
        {
            TypeDef ret;
            if (ctx.Delegates.TryGetValue(sig, out ret))
                return ret;

            ret = new TypeDefUser(ctx.Name.ObfuscateName(ctx.Method.DeclaringType.Namespace, RenameMode.Unicode), ctx.Name.RandomName(), ctx.Module.CorLibTypes.GetTypeRef("System", "MulticastDelegate"));
            ret.Attributes = TypeAttributes.NotPublic | TypeAttributes.Sealed;

            var ctor = new MethodDefUser(".ctor", MethodSig.CreateInstance(ctx.Module.CorLibTypes.Void, ctx.Module.CorLibTypes.Object, ctx.Module.CorLibTypes.IntPtr));
            ctor.Attributes = MethodAttributes.Assembly | MethodAttributes.HideBySig | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName;
            ctor.ImplAttributes = MethodImplAttributes.Runtime;
            ret.Methods.Add(ctor);

            var invoke = new MethodDefUser("Invoke", sig.Clone());
            invoke.MethodSig.HasThis = true;
            invoke.Attributes = MethodAttributes.Assembly | MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.NewSlot;
            invoke.ImplAttributes = MethodImplAttributes.Runtime;
            ret.Methods.Add(invoke);

            ctx.Module.Types.Add(ret);

            foreach (IDnlibDef def in ret.FindDefinitions()) {
                ctx.Marker.Mark(def);
                ctx.Name.SetCanRename(def, false);
            }

            ctx.Delegates[sig] = ret;
            return ret;
        }
Beispiel #3
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();
		}
		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();
		}
Beispiel #5
0
        private 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("Confuser.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);
                        ((MethodDef)def).Access = MethodAttributes.Public;
                    }
                    else
                    {
                        ctx.Name.MarkHelper(def, ctx.Marker);
                    }
                }
            }
            return(keyAttrs[index].Item1);
        }
Beispiel #6
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;
        }
 Tuple <Expression, Func <int, int> > GetKey(RPContext ctx, MethodDef init)
 {
     if (!keys.TryGetValue(init, out var ret))
     {
         Compile(ctx, init.Body, out var keyFunc, out var inverse);
         keys[init] = ret = Tuple.Create(inverse, keyFunc);
     }
     return(ret);
 }
Beispiel #8
0
 Tuple <MethodDef, Func <int, int> > GetKey(RPContext ctx, MethodDef init)
 {
     if (!keys.TryGetValue(init, out var ret))
     {
         Compile(ctx, out var keyFunc, out var native);
         keys[init] = ret = Tuple.Create(native, keyFunc);
     }
     return(ret);
 }
        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());
        }
        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());
        }
		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;
		}
Beispiel #12
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;
		}
        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);
        }
        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;
                    // 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)
                    {
                        return;
                    }
                    // No prefixed call
                    if (i - 1 >= 0 && ctx.Body.Instructions[i - 1].OpCode.OpCodeType == OpCodeType.Prefix)
                    {
                        continue;
                    }

                    ctx.ModeHandler.ProcessCall(ctx, i);
                }
            }
        }
Beispiel #15
0
 private 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;
 }
        private 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);
        }
Beispiel #17
0
        static int?TraceBeginning(RPContext ctx, int index, int argCount)
        {
            if (ctx.BranchTargets.Contains(ctx.Body.Instructions[index]))
            {
                return(null);
            }

            var currentStack = argCount;
            var currentIndex = index;

            while (currentStack > 0)
            {
                currentIndex--;
                var 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);
                }

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

                // No branch target
                if (ctx.BranchTargets.Contains(currentInstr) && currentStack != 0)
                {
                    return(null);
                }
            }
            if (currentStack < 0)
            {
                return(null);
            }

            return(currentIndex);
        }
Beispiel #18
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();
		}
		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>>();
		}
Beispiel #20
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("Confuser.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]);
        }
Beispiel #21
0
        void Compile(RPContext ctx, out Func <int, int> expCompiled, out MethodDef native)
        {
            var var    = new Variable("{VAR}");
            var result = new Variable("{RESULT}");

            var int32 = ctx.Module.CorLibTypes.Int32;

            native = new MethodDefUser(ctx.Context.Registry.GetService <INameService>().RandomName(), MethodSig.CreateStatic(int32, int32), MethodAttributes.PinvokeImpl | MethodAttributes.PrivateScope | MethodAttributes.Static)
            {
                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;

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

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

            var 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;
            }
        }
Beispiel #22
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 }
                    }
Beispiel #23
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);
            }
        }
        static RPContext ParseParameters(ModuleDef module, ConfuserContext 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);
        }
Beispiel #25
0
        public Instruction[] EmitDecode(MethodDef init, RPContext ctx, Instruction[] arg)
        {
            var 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());
        }
Beispiel #26
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}");

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

            expCompiled = new DMCodeGen(typeof(int), new[] { Tuple.Create("{VAR}", typeof(int)) })
                          .GenerateCIL(expression)
                          .Compile <Func <int, int> >();
        }
Beispiel #27
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 }.Concat(paramTypes);
                    else
                        paramTypes = new[] { Import(ctx, declType).ToTypeSig() }.Concat(paramTypes);
                }
                TypeSig retType = method.MethodSig.RetType;
                if (ctx.TypeErasure && retType.IsClassSig)
                    retType = module.CorLibTypes.Object;
                return MethodSig.CreateStatic(retType, paramTypes.ToArray());
            }
        }
Beispiel #28
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;
        }
Beispiel #29
0
        protected override void Execute(ConfuserContext context, ProtectionParameters parameters)
        {
            RandomGenerator random = context.Registry.GetService <IRandomService>().GetRandomGenerator(ReferenceProxyProtection._FullId);

            var store = new RPStore {
                random = random
            };

            foreach (MethodDef method in parameters.Targets.OfType <MethodDef>().WithProgress(context.Logger))
            {
                if (method.HasBody && method.Body.Instructions.Count > 0)
                {
                    ProcessMethod(ParseParameters(method, context, parameters, store));
                    context.CheckCancellation();
                }
            }

            RPContext ctx = ParseParameters(context.CurrentModule, context, parameters, store);

            store.mild?.Finalize(ctx);
            store.strong?.Finalize(ctx);
        }
Beispiel #30
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);
        }
Beispiel #31
0
		public override void ProcessCall(RPContext ctx, int instrIndex) {
			Instruction invoke = ctx.Body.Instructions[instrIndex];

			TypeDef declType = ((IMethod)invoke.Operand).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;

			int push, pop;
			invoke.CalculateStackUsage(out push, out pop);
			int? begin = TraceBeginning(ctx, instrIndex, pop);
			// Fail to trace the arguments => fall back to bridge method
			bool fallBack = begin == null;

			if (fallBack) {
				ProcessBridge(ctx, instrIndex);
			}
			else {
				ProcessInvoke(ctx, instrIndex, begin.Value);
			}
		}
Beispiel #32
0
        protected static TypeDef GetDelegateType(RPContext ctx, MethodSig sig)
        {
            if (ctx.Delegates.TryGetValue(sig, out var ret))
            {
                return(ret);
            }

            ret = new TypeDefUser(ctx.Name.ObfuscateName(ctx.Method.DeclaringType.Namespace, RenameMode.Unicode), ctx.Name.RandomName(), ctx.Module.CorLibTypes.GetTypeRef("System", "MulticastDelegate"))
            {
                Attributes = TypeAttributes.NotPublic | TypeAttributes.Sealed
            };

            var ctor = new MethodDefUser(".ctor", MethodSig.CreateInstance(ctx.Module.CorLibTypes.Void, ctx.Module.CorLibTypes.Object, ctx.Module.CorLibTypes.IntPtr))
            {
                Attributes     = MethodAttributes.Assembly | MethodAttributes.HideBySig | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName,
                ImplAttributes = MethodImplAttributes.Runtime
            };

            ret.Methods.Add(ctor);

            var invoke = new MethodDefUser("Invoke", sig.Clone());

            invoke.MethodSig.HasThis = true;
            invoke.Attributes        = MethodAttributes.Assembly | MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.NewSlot;
            invoke.ImplAttributes    = MethodImplAttributes.Runtime;
            ret.Methods.Add(invoke);

            ctx.Module.Types.Add(ret);

            foreach (var def in ret.FindDefinitions())
            {
                ctx.Marker.Mark(def, ctx.Protection);
                ctx.Name.SetCanRename(def, false);
            }

            ctx.Delegates[sig] = ret;
            return(ret);
        }
Beispiel #33
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;
		}
Beispiel #34
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);
        }
Beispiel #35
0
        private 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.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;
            }
        }
Beispiel #36
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.Name.SetCanRename(cctor, false);
            }

            ctx.Context.CurrentModuleWriterOptions.MetaDataOptions.Flags |= MetaDataFlags.PreserveExtraSignatureData;
            ctx.Context.CurrentModuleWriterListener.OnWriterEvent += EncodeField;
            encodeCtx = ctx;
        }
Beispiel #37
0
        public override void ProcessCall(RPContext ctx, int instrIndex)
        {
            var 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;
            }

            var key = Tuple.Create(invoke.OpCode.Code, ctx.Method.DeclaringType, target);

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

                proxy = new MethodDefUser(ctx.Name.RandomName(), sig)
                {
                    Attributes     = MethodAttributes.PrivateScope | MethodAttributes.Static,
                    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 (var 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 (var 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);
            }
        }
Beispiel #38
0
 public override void Finalize(RPContext ctx)
 {
 }
        RPContext ParseParameters(MethodDef method, ConfuserContext 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);
        }
Beispiel #40
0
		public int Encode(MethodDef init, RPContext ctx, int value) {
			Tuple<int, int> key = GetKey(ctx.Random, init);
			return value * key.Item2;
		}
		public int Encode(MethodDef init, RPContext ctx, int value) {
			Tuple<Expression, Func<int, int>> key = GetKey(ctx, init);
			return key.Item2(value);
		}
 public abstract void Finalize(RPContext ctx);
Beispiel #43
0
        private 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("Confuser.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);

                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];
        }
Beispiel #44
0
        private 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.Name.SetCanRename(field, false);

            return field;
        }
Beispiel #45
0
 public abstract void Finalize(RPContext ctx);
        public int Encode(MethodDef init, RPContext ctx, int value)
        {
            Tuple <Expression, Func <int, int> > key = GetKey(ctx, init);

            return(key.Item2(value));
        }
Beispiel #47
0
 public abstract void ProcessCall(RPContext ctx, int instrIndex);
Beispiel #48
0
 public override void Finalize(RPContext ctx)
 {
 }
Beispiel #49
0
        private 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("Confuser.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);
                        ((MethodDef)def).Access = MethodAttributes.Public;
                    }
                    else
                        ctx.Name.MarkHelper(def, ctx.Marker);
                }
            }
            return keyAttrs[index].Item1;
        }
Beispiel #50
0
        public int Encode(MethodDef init, RPContext ctx, int value)
        {
            var key = GetKey(ctx.Random, init);

            return(value * key.Item2);
        }
Beispiel #51
0
        private 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.Name.SetCanRename(method, false);

            return method;
        }
 public abstract void ProcessCall(RPContext ctx, int instrIndex);
Beispiel #53
0
 private 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;
 }
Beispiel #54
0
        private 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");
            }
        }
Beispiel #55
0
        private 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;
        }