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()); }
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); }
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()); }
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> >(); }
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); }
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); }
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()); }
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)); }
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); } } }
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); }
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; } }
public abstract void Finalize(RPContext ctx);
public abstract void ProcessCall(RPContext ctx, int instrIndex);
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>())); }
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);
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); }
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); } } }
public override void Finalize(RPContext ctx) { }