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); } }
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()); } } }