Exemple #1
0
        bool FindEntryPointToken(ISimpleDeobfuscator simpleDeobfuscator, MethodDef cctor, MethodDef entryPoint, out uint token)
        {
            token = 0;
            if (!FindBase(cctor, out ulong @base))
            {
                return(false);
            }

            var modPowMethod = DotNetUtils.GetMethod(cctor.DeclaringType, "System.UInt64", "(System.UInt64,System.UInt64,System.UInt64)");

            if (modPowMethod == null)
            {
                throw new ApplicationException("Could not find modPow()");
            }

            simpleDeobfuscator.Deobfuscate(entryPoint);
            if (!FindMod(entryPoint, out ulong mod))
            {
                throw new ApplicationException("Could not find modulus");
            }

            token = 0x06000000 | (uint)ModPow(@base, 0x47, mod);
            if ((token >> 24) != 0x06)
            {
                throw new ApplicationException("Illegal entry point token");
            }
            return(true);
        }
        public void FindDelegateCreator(ModuleDefMD module)
        {
            var callCounter = new CallCounter();

            foreach (var type in module.Types)
            {
                if (type.Namespace != "" || !DotNetUtils.DerivesFromDelegate(type))
                {
                    continue;
                }
                var cctor = type.FindStaticConstructor();
                if (cctor == null)
                {
                    continue;
                }
                foreach (var method in DotNetUtils.GetMethodCalls(cctor))
                {
                    callCounter.Add(method);
                }
            }

            var mostCalls = callCounter.Most();

            if (mostCalls == null)
            {
                return;
            }

            SetDelegateCreatorMethod(DotNetUtils.GetMethod(module, mostCalls));
        }
Exemple #3
0
        public void Find()
        {
            foreach (var type in module.Types)
            {
                if (type.HasFields || type.HasEvents || type.HasProperties)
                {
                    continue;
                }

                var checkMethod = GetAntiTamperingDetectionMethod(type);
                if (checkMethod == null)
                {
                    continue;
                }

                if (DotNetUtils.GetMethod(type, "System.Byte[]", "(System.Reflection.Assembly)") == null)
                {
                    continue;
                }
                if (DotNetUtils.GetMethod(type, "System.String", "(System.Collections.Generic.Stack`1<System.Int32>)") == null)
                {
                    continue;
                }
                if (DotNetUtils.GetMethod(type, "System.Int32", "(System.Int32,System.Byte[])") == null)
                {
                    continue;
                }

                strongNameType        = type;
                strongNameCheckMethod = checkMethod;
                return;
            }
        }
Exemple #4
0
        TypeDef FindMethodsDecrypterType(TypeDef type)
        {
            foreach (var field in type.Fields)
            {
                var fieldType = DotNetUtils.GetType(module, field.FieldSig.GetFieldType());
                if (fieldType == null)
                {
                    continue;
                }
                if (fieldType.FindMethod("Finalize") == null)
                {
                    continue;
                }
                if (!new FieldTypes(fieldType).Exists("System.Collections.Hashtable"))
                {
                    continue;
                }
                if (DotNetUtils.GetMethod(fieldType, "System.String", "()") == null)
                {
                    continue;
                }

                return(fieldType);
            }

            return(null);
        }
Exemple #5
0
            public static bool CouldBeResourceDecrypter(MethodDef method, LocalTypes localTypes, IList <string> additionalTypes)
            {
                var requiredTypes = new List <string> {
                    "System.Byte[]",
                    "System.IO.BinaryReader",
                    "System.IO.MemoryStream",
                    "System.Security.Cryptography.CryptoStream",
                    "System.Security.Cryptography.ICryptoTransform",
                };

                requiredTypes.AddRange(additionalTypes);
                if (!localTypes.All(requiredTypes))
                {
                    return(false);
                }

                if (DotNetUtils.GetMethod(method.DeclaringType, "System.Security.Cryptography.SymmetricAlgorithm", "()") != null)
                {
                    if (localTypes.Exists("System.UInt64") || (localTypes.Exists("System.UInt32") && !localTypes.Exists("System.Reflection.Assembly")))
                    {
                        return(false);
                    }
                }

                if (!localTypes.Exists("System.Security.Cryptography.RijndaelManaged") &&
                    !localTypes.Exists("System.Security.Cryptography.AesManaged") &&
                    !localTypes.Exists("System.Security.Cryptography.SymmetricAlgorithm"))
                {
                    return(false);
                }

                return(true);
            }
Exemple #6
0
        bool CheckMethods(TypeDef type)
        {
            methodI4    = DotNetUtils.GetMethod(type, "System.Int32", "(System.Int32)");
            methodI8    = DotNetUtils.GetMethod(type, "System.Int64", "(System.Int32)");
            methodR4    = DotNetUtils.GetMethod(type, "System.Single", "(System.Int32)");
            methodR8    = DotNetUtils.GetMethod(type, "System.Double", "(System.Int32)");
            methodArray = DotNetUtils.GetMethod(type, "System.Void", "(System.Array,System.Int32)");

            return(methodI4 != null && methodI8 != null &&
                   methodR4 != null && methodR8 != null &&
                   methodArray != null);
        }
        public static bool FindRegisterMethod(TypeDef type, out MethodDef regMethod, out MethodDef handler)
        {
            foreach (var method in type.Methods)
            {
                if (!method.IsStatic || method.Body == null)
                {
                    continue;
                }
                if (method.Body.ExceptionHandlers.Count != 1)
                {
                    continue;
                }

                foreach (var instr in method.Body.Instructions)
                {
                    if (instr.OpCode.Code != Code.Ldftn)
                    {
                        continue;
                    }
                    var handlerRef = instr.Operand as IMethod;
                    if (handlerRef == null)
                    {
                        continue;
                    }
                    if (!DotNetUtils.IsMethod(handlerRef, "System.Reflection.Assembly", "(System.Object,System.ResolveEventArgs)"))
                    {
                        continue;
                    }
                    if (!new SigComparer().Equals(type, handlerRef.DeclaringType))
                    {
                        continue;
                    }
                    handler = DotNetUtils.GetMethod(type, handlerRef);
                    if (handler == null)
                    {
                        continue;
                    }
                    if (handler.Body == null || handler.Body.ExceptionHandlers.Count != 1)
                    {
                        continue;
                    }

                    regMethod = method;
                    return(true);
                }
            }

            regMethod = null;
            handler   = null;
            return(false);
        }
Exemple #8
0
        bool CheckMethod(MethodDef method, out MethodDef exceptionMethod)
        {
            exceptionMethod = null;

            var body = method.Body;

            if (body == null)
            {
                return(false);
            }
            var instrs = body.Instructions;

            if (instrs.Count < 1)
            {
                return(false);
            }
            if (body.ExceptionHandlers.Count == 0)
            {
                return(false);
            }
            var eh = body.ExceptionHandlers[body.ExceptionHandlers.Count - 1];

            if (eh.HandlerType != ExceptionHandlerType.Catch)
            {
                return(false);
            }
            if (eh.FilterStart != null)
            {
                return(false);
            }
            if (eh.CatchType == null || eh.CatchType.FullName != "System.Exception")
            {
                return(false);
            }
            if (eh.HandlerStart == null)
            {
                return(false);
            }

            int handlerStart = instrs.IndexOf(eh.HandlerStart);
            int handlerEnd   = eh.HandlerEnd == null ? instrs.Count : instrs.IndexOf(eh.HandlerEnd);

            exceptionMethod = DotNetUtils.GetMethod(module, CheckHandler(instrs, handlerStart, handlerEnd));
            if (exceptionMethod == null || !exceptionMethod.IsStatic || exceptionMethod.Body == null)
            {
                return(false);
            }

            return(IsExceptionLoggerMethod(exceptionMethod));
        }
        public void Deobfuscate(Blocks blocks)
        {
            if (type == null)
            {
                return;
            }

            var gpContext = GenericParamContext.Create(blocks.Method);

            foreach (var block in blocks.MethodBlocks.GetAllBlocks())
            {
                var instrs = block.Instructions;
                for (int i = 0; i < instrs.Count - 1; i++)
                {
                    var instr = instrs[i];
                    if (instr.OpCode.Code != Code.Ldc_I4)
                    {
                        continue;
                    }
                    var call = instrs[i + 1];
                    if (call.OpCode.Code != Code.Call)
                    {
                        continue;
                    }
                    var method = call.Operand as IMethod;
                    if (method == null)
                    {
                        continue;
                    }
                    if (!new SigComparer().Equals(type, method.DeclaringType))
                    {
                        continue;
                    }
                    var methodDef = DotNetUtils.GetMethod(module, method);
                    if (methodDef == null)
                    {
                        continue;
                    }
                    if (methodDef != typeMethod && methodDef != fieldMethod)
                    {
                        continue;
                    }

                    uint token = (uint)(int)instrs[i].Operand;
                    instrs[i]     = new Instr(OpCodes.Nop.ToInstruction());
                    instrs[i + 1] = new Instr(new Instruction(OpCodes.Ldtoken, module.ResolveToken(token, gpContext) as ITokenOperand));
                }
            }
        }
Exemple #10
0
        Version DetectVersion()
        {
            var ep = Module.EntryPoint;

            if (ep == null || ep.Body == null)
            {
                return(Version.Unknown);
            }
            var type = ep.DeclaringType;

            if (type == null)
            {
                return(Version.Unknown);
            }
            if (!new FieldTypes(type).Exactly(requiredFields))
            {
                return(Version.Unknown);
            }
            if (Module.Types.Count != 2)
            {
                return(Version.Unknown);
            }
            if (Module.Types[1] != type)
            {
                return(Version.Unknown);
            }
            if (Module.Types[0].Methods.Count != 0)
            {
                return(Version.Unknown);
            }

            if (CheckMethods(type, methods_v0x))
            {
                return(Version.V0x);
            }
            if (CheckMethods(type, methods_v1x))
            {
                var lfMethod = DotNetUtils.GetMethod(type, "System.Boolean", "(System.String,System.Byte[]&)");
                if (lfMethod != null)
                {
                    if (DeobUtils.HasInteger(lfMethod, (int)Machine.AMD64))
                    {
                        return(Version.V218);
                    }
                    return(Version.V1x_217);
                }
            }
            return(Version.Unknown);
        }
        IEnumerable <MethodDef> GetResolverHandlers(MethodDef method)
        {
            int numHandlers  = 0;
            var instructions = method.Body.Instructions;

            for (int i = 0; i < instructions.Count; i++)
            {
                var instrs = DotNetUtils.GetInstructions(instructions, i, OpCodes.Call, OpCodes.Ldnull, OpCodes.Ldftn, OpCodes.Newobj, OpCodes.Callvirt);
                if (instrs == null)
                {
                    continue;
                }

                var call = instrs[0];
                if (!DotNetUtils.IsMethod(call.Operand as IMethod, "System.AppDomain", "()"))
                {
                    continue;
                }

                var ldftn      = instrs[2];
                var handlerDef = DotNetUtils.GetMethod(module, ldftn.Operand as IMethod);
                if (handlerDef == null)
                {
                    continue;
                }

                var newobj = instrs[3];
                if (!DotNetUtils.IsMethod(newobj.Operand as IMethod, "System.Void", "(System.Object,System.IntPtr)"))
                {
                    continue;
                }

                var callvirt = instrs[4];
                if (!DotNetUtils.IsMethod(callvirt.Operand as IMethod, "System.Void", "(System.ResolveEventHandler)"))
                {
                    continue;
                }

                numHandlers++;
                yield return(handlerDef);
            }

            // If no handlers found, it's possible that the method itself is the handler.
            if (numHandlers == 0)
            {
                yield return(method);
            }
        }
        public IMethod TryGetMethodDef(IMethod methodRef)
        {
            var methodDef = methodRef as MethodDef;

            if (methodDef != null)
            {
                return(methodDef);
            }

            var declaringType = DotNetUtils.GetType(module, methodRef.DeclaringType);

            if (declaringType == null)
            {
                return(methodRef);
            }
            return(DotNetUtils.GetMethod(declaringType, methodRef));
        }
Exemple #13
0
        public void Find()
        {
            foreach (var type in module.Types)
            {
                if (!IsConstantDecrypter(type))
                {
                    continue;
                }

                int32Decrypter  = DotNetUtils.GetMethod(type, "System.Int32", "(System.Int32)");
                int64Decrypter  = DotNetUtils.GetMethod(type, "System.Int64", "(System.Int32)");
                singleDecrypter = DotNetUtils.GetMethod(type, "System.Single", "(System.Int32)");
                doubleDecrypter = DotNetUtils.GetMethod(type, "System.Double", "(System.Int32)");
                arrayDecrypter  = DotNetUtils.GetMethod(type, "System.Array", "(System.Byte[])");
                decrypterType   = type;
                return;
            }
        }
Exemple #14
0
        void FindResourceType()
        {
            var cctor = DotNetUtils.GetModuleTypeCctor(module);

            if (cctor == null)
            {
                return;
            }

            foreach (var calledMethod in DotNetUtils.GetCalledMethods(module, cctor))
            {
                if (!calledMethod.IsStatic || calledMethod.Body == null)
                {
                    continue;
                }
                if (!DotNetUtils.IsMethod(calledMethod, "System.Void", "()"))
                {
                    continue;
                }
                var type       = calledMethod.DeclaringType;
                var fieldTypes = new FieldTypes(type);
                if (!fieldTypes.Exactly(requiredFields1) &&
                    !fieldTypes.Exactly(requiredFields2))
                {
                    continue;
                }

                var resolveHandler = DotNetUtils.GetMethod(type, "System.Reflection.Assembly", "(System.Object,System.ResolveEventArgs)");
                var decryptMethod  = DotNetUtils.GetMethod(type, "System.Byte[]", "(System.IO.Stream)");
                if (resolveHandler == null || !resolveHandler.IsStatic)
                {
                    continue;
                }
                if (decryptMethod == null || !decryptMethod.IsStatic)
                {
                    continue;
                }

                rsrcType          = type;
                rsrcRrrMethod     = calledMethod;
                rsrcResolveMethod = resolveHandler;
                return;
            }
        }
Exemple #15
0
        bool IsConstantDecrypter(TypeDef type)
        {
            if (type.HasEvents)
            {
                return(false);
            }
            if (type.NestedTypes.Count != 1)
            {
                return(false);
            }

            var nested = type.NestedTypes[0];

            if (!CheckNestedFields(nested))
            {
                return(false);
            }

            resourceDecrypter.DecryptMethod = ResourceDecrypter.FindDecrypterMethod(nested.FindMethod(".ctor"));

            if (DotNetUtils.GetMethod(type, "System.Int32", "(System.Int32)") == null)
            {
                return(false);
            }
            if (DotNetUtils.GetMethod(type, "System.Int64", "(System.Int32)") == null)
            {
                return(false);
            }
            if (DotNetUtils.GetMethod(type, "System.Single", "(System.Int32)") == null)
            {
                return(false);
            }
            if (DotNetUtils.GetMethod(type, "System.Double", "(System.Int32)") == null)
            {
                return(false);
            }
            if (DotNetUtils.GetMethod(type, "System.Array", "(System.Byte[])") == null)
            {
                return(false);
            }

            return(true);
        }
Exemple #16
0
        public static bool IsSimpleZipDecryptMethod_QuickCheck(ModuleDefMD module, IMethod method, out MethodDef simpleZipTypeMethod)
        {
            simpleZipTypeMethod = null;

            if (!DotNetUtils.IsMethod(method, "System.Byte[]", "(System.Byte[])"))
            {
                return(false);
            }

            var methodDef = DotNetUtils.GetMethod(DotNetUtils.GetType(module, method.DeclaringType), method);

            if (methodDef == null)
            {
                return(false);
            }

            simpleZipTypeMethod = methodDef;
            return(true);
        }
Exemple #17
0
        bool CheckType(TypeDef type)
        {
            if (DotNetUtils.GetMethod(type, "System.Byte[]", "(System.Byte[],System.String,System.String,System.Int32,System.String,System.Int32)") == null)
            {
                return(false);
            }
            if (DotNetUtils.GetMethod(type, "System.String", "(System.String)") == null)
            {
                return(false);
            }
            if (DotNetUtils.GetMethod(type, "System.Byte[]", "(System.Reflection.Assembly,System.String)") == null)
            {
                return(false);
            }
            if (DotNetUtils.GetMethod(type, "System.Void", "(System.IO.Stream,System.IO.Stream)") == null)
            {
                return(false);
            }

            return(true);
        }
Exemple #18
0
        public void Find()
        {
            var requiredFields = new string[] {
                "System.Threading.ReaderWriterLock",
                "System.Collections.Hashtable",
            };

            foreach (var type in module.GetTypes())
            {
                var fieldTypes = new FieldTypes(type);
                if (!fieldTypes.All(requiredFields))
                {
                    continue;
                }
                if (type.FindMethod("Finalize") == null)
                {
                    continue;
                }
                var executeMethod = DotNetUtils.GetMethod(type, "System.Object", "(System.String,System.Object[])");
                if (executeMethod == null || !executeMethod.IsStatic || executeMethod.Body == null)
                {
                    continue;
                }

                var decrypterType = FindMethodsDecrypterType(type);
                if (decrypterType == null)
                {
                    continue;
                }

                resourceDecrypter.DecryptMethod = FindDecryptMethod(decrypterType);

                methodsDecrypterCreator = type;
                methodsDecrypter        = decrypterType;
                decryptExecuteMethod    = executeMethod;
                return;
            }
        }
Exemple #19
0
        bool FindFirstBlocks(Block block, TamperBlocks tamperBlocks, IList <Block> allBlocks, IList <Local> locals)
        {
            if (!block.LastInstr.IsBrfalse())
            {
                return(false);
            }

            /*
             * ldc.i4.0
             * stloc X
             * call GetExecutingAssembly()
             * stloc Y
             * ldloc Y
             * callvirt Location
             * ldc.i4.1
             * ldloca X
             * call StrongNameSignatureVerificationEx
             * pop / brfalse bad_code
             * ldloc X
             * brfalse bad_code
             * ldloc Y
             * callvirt FullName()
             * ldstr "......"
             * callvirt EndsWith(string)
             * brfalse bad_code / brtrue good_code
             */

            var     instrs = block.Instructions;
            int     end    = instrs.Count - 1;
            Instr   instr;
            IMethod method;

            tamperBlocks.type = Type.V1;

            int index = 0;

            int start = FindCallMethod(block, index, true, (calledMethod) => calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetExecutingAssembly()");

            if (start < 0)
            {
                return(false);
            }
            index = start + 1;
            instr = instrs[--start];
            if (!instr.IsStloc())
            {
                return(false);
            }
            var loc0 = Instr.GetLocalVar(locals, instr);

            instr = instrs[--start];
            if (!instr.IsLdcI4())
            {
                return(false);
            }

            index = FindCallMethod(block, index, false, (calledMethod) => calledMethod.ToString() == "System.String System.Reflection.Assembly::get_Location()");
            if (index < 0)
            {
                return(false);
            }
            index++;

            index = FindCallMethod(block, index, false, (calledMethod) => {
                tamperBlocks.pinvokeMethod = DotNetUtils.GetMethod(module, calledMethod);
                return(DotNetUtils.IsPinvokeMethod(tamperBlocks.pinvokeMethod, "mscorwks", "StrongNameSignatureVerificationEx"));
            });
            if (index < 0)
            {
                return(false);
            }
            index++;

            if (!instrs[index].IsBrfalse())
            {
                if (instrs[index].OpCode.Code != Code.Pop)
                {
                    return(false);
                }
                instr = instrs[index + 1];
                if (!instr.IsLdloc() || Instr.GetLocalVar(locals, instr) != loc0)
                {
                    return(false);
                }
                if (!instrs[index + 2].IsBrfalse())
                {
                    return(false);
                }

                tamperBlocks.type  = Type.V1;
                tamperBlocks.first = new BlockInfo {
                    Block = block,
                    Start = start,
                    End   = end,
                };
            }
            else
            {
                tamperBlocks.type  = Type.V2;
                tamperBlocks.first = new BlockInfo {
                    Block = block,
                    Start = start,
                    End   = end,
                };

                block = block.FallThrough;
                if (block == null)
                {
                    return(false);
                }
                instrs = block.Instructions;
                index  = 0;
                instr  = instrs[index];
                if (!instr.IsLdloc() || Instr.GetLocalVar(locals, instr) != loc0)
                {
                    return(false);
                }
                if (!instrs[index + 1].IsBrfalse())
                {
                    return(false);
                }
            }

            block  = block.FallThrough;
            instrs = block.Instructions;
            start  = end = 0;

            instr = instrs[end++];
            if (!instr.IsLdloc())
            {
                return(false);
            }

            instr = instrs[end++];
            if (instr.OpCode != OpCodes.Callvirt)
            {
                return(false);
            }
            method = instr.Operand as IMethod;
            if (method == null || method.ToString() != "System.String System.Reflection.Assembly::get_FullName()")
            {
                return(false);
            }

            instr = instrs[end++];
            if (instr.OpCode != OpCodes.Ldstr)
            {
                return(false);
            }

            instr = instrs[end++];
            if (instr.OpCode != OpCodes.Callvirt)
            {
                return(false);
            }
            method = instr.Operand as IMethod;
            if (method == null || method.ToString() != "System.Boolean System.String::EndsWith(System.String)")
            {
                return(false);
            }

            instr = instrs[end++];
            if (!instr.IsBrfalse() && !instr.IsBrtrue())
            {
                return(false);
            }

            end--;
            tamperBlocks.second = new BlockInfo {
                Block = block,
                Start = start,
                End   = end,
            };

            return(true);
        }
        IDecrypterInfo CheckNested(TypeDef type, TypeDef nested)
        {
            if (nested.HasProperties || nested.HasEvents)
            {
                return(null);
            }

            if (nested.FindMethod(".ctor") == null)
            {
                return(null);
            }

            if (nested.Fields.Count == 1 || nested.Fields.Count == 3)
            {
                // 4.0+

                if (!HasFieldType(nested.Fields, nested))
                {
                    return(null);
                }

                var decrypterBuilderMethod = DotNetUtils.GetMethod(nested, "System.Reflection.Emit.MethodBuilder", "(System.Reflection.Emit.TypeBuilder)");
                if (decrypterBuilderMethod == null)
                {
                    return(null);
                }

                resourceDecrypter.DecryptMethod = ResourceDecrypter.FindDecrypterMethod(nested.FindMethod(".ctor"));

                var nestedDecrypter = DotNetUtils.GetMethod(nested, "System.String", "(System.Int32)");
                if (nestedDecrypter == null || nestedDecrypter.IsStatic)
                {
                    return(null);
                }
                var decrypter = DotNetUtils.GetMethod(type, "System.String", "(System.Int32)");
                if (decrypter == null || !decrypter.IsStatic)
                {
                    return(null);
                }

                simpleDeobfuscator.Deobfuscate(decrypterBuilderMethod);
                return(new DecrypterInfoV3(resourceDecrypter)
                {
                    Decrypter = decrypter,
                    OffsetCalcInstructions = GetOffsetCalcInstructions(decrypterBuilderMethod),
                });
            }
            else if (nested.Fields.Count == 2)
            {
                // 3.0 - 3.5

                if (CheckFields(nested, "System.Collections.Hashtable", nested))
                {
                    // 3.0 - 3.5
                    var nestedDecrypter = DotNetUtils.GetMethod(nested, "System.String", "(System.Int32)");
                    if (nestedDecrypter == null || nestedDecrypter.IsStatic)
                    {
                        return(null);
                    }
                    var decrypter = DotNetUtils.GetMethod(type, "System.String", "(System.Int32)");
                    if (decrypter == null || !decrypter.IsStatic)
                    {
                        return(null);
                    }

                    resourceDecrypter.DecryptMethod = ResourceDecrypter.FindDecrypterMethod(nested.FindMethod(".ctor"));

                    return(new DecrypterInfoV3(resourceDecrypter)
                    {
                        Decrypter = decrypter
                    });
                }
                else if (CheckFields(nested, "System.Byte[]", nested))
                {
                    // 3.0
                    var nestedDecrypter = DotNetUtils.GetMethod(nested, "System.String", "(System.String,System.Int32)");
                    if (nestedDecrypter == null || nestedDecrypter.IsStatic)
                    {
                        return(null);
                    }
                    var decrypter = DotNetUtils.GetMethod(type, "System.String", "(System.String,System.Int32)");
                    if (decrypter == null || !decrypter.IsStatic)
                    {
                        return(null);
                    }

                    return(new DecrypterInfoV2 {
                        Decrypter = decrypter
                    });
                }
                else
                {
                    return(null);
                }
            }

            return(null);
        }