public Instruction[] EmitDecode(MethodDef init, RPContext ctx, Instruction[] arg)
        {
            Tuple <MethodDef, Func <int, int> > key = this.GetKey(ctx, init);
            List <Instruction> list = new List <Instruction>();

            list.AddRange(arg);
            list.Add(Instruction.Create(OpCodes.Call, key.Item1));
            return(list.ToArray());
        }
예제 #2
0
        private static ITypeDefOrRef Import(RPContext ctx, TypeDef typeDef)
        {
            ITypeDefOrRef ref2 = new Importer(ctx.Module, ImporterOptions.TryToUseTypeDefs).Import(typeDef);

            if ((typeDef.Module != ctx.Module) && ctx.Context.Modules.Contains((ModuleDefMD)typeDef.Module))
            {
                ctx.Name.AddReference <TypeDef>(typeDef, new TypeRefReference((TypeRef)ref2, typeDef));
            }
            return(ref2);
        }
예제 #3
0
        private TypeDef GetKeyAttr(RPContext ctx)
        {
            if (this.keyAttrs == null)
            {
                this.keyAttrs = new Tuple <TypeDef, Func <int, int> > [0x10];
            }
            int index = ctx.Random.NextInt32(this.keyAttrs.Length);

            return(this.keyAttrs[index]?.Item1);
        }
        public Instruction[] EmitDecode(MethodDef init, RPContext ctx, Instruction[] arg)
        {
            Tuple <Expression, Func <int, int> > key = this.GetKey(ctx, init);
            List <Instruction> instrs = new List <Instruction>();

            new CodeGen(arg, ctx.Method, instrs).GenerateCIL(key.Item1);
            CilBody body = init.Body;

            body.MaxStack = (ushort)(body.MaxStack + ((ushort)ctx.Depth));
            return(instrs.ToArray());
        }
예제 #5
0
        public override void ProcessCall(RPContext ctx, int instrIndex)
        {
            Instruction instruction = ctx.Body.Instructions[instrIndex];
            IMethod     operand     = (IMethod)instruction.Operand;

            if (!operand.DeclaringType.ResolveTypeDefThrow().IsValueType&& (operand.ResolveThrow().IsPublic || operand.ResolveThrow().IsAssembly))
            {
                MethodDef def;
                Tuple <Code, TypeDef, IMethod> key = Tuple.Create <Code, TypeDef, IMethod>(instruction.OpCode.Code, ctx.Method.DeclaringType, operand);
                if (!this.proxies.TryGetValue(key, out def))
                {
                    MethodSig methodSig = RPMode.CreateProxySignature(ctx, operand, instruction.OpCode.Code == Code.Newobj);
                    def = new MethodDefUser(NameService.RandomNameStatic(), methodSig)
                    {
                        Attributes     = MethodAttributes.CompilerControlled | MethodAttributes.Static,
                        ImplAttributes = MethodImplAttributes.IL
                    };
                    ctx.Method.DeclaringType.Methods.Add(def);
                    if ((instruction.OpCode.Code == Code.Call) && operand.ResolveThrow().IsVirtual)
                    {
                        def.IsStatic      = false;
                        methodSig.HasThis = true;
                        methodSig.Params.RemoveAt(0);
                    }
                    ctx.Marker.Mark(def, ctx.Protection);

                    /*ctx.Name.Analyze(def);
                     * ctx.Name.SetCanRename(def, false);*/
                    def.Body = new CilBody();
                    for (int i = 0; i < def.Parameters.Count; i++)
                    {
                        def.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg, def.Parameters[i]));
                    }
                    def.Body.Instructions.Add(Instruction.Create(instruction.OpCode, operand));
                    def.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
                    this.proxies[key] = def;
                }
                instruction.OpCode = OpCodes.Call;
                if (ctx.Method.DeclaringType.HasGenericParameters)
                {
                    GenericVar[] genArgs = new GenericVar[ctx.Method.DeclaringType.GenericParameters.Count];
                    for (int j = 0; j < genArgs.Length; j++)
                    {
                        genArgs[j] = new GenericVar(j);
                    }
                    instruction.Operand = new MemberRefUser(ctx.Module, def.Name, def.MethodSig, new GenericInstSig((ClassOrValueTypeSig)ctx.Method.DeclaringType.ToTypeSig(), genArgs).ToTypeDefOrRef());
                }
                else
                {
                    instruction.Operand = def;
                }
            }
        }
        private Tuple <Expression, Func <int, int> > GetKey(RPContext ctx, MethodDef init)
        {
            Tuple <Expression, Func <int, int> > tuple;

            if (!this.keys.TryGetValue(init, out tuple))
            {
                Func <int, int> func;
                Expression      expression;
                this.Compile(ctx, init.Body, out func, out expression);
                this.keys[init] = tuple = Tuple.Create <Expression, Func <int, int> >(expression, func);
            }
            return(tuple);
        }
        private Tuple <MethodDef, Func <int, int> > GetKey(RPContext ctx, MethodDef init)
        {
            Tuple <MethodDef, Func <int, int> > tuple;

            if (!this.keys.TryGetValue(init, out tuple))
            {
                Func <int, int> func;
                MethodDef       def;
                this.Compile(ctx, out func, out def);
                this.keys[init] = tuple = Tuple.Create <MethodDef, Func <int, int> >(def, func);
            }
            return(tuple);
        }
        private void Compile(RPContext ctx, CilBody body, out Func <int, int> expCompiled, out Expression inverse)
        {
            Expression         expression;
            Variable           variable  = new Variable("{VAR}");
            Variable           variable2 = new Variable("{RESULT}");
            VariableExpression var       = new VariableExpression {
                Variable = variable
            };
            VariableExpression result = new VariableExpression {
                Variable = variable2
            };

            ctx.DynCipher.GenerateExpressionPair(ctx.Random, var, result, ctx.Depth, out expression, out inverse);
            expCompiled = new DMCodeGen(typeof(int), new Tuple <string, Type>[] { Tuple.Create <string, Type>("{VAR}", typeof(int)) }).GenerateCIL(expression).Compile <Func <int, int> >();
        }
예제 #9
0
        private FieldDef CreateField(RPContext ctx, TypeDef delegateType)
        {
            TypeDef def;

            do
            {
                def = ctx.Module.Types[ctx.Random.NextInt32(ctx.Module.Types.Count)];
            }while ((def.HasGenericParameters || def.IsGlobalModuleType) || def.IsDelegate());
            TypeSig      type = new CModOptSig(def, delegateType.ToTypeSig());
            FieldDefUser item = new FieldDefUser("", new FieldSig(type), FieldAttributes.Assembly | FieldAttributes.Static);

            item.CustomAttributes.Add(new CustomAttribute(this.GetKeyAttr(ctx).FindInstanceConstructors().First <MethodDef>()));
            delegateType.Fields.Add(item);
            ctx.Marker.Mark(item, ctx.Protection);
            ctx.Name.SetCanRename(item, false);
            return(item);
        }
예제 #10
0
        static RPContext ParseParameters(ModuleDef module, ConfuserContext context, ProtectionParameters parameters, RPStore store)
        {
            var ret = new RPContext();

            ret.Depth     = parameters.GetParameter(context, module, "depth", 15);
            ret.InitCount = parameters.GetParameter(context, module, "initCount", 25);

            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);
        }
예제 #11
0
        public Instruction[] EmitDecode(MethodDef init, RPContext ctx, Instruction[] arg)
        {
            Tuple <int, int>   key  = this.GetKey(ctx.Random, init);
            List <Instruction> list = new List <Instruction>();

            if (ctx.Random.NextBoolean())
            {
                list.Add(Instruction.Create(OpCodes.Ldc_I4, key.Item1));
                list.AddRange(arg);
            }
            else
            {
                list.AddRange(arg);
                list.Add(Instruction.Create(OpCodes.Ldc_I4, key.Item1));
            }
            list.Add(Instruction.Create(OpCodes.Mul));
            return(list.ToArray());
        }
예제 #12
0
        private static int?TraceBeginning(RPContext ctx, int index, int argCount)
        {
            if (ctx.BranchTargets.Contains(ctx.Body.Instructions[index]))
            {
                return(null);
            }
            int num  = argCount;
            int num2 = index;

            while (num > 0)
            {
                num2--;
                Instruction item = ctx.Body.Instructions[num2];
                if ((item.OpCode != OpCodes.Pop) && (item.OpCode != OpCodes.Dup))
                {
                    switch (item.OpCode.FlowControl)
                    {
                    case FlowControl.Break:
                    case FlowControl.Call:
                    case FlowControl.Meta:
                    case FlowControl.Next:
                        int num3;
                        int num4;
                        item.CalculateStackUsage(out num3, out num4);
                        num += num4;
                        num -= num3;
                        if (!ctx.BranchTargets.Contains(item) || (num == 0))
                        {
                            continue;
                        }
                        return(null);
                    }
                }
                return(null);
            }
            if (num < 0)
            {
                return(null);
            }
            return(new int?(num2));
        }
예제 #13
0
        public override void ProcessCall(RPContext ctx, int instrIndex)
        {
            Instruction instruction = ctx.Body.Instructions[instrIndex];
            TypeDef     def         = ((IMethod)instruction.Operand).DeclaringType.ResolveTypeDefThrow();

            if (def.Module.IsILOnly && !def.IsGlobalModuleType)
            {
                int num;
                int num2;
                instruction.CalculateStackUsage(out num, out num2);
                int?nullable = TraceBeginning(ctx, instrIndex, num2);
                if (!nullable.HasValue)
                {
                    this.ProcessBridge(ctx, instrIndex);
                }
                else
                {
                    this.ProcessInvoke(ctx, instrIndex, nullable.Value);
                }
            }
        }
예제 #14
0
        private MethodDef CreateBridge(RPContext ctx, TypeDef delegateType, FieldDef field, MethodSig sig)
        {
            MethodDefUser item = new MethodDefUser(ctx.Name.RandomName(), sig)
            {
                Attributes     = MethodAttributes.CompilerControlled | MethodAttributes.Static,
                ImplAttributes = MethodImplAttributes.IL,
                Body           = new CilBody()
            };

            item.Body.Instructions.Add(Instruction.Create(OpCodes.Ldsfld, (IField)field));
            for (int i = 0; i < item.Parameters.Count; i++)
            {
                item.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg, item.Parameters[i]));
            }
            item.Body.Instructions.Add(Instruction.Create(OpCodes.Call, (IMethod)delegateType.FindMethod("Invoke")));
            item.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
            delegateType.Methods.Add(item);
            ctx.Context.Registry.GetService <IMarkerService>().Mark(item, ctx.Protection);
            ctx.Name.SetCanRename(item, false);
            return(item);
        }
예제 #15
0
        private InitMethodDesc GetInitMethod(RPContext ctx, IRPEncoding encoding)
        {
            InitMethodDesc[] descArray;
            if (!this.inits.TryGetValue(encoding, out descArray))
            {
                this.inits[encoding] = descArray = new InitMethodDesc[ctx.InitCount];
            }
            int index = ctx.Random.NextInt32(descArray.Length);

            if (descArray[index] == null)
            {
                TypeDef   runtimeType    = ctx.Context.Registry.GetService <IRuntimeService>().GetRuntimeType("Confuser.Runtime.RefProxyStrong");
                MethodDef injectedMethod = InjectHelper.Inject(runtimeType.FindMethod("Initialize"), ctx.Module);
                ctx.Module.GlobalType.Methods.Add(injectedMethod);
                injectedMethod.Access = MethodAttributes.CompilerControlled;
                injectedMethod.Name   = ctx.Name.RandomName();
                ctx.Name.SetCanRename(injectedMethod, false);
                ctx.Marker.Mark(injectedMethod, ctx.Protection);
                InitMethodDesc desc = new InitMethodDesc {
                    Method = injectedMethod
                };
                int[] list = Enumerable.Range(0, 5).ToArray <int>();
                ctx.Random.Shuffle <int>(list);
                desc.OpCodeIndex    = list[4];
                desc.TokenNameOrder = new int[4];
                Array.Copy(list, 0, desc.TokenNameOrder, 0, 4);
                desc.TokenByteOrder = (from x in Enumerable.Range(0, 4) select x * 8).ToArray <int>();
                ctx.Random.Shuffle <int>(desc.TokenByteOrder);
                int[] destinationArray = new int[9];
                Array.Copy(desc.TokenNameOrder, 0, destinationArray, 0, 4);
                Array.Copy(desc.TokenByteOrder, 0, destinationArray, 4, 4);
                destinationArray[8] = desc.OpCodeIndex;
                MutationHelper.InjectKeys(injectedMethod, Enumerable.Range(0, 9).ToArray <int>(), destinationArray);
                MutationHelper.ReplacePlaceholder(injectedMethod, arg => encoding.EmitDecode(injectedMethod, ctx, arg));
                desc.Encoding    = encoding;
                descArray[index] = desc;
            }
            return(descArray[index]);
        }
        private void Compile(RPContext ctx, out Func <int, int> expCompiled, out MethodDef native)
        {
            x86Register?  nullable;
            Expression    expression;
            Variable      variable  = new Variable("{VAR}");
            Variable      variable2 = new Variable("{RESULT}");
            CorLibTypeSig retType   = ctx.Module.CorLibTypes.Int32;

            native = new MethodDefUser(ctx.Context.Registry.GetService <INameService>().RandomName(), MethodSig.CreateStatic(retType, retType), MethodAttributes.CompilerControlled | MethodAttributes.PinvokeImpl | MethodAttributes.Static);
            native.ImplAttributes = MethodImplAttributes.IL | MethodImplAttributes.ManagedMask | MethodImplAttributes.Native | 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);
            x86CodeGen codeGen = new x86CodeGen();

            do
            {
                Expression         expression2;
                VariableExpression var = new VariableExpression {
                    Variable = variable
                };
                VariableExpression result = new VariableExpression {
                    Variable = variable2
                };
                ctx.DynCipher.GenerateExpressionPair(ctx.Random, var, result, ctx.Depth, out expression, out expression2);
                nullable = codeGen.GenerateX86(expression2, (v, r) => new x86Instruction[] { x86Instruction.Create(x86OpCode.POP, new Ix86Operand[] { new x86RegisterOperand(r) }) });
            }while (!nullable.HasValue);
            byte[] buffer = CodeGenUtils.AssembleCode(codeGen, nullable.Value);
            expCompiled = new DMCodeGen(typeof(int), new Tuple <string, Type>[] { Tuple.Create <string, Type>("{VAR}", typeof(int)) }).GenerateCIL(expression).Compile <Func <int, int> >();
            this.nativeCodes.Add(Tuple.Create <MethodDef, byte[], dnlib.DotNet.Writer.MethodBody>(native, buffer, null));
            if (!this.addedHandler)
            {
                ctx.Context.CurrentModuleWriterListener.OnWriterEvent += new EventHandler <ModuleWriterListenerEventArgs>(this.InjectNativeCode);
                this.addedHandler = true;
            }
        }
예제 #17
0
 public abstract void Finalize(RPContext ctx);
예제 #18
0
 public abstract void ProcessCall(RPContext ctx, int instrIndex);
예제 #19
0
        protected static MethodSig CreateProxySignature(RPContext ctx, IMethod method, bool newObj)
        {
            Func <TypeSig, TypeSig> selector = null;
            Func <TypeSig, TypeSig> func2    = null;
            ModuleDef module = ctx.Module;

            if (newObj)
            {
                TypeSig sig;
                if (selector == null)
                {
                    selector = delegate(TypeSig type) {
                        if ((ctx.TypeErasure && type.IsClassSig) && method.MethodSig.HasThis)
                        {
                            return(module.CorLibTypes.Object);
                        }
                        return(type);
                    };
                }
                TypeSig[] argTypes = method.MethodSig.Params.Select <TypeSig, TypeSig>(selector).ToArray <TypeSig>();
                if (ctx.TypeErasure)
                {
                    sig = module.CorLibTypes.Object;
                }
                else
                {
                    TypeDef typeDef = method.DeclaringType.ResolveTypeDefThrow();
                    sig = Import(ctx, typeDef).ToTypeSig();
                }
                return(MethodSig.CreateStatic(sig, argTypes));
            }
            if (func2 == null)
            {
                func2 = delegate(TypeSig type) {
                    if ((ctx.TypeErasure && type.IsClassSig) && method.MethodSig.HasThis)
                    {
                        return(module.CorLibTypes.Object);
                    }
                    return(type);
                };
            }
            IEnumerable <TypeSig> second = method.MethodSig.Params.Select <TypeSig, TypeSig>(func2);

            if (method.MethodSig.HasThis && !method.MethodSig.ExplicitThis)
            {
                TypeDef def2 = method.DeclaringType.ResolveTypeDefThrow();
                if (ctx.TypeErasure && !def2.IsValueType)
                {
                    second = new CorLibTypeSig[] { module.CorLibTypes.Object }.Concat <TypeSig>(second);
                }
                else
                {
                    second = new TypeSig[] { Import(ctx, def2).ToTypeSig() }.Concat <TypeSig>(second);
                }
            }
            TypeSig retType = method.MethodSig.RetType;

            if (ctx.TypeErasure && retType.IsClassSig)
            {
                retType = module.CorLibTypes.Object;
            }
            return(MethodSig.CreateStatic(retType, second.ToArray <TypeSig>()));
        }
예제 #20
0
        public int Encode(MethodDef init, RPContext ctx, int value)
        {
            Tuple <int, int> key = this.GetKey(ctx.Random, init);

            return(value * key.Item2);
        }
 public int Encode(MethodDef init, RPContext ctx, int value) =>
 this.GetKey(ctx, init).Item2(value);
예제 #22
0
        RPContext ParseParameters(MethodDef method, ConfuserContext context, ProtectionParameters parameters, RPStore store)
        {
            var ret = new RPContext();

            ret.Mode         = parameters.GetParameter(context, method, "mode", Mode.Mild);     //mod
            ret.Encoding     = parameters.GetParameter(context, method, "encoding", EncodingType.x86);
            ret.InternalAlso = parameters.GetParameter(context, method, "internal", true);
            ret.TypeErasure  = parameters.GetParameter(context, method, "typeErasure", true);
            ret.Depth        = parameters.GetParameter(context, method, "depth", 5);

            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 = (MildReferenceProxyProtection)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);
        }
예제 #23
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)
                    {
                        return;
                    }
                    // No prefixed call
                    if (i - 1 >= 0 && ctx.Body.Instructions[i - 1].OpCode.OpCodeType == OpCodeType.Prefix)
                    {
                        continue;
                    }

                    ctx.ModeHandler.ProcessCall(ctx, i);
                }
            }
        }
예제 #24
0
 public override void Finalize(RPContext ctx)
 {
 }