public static string Compile(string input) { Console.Write("# Parsing {0}: ", input); FunctionDecl main; using (var file = new FileStream(input, FileMode.Open)) { var scanner = new Scanner(file); var parser = new Parser(scanner); if (!parser.Parse()) { Console.WriteLine("Not OK :("); throw new ArgumentException("Input is not valid..."); } Console.WriteLine("OK"); main = parser.Prog; } Console.Write("# Type checking {0}: ", input); var tcv = new TypecheckVisitor(); main.Accept(tcv); Console.WriteLine("OK"); Console.Write("# Return checking {0}: ", input); var rcv = new ReturnCheckVisitor(); main.Accept(rcv); Console.WriteLine("OK"); Console.WriteLine("# Contents of {0}:", input); var toStringVisitor = new ToStringVisitor(); main.Accept(toStringVisitor); Console.Write(toStringVisitor.Result); var prefix = input.Substring(0, input.LastIndexOf('.')); Console.Write("# Compiling {0} into {1}: ", input, prefix + ".exe"); var cecilVisitor = new CecilVisitor(tcv.Assembly, tcv.Module); main.Accept(cecilVisitor); cecilVisitor.Write(prefix); Console.WriteLine("OK"); Console.Out.Flush(); return(prefix + ".exe"); }
public static string Compile(string input) { Console.Write("# Parsing {0}: ", input); FunctionDecl main; using (var file = new FileStream(input, FileMode.Open)) { var scanner = new Scanner(file); var parser = new Parser(scanner); if (!parser.Parse()) { Console.WriteLine("Not OK :("); throw new ArgumentException("Input is not valid..."); } Console.WriteLine("OK"); main = parser.Prog; } Console.Write("# Type checking {0}: ", input); var tcv = new TypecheckVisitor(); main.Accept(tcv); Console.WriteLine("OK"); Console.Write("# Return checking {0}: ", input); var rcv = new ReturnCheckVisitor(); main.Accept(rcv); Console.WriteLine("OK"); Console.WriteLine("# Contents of {0}:", input); var toStringVisitor = new ToStringVisitor(); main.Accept(toStringVisitor); Console.Write(toStringVisitor.Result); var prefix = input.Substring(0, input.LastIndexOf('.')); Console.Write("# Compiling {0} into {1}: ", input, prefix + ".exe"); var cecilVisitor = new CecilVisitor(tcv.Assembly, tcv.Module); main.Accept(cecilVisitor); cecilVisitor.Write(prefix); Console.WriteLine("OK"); Console.Out.Flush(); return prefix + ".exe"; }
public override void Process(ConfusionParameter parameter) { if (Array.IndexOf(parameter.GlobalParameters.AllKeys, "dynamic") == -1) { ProcessSafe(parameter); return; } List <Context> txts = new List <Context>(); foreach (MethodDefinition mtd in parameter.Target as IList <IAnnotationProvider> ) { if (mtd == sc.strer || !mtd.HasBody) { continue; } var bdy = mtd.Body; bdy.SimplifyMacros(); var insts = bdy.Instructions; ILProcessor psr = bdy.GetILProcessor(); for (int i = 0; i < insts.Count; i++) { if (insts[i].OpCode.Code == Code.Ldstr) { txts.Add(new Context() { mtd = mtd, psr = psr, str = insts[i] }); } } } double total = txts.Count; int interval = 1; if (total > 1000) { interval = (int)total / 100; } int[] ids; bool retry; do { ids = new int[txts.Count]; retry = false; sc.dict.Clear(); int seed; sc.exp = ExpressionGenerator.Generate(5, out seed); for (int i = 0; i < txts.Count; i++) { string val = txts[i].str.Operand as string; if (val == "") { continue; } if (sc.dict.ContainsKey(val)) { ids[i] = (int)((sc.dict[val] + sc.key0) ^ txts[i].mtd.MetadataToken.ToUInt32()); } else { ids[i] = (int)((sc.idx + sc.key0) ^ txts[i].mtd.MetadataToken.ToUInt32()); int len; byte[] dat = Encrypt(val, sc.exp, out len); try { if (Decrypt(dat, len, sc.exp) != val) { retry = true; break; } } catch { retry = true; break; } len = (int)~(len ^ sc.key1); byte[] final = new byte[dat.Length + 4]; Buffer.BlockCopy(dat, 0, final, 4, dat.Length); Buffer.BlockCopy(BitConverter.GetBytes(len), 0, final, 0, 4); sc.dats.Add(final); sc.dict[val] = sc.idx; sc.idx += final.Length; } } } while (retry); for (int i = 0; i < sc.strer.Body.Instructions.Count; i++) { Instruction inst = sc.strer.Body.Instructions[i]; if (inst.Operand is MethodReference && ((MethodReference)inst.Operand).Name == "PolyStart") { List <Instruction> insts = new List <Instruction>(); int ptr = i + 1; while (ptr < sc.strer.Body.Instructions.Count) { Instruction z = sc.strer.Body.Instructions[ptr]; sc.strer.Body.Instructions.Remove(z); if (z.Operand is MethodReference && ((MethodReference)z.Operand).Name == "PlaceHolder") { break; } insts.Add(z); } Instruction[] expInsts = new CecilVisitor(sc.exp, true, insts.ToArray(), false).GetInstructions(); ILProcessor psr = sc.strer.Body.GetILProcessor(); psr.Replace(inst, expInsts[0]); for (int ii = 1; ii < expInsts.Length; ii++) { psr.InsertAfter(expInsts[ii - 1], expInsts[ii]); } } } sc.strer.Body.OptimizeMacros(); sc.strer.Body.ComputeOffsets(); for (int i = 0; i < txts.Count; i++) { int idx = txts[i].mtd.Body.Instructions.IndexOf(txts[i].str); Instruction now = txts[i].str; if (now.Operand as string == "") { continue; } txts[i].psr.InsertAfter(idx, txts[i].psr.Create(OpCodes.Call, sc.strer)); txts[i].psr.Replace(idx, txts[i].psr.Create(OpCodes.Ldc_I4, ids[i])); if (i % interval == 0 || i == txts.Count - 1) { progresser.SetProgress((i + 1) / total); } } List <int> hashs = new List <int>(); for (int i = 0; i < txts.Count; i++) { if (hashs.IndexOf(txts[i].mtd.GetHashCode()) == -1) { txts[i].mtd.Body.OptimizeMacros(); txts[i].mtd.Body.ComputeHeader(); hashs.Add(txts[i].mtd.GetHashCode()); } } }
public override void Process(ConfusionParameter parameter) { List<Context> txts = new List<Context>(); IList<IAnnotationProvider> targets = parameter.Target as IList<IAnnotationProvider>; for (int i = 0; i < targets.Count; i++) { MethodDefinition mtd = targets[i] as MethodDefinition; if (!mtd.HasBody) continue; mtd.Body.SimplifyMacros(); int lv = 5; if (Array.IndexOf(parameter.Parameters.AllKeys, mtd.GetHashCode().ToString("X8") + "_level") != -1) { if (!int.TryParse(parameter.Parameters[mtd.GetHashCode().ToString("X8") + "_level"], out lv) && (lv <= 0 || lv > 10)) { Log("Invaild level, 5 will be used."); lv = 5; } } foreach(Instruction inst in mtd.Body.Instructions) { if ((inst.OpCode.Name == "ldc.i4" && (int)inst.Operand != -1 && (int)inst.Operand != 0 && (int)inst.Operand != 1) || //(inst.OpCode.Name == "ldc.i8" && (long)inst.Operand != -1 && (long)inst.Operand != 0 && (long)inst.Operand != 1) || (inst.OpCode.Name == "ldc.r4" && (float)inst.Operand != -1 && (float)inst.Operand != 0 && (float)inst.Operand != 1) || (inst.OpCode.Name == "ldc.r8" && (double)inst.Operand != -1 && (double)inst.Operand != 0 && (double)inst.Operand != 1)) txts.Add(new Context() { mtd = mtd, psr = mtd.Body.GetILProcessor(), inst = inst, lv = lv }); } progresser.SetProgress((i + 1) / (double)targets.Count); } for (int i = 0; i < txts.Count; i++) { Context txt = txts[i]; int instIdx = txt.mtd.Body.Instructions.IndexOf(txt.inst); double val = Convert.ToDouble(txt.inst.Operand); int seed; Expression exp; double eval = 0; double tmp = 0; do { exp = ExpressionGenerator.Generate(txt.lv, out seed); eval = DoubleExpressionEvaluator.Evaluate(exp, val); try { tmp = DoubleExpressionEvaluator.ReverseEvaluate(exp, eval); } catch { continue; } } while (tmp != val); Instruction[] expInsts = new CecilVisitor(exp, true, new Instruction[] { Instruction.Create(OpCodes.Ldc_R8, eval) }, true).GetInstructions(); if (expInsts.Length == 0) continue; string op = txt.inst.OpCode.Name; txt.psr.Replace(instIdx, expInsts[0]); for (int ii = 1; ii < expInsts.Length; ii++) { txt.psr.InsertAfter(instIdx + ii - 1, expInsts[ii]); } switch (op) { case "ldc.i4": txt.psr.InsertAfter(instIdx +expInsts.Length - 1, Instruction.Create(OpCodes.Conv_I4)); break; //case "ldc.i8": // txt.psr.InsertAfter(instIdx +expInsts.Length - 1, Instruction.Create(OpCodes.Conv_I8)); break; case "ldc.r4": txt.psr.InsertAfter(instIdx +expInsts.Length - 1, Instruction.Create(OpCodes.Conv_R4)); break; case "ldc.r8": txt.psr.InsertAfter(instIdx +expInsts.Length - 1, Instruction.Create(OpCodes.Conv_R8)); break; } progresser.SetProgress((i + 1) / (double)txts.Count); } }
void FinalizeBodies(List <Context> txts) { double total = txts.Count; int interval = 1; if (total > 1000) { interval = (int)total / 100; } //StringGenerator sg = new StringGenerator(Random.Next(500000), txts[0].mtd.Module); for (int i = 0; i < txts.Count; i++) { int idx = txts[i].mtd.Body.Instructions.IndexOf(txts[i].str); Instruction now = txts[i].str; if (IsNull(now.Operand)) { continue; } TypeReference typeRef; if (now.Operand is int) { typeRef = txts[i].mtd.Module.TypeSystem.Int32; } else if (now.Operand is long) { typeRef = txts[i].mtd.Module.TypeSystem.Int64; } else if (now.Operand is float) { typeRef = txts[i].mtd.Module.TypeSystem.Single; } else if (now.Operand is double) { typeRef = txts[i].mtd.Module.TypeSystem.Double; } else { typeRef = txts[i].mtd.Module.TypeSystem.String; } Instruction call = Instruction.Create(OpCodes.Call, new GenericInstanceMethod(txts[i].conster.conster) { GenericArguments = { typeRef } }); call.SequencePoint = now.SequencePoint; txts[i].psr.InsertAfter(idx, call); MethodBody A_BODY = txts[i].mtd.Body; if (ObfuscationHelper.StringGen != null) { txts[i].psr.InsertAfter(idx, Instruction.Create(OpCodes.Ldc_I8, (long)txts[i].b)); Expression ex = new ExpressionGenerator(Random.Next(5000000), mod).Generate(5); int evald = ExpressionEvaluator.Evaluate(ex, (int)txts[i].a); Expression exR = ExpressionInverser.InverseExpression(ex); CecilVisitor cv = new CecilVisitor(exR, new Instruction[] { Instruction.Create(OpCodes.Ldc_I4, evald) }); List <Instruction> keyA = cv.GetInstructions().ToList(); //List<Instruction> keyA = ObfuscationHelper.StringGen.GenerateLevels(txts[i].mtd, (int)txts[i].a, Random.Next(0, 2), 3); txts[i].mtd.Body.Instructions[idx].OpCode = keyA[0].OpCode; txts[i].mtd.Body.Instructions[idx].Operand = keyA[0].Operand; keyA = keyA.Skip(1).Reverse().ToList(); foreach (Instruction a in keyA) { A_BODY.Instructions.Insert(idx + 1, a); } } else { txts[i].psr.Replace(idx, Instruction.Create(OpCodes.Ldc_I4, (int)txts[i].a)); txts[i].psr.InsertAfter(idx, Instruction.Create(OpCodes.Ldc_I8, (long)txts[i].b)); } //txts[i].psr.Replace(idx, Instruction.Create(OpCodes.Ldc_I4, (int)txts[i].a)); //txts[i].psr.InsertAfter(idx, Instruction.Create(OpCodes.Ldc_I8, (long)txts[i].b)); // I4_0 == U4 Conv // I4_1 == U8 conv /*List<Instruction> genInsts = sg.MathGen.GenerateLevels((int)txts[i].a, OpCodes.Ldc_I4, Random.Next(0, 3)); * * * txts[i].mtd.Body.Instructions[idx].OpCode = genInsts[0].OpCode; * txts[i].mtd.Body.Instructions[idx].Operand = genInsts[0].Operand; * * genInsts = genInsts.Skip(1).Reverse().ToList(); * foreach (Instruction a in genInsts) * { * txts[i].mtd.Body.Instructions.Insert(idx + 1, a); * }*/ //Instruction tmp = null; //foreach (Instruction a in genInsts) //{ // if (genInsts[0] == a) // { // txts[i].psr.Replace(idx, a); // tmp = a; // continue; // } // txts[i].psr.InsertAfter(tmp, a); // tmp = a; //} //txts[i].psr.Replace(idx, Instruction.Create(OpCodes.Ldc_I4, (int)txts[i].a)); //txts[i].psr.InsertAfter(idx, Instruction.Create(OpCodes.Ldc_I8, (long)txts[i].b)); //txts[i].psr.InsertAfter(tmp, Instruction.Create(OpCodes.Ldc_I8, (long)txts[i].b)); /*genInsts = mg.GenerateLevels(txts[i].b, OpCodes.Ldc_I4_1, Random.Next(0, 0), false, false); * * foreach (Instruction a in genInsts) * { * if (tmp == null) * { * txts[i].psr.InsertAfter(idx, a); * tmp = a; * continue; * } * txts[i].psr.InsertAfter(tmp, a); * tmp = a; * }*/ if (i % interval == 0 || i == txts.Count - 1) { progresser.SetProgress(i + 1, txts.Count); } } List <int> hashs = new List <int>(); for (int i = 0; i < txts.Count; i++) { if (hashs.IndexOf(txts[i].mtd.GetHashCode()) == -1) { txts[i].mtd.Body.MaxStackSize += 2; hashs.Add(txts[i].mtd.GetHashCode()); } } }
public override void Process(ConfusionParameter parameter) { if (Array.IndexOf(parameter.GlobalParameters.AllKeys, "dynamic") == -1) { ProcessSafe(parameter); return; } List <Context> txts = new List <Context>(); ExtractData(parameter.Target as IList <IAnnotationProvider>, txts, Array.IndexOf(parameter.GlobalParameters.AllKeys, "numeric") != -1); int[] ids; bool retry; do { ids = new int[txts.Count]; retry = false; cc.dict.Clear(); int seed; cc.exp = ExpressionGenerator.Generate(5, out seed); for (int i = 0; i < txts.Count; i++) { object val = txts[i].str.Operand as object; if (IsNull(val)) { continue; } if (cc.dict.ContainsKey(val)) { ids[i] = (int)(cc.dict[val] ^ ComputeHash(txts[i].mtd.MetadataToken.ToUInt32(), (uint)cc.key0, (uint)cc.key1, (uint)cc.key2, (uint)cc.key3)); } else { ids[i] = (int)(cc.idx ^ ComputeHash(txts[i].mtd.MetadataToken.ToUInt32(), (uint)cc.key0, (uint)cc.key1, (uint)cc.key2, (uint)cc.key3)); byte t; byte[] ori = GetOperand(val, out t); int len; byte[] dat = Encrypt(ori, cc.exp, out len); try { if (!IsEqual(Decrypt(dat, len, cc.exp), ori)) { retry = true; break; } } catch { retry = true; break; } byte[] final = new byte[dat.Length + 4]; Buffer.BlockCopy(dat, 0, final, 4, dat.Length); Buffer.BlockCopy(BitConverter.GetBytes(len), 0, final, 0, 4); cc.dats.Add(new Data() { Dat = final, Type = t }); cc.dict[val] = cc.idx; cc.idx += final.Length + 5; } System.Diagnostics.Debug.WriteLine(cc.dict[val].ToString() + " " + val.ToString()); } } while (retry); for (int i = 0; i < cc.strer.Body.Instructions.Count; i++) { Instruction inst = cc.strer.Body.Instructions[i]; if (inst.Operand is MethodReference && ((MethodReference)inst.Operand).Name == "PolyStart") { List <Instruction> insts = new List <Instruction>(); int ptr = i + 1; while (ptr < cc.strer.Body.Instructions.Count) { Instruction z = cc.strer.Body.Instructions[ptr]; cc.strer.Body.Instructions.Remove(z); if (z.Operand is MethodReference && ((MethodReference)z.Operand).Name == "PlaceHolder") { break; } insts.Add(z); } Instruction[] expInsts = new CecilVisitor(cc.exp, true, insts.ToArray(), false).GetInstructions(); ILProcessor psr = cc.strer.Body.GetILProcessor(); psr.Replace(inst, expInsts[0]); for (int ii = 1; ii < expInsts.Length; ii++) { psr.InsertAfter(expInsts[ii - 1], expInsts[ii]); } } } cc.strer.Body.OptimizeMacros(); cc.strer.Body.ComputeOffsets(); FinalizeBodies(txts, ids); }