Example #1
0
        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);
            }
        }
Example #2
0
            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());
                    }
                }
            }