Ejemplo n.º 1
0
        public override void CleanUp()
        {
            var badCall  = RoutineVariables["resolverCall"] as Tuple <Instruction[], MethodDef>;
            var badRes   = RoutineVariables["badRes"] as EmbeddedResource;
            var resolver = RoutineVariables["resolver"] as MethodDef;
            var asmFld   = RoutineVariables["asmFld"] as FieldDef;

            if (badCall != null)
            {
                RemovedInstructions.Add(Tuple.Create(badCall.Item2, badCall.Item1));
                foreach (var instr in badCall.Item1)
                {
                    badCall.Item2.Body.Instructions.Remove(instr);
                }
            }

            if (badRes != null)
            {
                Ctx.UIProvider.WriteVerbose("Removed encrypted resource: {0}", 2, true, badRes.Name);
                Ctx.Assembly.ManifestModule.Resources.Remove(badRes);
            }

            if (resolver != null)
            {
                Ctx.UIProvider.WriteVerbose("Removed resource decryptor: {0}::{1}", 2, true, resolver.DeclaringType.Name, resolver.Name);
                resolver.DeclaringType.Methods.Remove(resolver);
            }

            if (asmFld != null)
            {
                Ctx.UIProvider.WriteVerbose("Removed bad field: {0}::{1}", 2, true, asmFld.DeclaringType.Name, asmFld.Name);
                asmFld.DeclaringType.Fields.Remove(asmFld);
            }
        }
        private void DecryptConstants(
            List <Tuple <Decryptor, MethodDef, List <Tuple <Instruction, MethodDef> > > > demutatedDecryptors)
        {
            demutatedDecryptors.ForEach(d =>
            {
                CalculateMutations(d.Item2);
                PopulateKeys(d.Item1, d.Item2);

                foreach (var @ref in d.Item3)
                {
                    //var tracer = new ILEmulator(@ref.Item2.Body,
                    //                            @ref.Item2.Body.Instructions.Count);
                    //var test = tracer.TraceCallParameters(@ref.Item1).ToList();
                    var body       = @ref.Item2.Body;
                    var mdModifier =
                        (uint)@ref.Item1.Previous(body).Previous(body).GetLdcI4Value();
                    var hashModifier = (ulong)@ref.Item1.Previous(body).GetLdcI8();
                    var str          = d.Item1.Decrypt <string>(mdModifier, hashModifier);

                    body.SimplifyMacros(@ref.Item2.Parameters);
                    body.SimplifyBranches();

                    var removedInstructions = new[]
                    {
                        @ref.Item1.Previous(body),
                        @ref.Item1.Previous(body).Previous(body),
                        @ref.Item1
                    };

                    body.Instructions.Replace(@ref.Item1, Instruction.Create(OpCodes.Ldstr, str));

                    foreach (var instr in removedInstructions)
                    {
                        body.Instructions.Remove(instr);
                    }

                    body.OptimizeMacros();
                    body.OptimizeBranches();
                    body.UpdateInstructionOffsets();

                    RemovedInstructions.Add(Tuple.Create(@ref.Item2, removedInstructions));

                    Ctx.UIProvider.WriteVerbose("Restored string \"{0}\"", 2, true, str);
                }
            });
        }
        public override void RestoreProxyCall(Tuple <TypeDef, IMemberRef, FieldDef> resolvedProxy)
        {
            var destCall = resolvedProxy.Item1.Methods.First(x => x.IsStatic && !x.IsConstructor && x.HasBody);

            foreach (var @ref in destCall.FindAllReferences())
            {
                Ctx.UIProvider.WriteVerbose("Restored proxy call [{0} -> {1}]", 2, true, destCall.Name, resolvedProxy.Item2.Name);
                @ref.Item2.Body.SimplifyMacros(@ref.Item2.Parameters);
                @ref.Item2.Body.SimplifyBranches();
                RemovedInstructions.Add(Tuple.Create(@ref.Item2, new[]
                {
                    @ref.Item1
                }));
                @ref.Item2.Body.Instructions.Replace(@ref.Item1,
                                                     Instruction.Create(OpCodes.Newobj, resolvedProxy.Item2 as IMethod));
                @ref.Item2.Body.OptimizeBranches();
                @ref.Item2.Body.OptimizeMacros();
            }
        }
        public override void CleanUp()
        {
            var badCall = RoutineVariables["badcall"] as Tuple <Instruction, MethodDef>;
            var badType = RoutineVariables["badtype"] as TypeDef;

            if (badCall != null)
            {
                Ctx.UIProvider.WriteVerbose("Removed bad call from {0}::{1}", 2, true, badCall.Item2.DeclaringType.Name,
                                            badCall.Item2.Name);
                RemovedInstructions.Add(Tuple.Create(badCall.Item2, new[] { badCall.Item1 }));
                badCall.Item2.Body.Instructions.Remove(badCall.Item1);
            }

            if (badType != null)
            {
                Ctx.UIProvider.WriteVerbose("Removed bad type {0}", 2, true, badType.Name);
                badType.Module.Types.Remove(badType);
            }
        }
Ejemplo n.º 5
0
        public override void CleanUp()
        {
            var antiTamper = RoutineVariables["antiTamper"] as MethodDef;
            var refs       = antiTamper.FindAllReferences().ToList();

            if (refs.Count != 1)
            {
                Ctx.UIProvider.Write("Too many or too few references to anti-tamper module");
                return;
            }

            Ctx.UIProvider.WriteVerbose("Removed call to anti-tamper from {0}::{1}", 2, true, refs[0].Item2.DeclaringType.Name,
                                        ".cctor");

            RemovedInstructions.Add(Tuple.Create(refs[0].Item2, new[] { refs[0].Item1 }));
            refs[0].Item2.Body.Instructions.Remove(refs[0].Item1);

            Ctx.UIProvider.WriteVerbose("Removed bad type: {0}", 2, true, antiTamper.DeclaringType.Name);
            Ctx.Assembly.ManifestModule.Types.Remove(antiTamper.DeclaringType);
        }
        public override void RestoreProxyCall(Tuple <TypeDef, IMemberRef, FieldDef> resolvedProxy, char virtIdentifier)
        {
            var destCall =
                resolvedProxy.Item1.Methods.First(
                    x =>
                    x.IsStatic && !x.IsConstructor && x.HasBody &&
                    x.Body.Instructions.FindInstruction(
                        y => y.OpCode.Code == Code.Ldsfld && y.Operand == resolvedProxy.Item3, 0) != null);

            var isVirtual = resolvedProxy.Item3.Name.String[0] == virtIdentifier;

            foreach (var @ref in destCall.FindAllReferences())
            {
                if (resolvedProxy.Item2 == null)
                {
                    continue;
                }
                Ctx.UIProvider.WriteVerbose("Restored proxy call [{0} -> {1}]", 2, true, destCall.Name, resolvedProxy.Item2.Name);
                @ref.Item2.Body.SimplifyMacros(@ref.Item2.Parameters);
                @ref.Item2.Body.SimplifyBranches();
                if ((resolvedProxy.Item2 as MemberRef) == null)
                {
                    return;
                }

                RemovedInstructions.Add(Tuple.Create(@ref.Item2, new[]
                {
                    @ref.Item1
                }));
                @ref.Item2.Body.Instructions.Replace(@ref.Item1,
                                                     Instruction.Create((isVirtual ? OpCodes.Callvirt : OpCodes.Call), resolvedProxy.Item2 as MemberRef));

                @ref.Item2.Body.OptimizeMacros();
                @ref.Item2.Body.OptimizeBranches();
                @ref.Item2.Body.UpdateInstructionOffsets();
            }
        }
Ejemplo n.º 7
0
        public void CalculateMutations(MethodDef method)
        {
            if (method == null || method.Body == null)
            {
                return;
            }
            var pattern = new List <Predicate <Instruction> >
            {
                (x => x.IsLdcI4_2()),
                (x => x.OpCode.Code == Code.Add),
                (x => x.OpCode.Code == Code.Xor),
                (x => x.OpCode.Code == Code.Sub),
                //(x => x.OpCode.Code == Code.Mul),
                (x => x.OpCode.Code == Code.Ldc_I8),
            };
            var stackvals     = new List <dynamic>();
            var updatedValues = new List <Tuple <Instruction, Instruction[], Instruction> >();

            for (var i = 0; i < method.Body.Instructions.Count; i++)
            {
                var         instr = method.Body.Instructions[i];
                Instruction ender;
                int         size;

                if (!instr.IsLdcI4() && instr.OpCode.Code != Code.Ldc_I8)
                {
                    continue;
                }
                if (!instr.FollowsPattern(method.Body, out ender, pattern, 2, out size))
                {
                    continue;
                }

                var st = new ILEmulator(method.Body, method.Body.Instructions.Count);
                try
                {
                    st.EmulateUntil(ender.Next(method.Body), method.Body, instr);
                    var fakedVal = false;
                    if (st.Stack.Count > 1)
                    {
                        if (instr.Previous(method.Body).OpCode.StackBehaviourPush != StackBehaviour.Push1)
                        {
                            fakedVal = true;
                            stackvals.Add((dynamic)st.Stack.Reverse().ToList()[0].Value);
                        }
                        else
                        {
                            continue;
                        }
                    }
                    else
                    {
                        stackvals.Add((dynamic)st.Stack.Peek().Value);
                    }
                    var oldInstr  = instr.Next(method.Body);
                    var badInstrs = new Instruction[size - 1];
                    for (int j = i, x = 0; j < size + i - 1; j++, x++)
                    {
                        badInstrs[x] = oldInstr;
                        oldInstr     = oldInstr.Next(method.Body);
                    }
                    if (fakedVal)
                    {
                        dynamic val = st.Stack.ToList().Last().Value;
                        if (val is int)
                        {
                            updatedValues.Add(Tuple.Create(instr, badInstrs,
                                                           Instruction.CreateLdcI4(val)));
                        }
                        else
                        {
                            updatedValues.Add(Tuple.Create(instr, badInstrs,
                                                           Instruction.Create(OpCodes.Ldc_I8, (long)val)));
                        }
                        badInstrs[badInstrs.Length - 1] = null;
                    }
                    else
                    {
                        dynamic val = st.Stack.ToList().Last().Value;
                        if (val is int)
                        {
                            updatedValues.Add(Tuple.Create(instr, badInstrs,
                                                           Instruction.CreateLdcI4(val)));
                        }
                        else if (val != null)
                        {
                            updatedValues.Add(Tuple.Create(instr, badInstrs,
                                                           Instruction.Create(OpCodes.Ldc_I8, (long)val)));
                        }
                    }
                    i += size;
                }
                catch (InvalidOperationException)
                {
                }
            }
            foreach (var @new in updatedValues)
            {
                method.Body.SimplifyBranches();

                var initIdx = @new.Item1.GetInstructionIndex(method.Body.Instructions);
                if (@new.Item1.IsLdcI4())
                {
                    if (@new.Item1.GetLdcI4Value() == @new.Item3.GetLdcI4Value())
                    {
                        continue;
                    }
                }
                else
                if ((dynamic)@new.Item1.Operand == (dynamic)@new.Item3.Operand)
                {
                    continue;
                }

                var removedInstructions = new Instruction[@new.Item2.Count(x => x != null) + 1];
                var idx = 0;
                foreach (var instr in @new.Item2.Where(instr => instr != null))
                {
                    removedInstructions[idx++] = instr;
                    method.Body.Instructions.Remove(instr);
                }

                method.Body.Instructions.Insert(initIdx, @new.Item3);
                method.Body.Instructions.Remove(@new.Item1);
                method.Body.OptimizeBranches();

                removedInstructions[removedInstructions.Length - 1] = @new.Item1;
                RemovedInstructions.Add(Tuple.Create(method, removedInstructions));
            }
        }