예제 #1
0
 bool CallsMethod(MethodDef methodToCheck, MethodDef calledMethod)
 {
     foreach (var method in DotNetUtils.GetCalledMethods(module, methodToCheck))
     {
         if (method == calledMethod)
         {
             return(true);
         }
     }
     return(false);
 }
예제 #2
0
        public void Find()
        {
            var additionalTypes = new string[] {
                "System.IntPtr",
//				"System.Reflection.Assembly",		//TODO: Not in unknown DNR version with jitter support
            };
            var checkedMethods = new Dictionary <IMethod, bool>(MethodEqualityComparer.CompareDeclaringTypes);
            var callCounter    = new CallCounter();
            int typesLeft      = 30;

            foreach (var type in module.GetTypes())
            {
                var cctor = type.FindStaticConstructor();
                if (cctor == null || cctor.Body == null)
                {
                    continue;
                }
                if (typesLeft-- <= 0)
                {
                    break;
                }

                foreach (var method in DotNetUtils.GetCalledMethods(module, cctor))
                {
                    if (!checkedMethods.ContainsKey(method))
                    {
                        checkedMethods[method] = false;
                        if (method.DeclaringType.BaseType == null || method.DeclaringType.BaseType.FullName != "System.Object")
                        {
                            continue;
                        }
                        if (!DotNetUtils.IsMethod(method, "System.Void", "()"))
                        {
                            continue;
                        }
                        if (!encryptedResource.CouldBeResourceDecrypter(method, additionalTypes))
                        {
                            continue;
                        }
                        checkedMethods[method] = true;
                    }
                    else if (!checkedMethods[method])
                    {
                        continue;
                    }
                    callCounter.Add(method);
                }
            }

            encryptedResource.Method = (MethodDef)callCounter.Most();
        }
예제 #3
0
 // The main decrypter type calls the string decrypter init method inside its init method
 void FindV5(MethodDef method)
 {
     if (!mainType.Detected)
     {
         return;
     }
     foreach (var calledMethod in DotNetUtils.GetCalledMethods(module, mainType.InitMethod))
     {
         if (Find(calledMethod))
         {
             return;
         }
     }
 }
예제 #4
0
        string GetPassword2(MethodDef method)
        {
            string password = "";

            foreach (var calledMethod in DotNetUtils.GetCalledMethods(module, method))
            {
                var s = GetPassword3(calledMethod);
                if (string.IsNullOrEmpty(s))
                {
                    return(null);
                }

                password += s;
            }
            return(password);
        }
예제 #5
0
        bool Find(MethodDef methodToCheck)
        {
            if (methodToCheck == null)
            {
                return(false);
            }
            foreach (var method in DotNetUtils.GetCalledMethods(module, methodToCheck))
            {
                var type = method.DeclaringType;

                if (!method.IsStatic || !DotNetUtils.IsMethod(method, "System.Void", "()"))
                {
                    continue;
                }
                if (DotNetUtils.GetPInvokeMethod(type, "kernel32", "LoadLibrary") == null)
                {
                    continue;
                }
                if (DotNetUtils.GetPInvokeMethod(type, "kernel32", "GetProcAddress") == null)
                {
                    continue;
                }
                Deobfuscate(method);
                if (!ContainsString(method, "debugger is activ") &&
                    !ContainsString(method, "debugger is running") &&
                    !ContainsString(method, "Debugger detected") &&
                    !ContainsString(method, "Debugger was detected") &&
                    !ContainsString(method, "{0} was detected") &&
                    !ContainsString(method, "run under") &&
                    !ContainsString(method, "run with") &&
                    !ContainsString(method, "started under") &&
                    !ContainsString(method, "{0} detected") &&
                    !ContainsString(method, "{0} was found - this software cannot be executed") &&
                    !ContainsString(method, "{0} found"))
                {
                    continue;
                }

                antiDebuggerType   = type;
                antiDebuggerMethod = method;
                return(true);
            }

            return(false);
        }
예제 #6
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;
            }
        }
예제 #7
0
        void Initialize()
        {
            var callCounter = new CallCounter();
            int count       = 0;

            foreach (var type in module.GetTypes())
            {
                if (count >= 40)
                {
                    break;
                }
                foreach (var method in type.Methods)
                {
                    if (method.Name != ".ctor" && method.Name != ".cctor" && module.EntryPoint != method)
                    {
                        continue;
                    }
                    foreach (var calledMethod in DotNetUtils.GetCalledMethods(module, method))
                    {
                        if (!calledMethod.IsStatic || calledMethod.Body == null)
                        {
                            continue;
                        }
                        if (!DotNetUtils.IsMethod(calledMethod, "System.Void", "()"))
                        {
                            continue;
                        }
                        if (IsEmptyClass(calledMethod))
                        {
                            callCounter.Add(calledMethod);
                            count++;
                        }
                    }
                }
            }

            int numCalls;
            var theMethod = (MethodDef)callCounter.Most(out numCalls);

            if (numCalls >= 10)
            {
                emptyMethod = theMethod;
            }
        }
예제 #8
0
        MethodDef GetResourceDecrypterInitMethod(MethodDef method, string[] additionalTypes, bool checkResource)
        {
            if (encryptedResource.CouldBeResourceDecrypter(method, additionalTypes, checkResource))
            {
                return(method);
            }

            foreach (var calledMethod in DotNetUtils.GetCalledMethods(module, method))
            {
                if (!DotNetUtils.IsMethod(calledMethod, "System.Void", "()"))
                {
                    continue;
                }
                if (encryptedResource.CouldBeResourceDecrypter(calledMethod, additionalTypes, checkResource))
                {
                    return(calledMethod);
                }
            }

            return(null);
        }
예제 #9
0
        /// <summary>
        /// Check if a called method's body contains the given pattern (can be improved).
        /// </summary>
        /// <param name="codePattern">Pattern to search for in called method</param>
        /// <remarks>
        /// Looks like: [static] ??? method(Value, Value)
        /// </remarks>
        /// <returns>true if match, false if not</returns>
        public Boolean MatchesIndirect(IList <Code> codePattern)
        {
            this.CheckDelegateMethod();

            var called       = DotNetUtils.GetCalledMethods(this.Parent.Module, this.DelegateMethod);
            var targetMethod = called.FirstOrDefault((m) => {
                return((!m.IsStatic && m.Parameters.Count == 3 &&
                        m.Parameters[1].Type.FullName.Equals(m.Parameters[2].Type.FullName)) ||
                       (m.IsStatic && m.Parameters.Count == 2 &&
                        m.Parameters[0].Type.FullName.Equals(m.Parameters[1].Type.FullName)));
            });

            if (targetMethod != null)
            {
                return(Helpers.FindOpCodePatterns(targetMethod.Body.Instructions, codePattern).Count > 0);
            }
            else
            {
                return(false);
            }
        }
        bool CallsMainTypeTamperCheckMethod(MethodDef method)
        {
            foreach (var calledMethod in DotNetUtils.GetCalledMethods(module, method))
            {
                if (calledMethod == mainType.TamperCheckMethod)
                {
                    return(true);
                }
            }

            var instructions = method.Body.Instructions;

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

                if (!CheckInvokeCall(instrs[1], "System.Type", "(System.RuntimeTypeHandle)"))
                {
                    continue;
                }
                if (!CheckInvokeCall(instrs[2], "System.Reflection.Assembly", "(System.Object)"))
                {
                    continue;
                }
                if (!CheckInvokeCall(instrs[4], "System.Void", "(System.Reflection.Assembly,System.UInt64)"))
                {
                    continue;
                }

                return(true);
            }

            return(false);
        }
예제 #11
0
        /// <summary>
        /// Check if a called method's body contains the given pattern, and that the called
        /// method is given two Booleans of specific values as the third and fourth arguments.
        /// </summary>
        /// <param name="val1">First Boolean value to expect</param>
        /// <param name="val2">Second Boolean value to expect</param>
        /// <param name="codePattern">Pattern to search for in called method</param>
        /// <remarks>
        /// Looks like: [static] ??? method(Value, Value, Boolean, Boolean)
        /// </remarks>
        /// <returns>true if match, false if not</returns>
        public Boolean MatchesIndirectWithBoolean2(Boolean val1, Boolean val2, IList <Code> codePattern)
        {
            this.CheckDelegateMethod();

            var called       = DotNetUtils.GetCalledMethods(this.Parent.Module, this.DelegateMethod);
            var targetMethod = called.FirstOrDefault((m) =>
            {
                return(m.Parameters.Count == 5 &&
                       m.Parameters[3].Type.FullName.Equals("System.Boolean") &&
                       m.Parameters[4].Type.FullName.Equals("System.Boolean"));
            });

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

            // Expected values of ldc.i4 operands, loading the two bool values
            Int32 expected1 = val1 ? 1 : 0, expected2 = val2 ? 1 : 0;

            var instrs = this.DelegateMethod.Body.Instructions;

            for (Int32 i = 0; i < instrs.Count; i++)
            {
                var instr = instrs[i];

                if (instr.OpCode.Code == Code.Call && instr.Operand is MethodDef &&
                    ((MethodDef)instr.Operand).MDToken == targetMethod.MDToken &&
                    i > 1 && instrs[i - 1].IsLdcI4() && Helpers.GetLdcOperand(instrs[i - 1]) == expected2 &&
                    instrs[i - 2].IsLdcI4() && Helpers.GetLdcOperand(instrs[i - 2]) == expected1)
                {
                    // If we get here, we have the right method
                    return(Helpers.FindOpCodePatterns(targetMethod.Body.Instructions, codePattern).Count > 0);
                }
            }

            return(false);
        }
예제 #12
0
 ProxyCreatorType GetProxyCreatorType(MethodDef methodToCheck)
 {
     foreach (var calledMethod in DotNetUtils.GetCalledMethods(module, methodToCheck))
     {
         if (!calledMethod.IsStatic || calledMethod.Body == null)
         {
             continue;
         }
         if (!new SigComparer().Equals(methodToCheck.DeclaringType, calledMethod.DeclaringType))
         {
             continue;
         }
         if (DotNetUtils.IsMethod(calledMethod, "System.Void", "(System.Reflection.FieldInfo,System.Type,System.Reflection.MethodInfo)"))
         {
             return(ProxyCreatorType.CallOrCallvirt);
         }
         if (DotNetUtils.IsMethod(calledMethod, "System.Void", "(System.Reflection.FieldInfo,System.Type,System.Reflection.ConstructorInfo)"))
         {
             return(ProxyCreatorType.Newobj);
         }
     }
     return(ProxyCreatorType.None);
 }
예제 #13
0
        bool InitProxyType(Info infoTmp, MethodDef method)
        {
            foreach (var calledMethod in DotNetUtils.GetCalledMethods(module, method))
            {
                if (!calledMethod.IsStatic)
                {
                    continue;
                }
                if (!DotNetUtils.IsMethod(calledMethod, "System.Void", "(System.Int32)"))
                {
                    continue;
                }
                if (!CheckProxyType(infoTmp, calledMethod.DeclaringType))
                {
                    continue;
                }

                infoTmp.proxyType  = calledMethod.DeclaringType;
                infoTmp.initMethod = calledMethod;
                return(true);
            }
            return(false);
        }
예제 #14
0
        bool FindTypes(MethodDef initMethod)
        {
            if (initMethod == null)
            {
                return(false);
            }
            foreach (var method in DotNetUtils.GetCalledMethods(module, initMethod))
            {
                if (method.Name == ".cctor" || method.Name == ".ctor")
                {
                    continue;
                }
                if (!method.IsStatic || !DotNetUtils.IsMethod(method, "System.Void", "()"))
                {
                    continue;
                }
                if (CheckAttachAppMethod(method))
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #15
0
        bool Find(MethodDef methodToCheck)
        {
            if (methodToCheck == null)
            {
                return(false);
            }

            foreach (var method in DotNetUtils.GetCalledMethods(module, methodToCheck))
            {
                bool result = false;
                switch (frameworkType)
                {
                case FrameworkType.Desktop:
                    result = FindDesktop(method);
                    break;

                case FrameworkType.Silverlight:
                    result = FindSilverlight(method);
                    break;

                case FrameworkType.CompactFramework:
                    result = FindCompactFramework(method);
                    break;
                }
                if (!result)
                {
                    continue;
                }

                tamperType   = method.DeclaringType;
                tamperMethod = method;
                return(true);
            }

            return(false);
        }
예제 #16
0
        bool CheckMethod(ISimpleDeobfuscator simpleDeobfuscator, MethodDef methodToCheck)
        {
            if (methodToCheck == null)
            {
                return(false);
            }

            var resolverLocals = new string[] {
                "System.Byte[]",
                "System.Reflection.Assembly",
                "System.String",
                "System.IO.BinaryReader",
                "System.IO.Stream",
            };
            var resolverLocals2 = new string[] {
                "System.Reflection.Assembly",
                "System.IO.BinaryReader",
                "System.IO.Stream",
            };

            simpleDeobfuscator.Deobfuscate(methodToCheck);
            foreach (var method in DotNetUtils.GetCalledMethods(module, methodToCheck))
            {
                var type = method.DeclaringType;
                if (!DotNetUtils.IsMethod(method, "System.Void", "()"))
                {
                    continue;
                }
                if (!method.IsStatic)
                {
                    continue;
                }

                if (type.Fields.Count != 2 && type.Fields.Count != 3)
                {
                    continue;
                }
                if (type.HasNestedTypes)
                {
                    continue;
                }
                if (type.HasEvents || type.HasProperties)
                {
                    continue;
                }
                if (!CheckFields(type.Fields))
                {
                    continue;
                }

                var resolverMethod = FindAssemblyResolveMethod(type);
                if (resolverMethod == null)
                {
                    continue;
                }

                var localTypes = new LocalTypes(resolverMethod);
                if (!localTypes.All(resolverLocals) && !localTypes.All(resolverLocals2))
                {
                    continue;
                }

                assemblyResolverType       = type;
                assemblyResolverMethod     = resolverMethod;
                assemblyResolverInitMethod = method;
                return(true);
            }

            return(false);
        }
예제 #17
0
        void FindKeyIv(MethodDef method, out byte[] key, out byte[] iv)
        {
            key = null;
            iv  = null;

            var requiredTypes = new string[] {
                "System.Byte[]",
                "System.IO.MemoryStream",
                "System.Security.Cryptography.CryptoStream",
                "System.Security.Cryptography.Rijndael",
            };

            foreach (var calledMethod in DotNetUtils.GetCalledMethods(module, method))
            {
                if (calledMethod.DeclaringType != method.DeclaringType)
                {
                    continue;
                }
                if (calledMethod.MethodSig.GetRetType().GetFullName() != "System.Byte[]")
                {
                    continue;
                }
                var localTypes = new LocalTypes(calledMethod);
                if (!localTypes.All(requiredTypes))
                {
                    continue;
                }

                var    instructions = calledMethod.Body.Instructions;
                byte[] newKey       = null, newIv = null;
                for (int i = 0; i < instructions.Count && (newKey == null || newIv == null); i++)
                {
                    var instr = instructions[i];
                    if (instr.OpCode.Code != Code.Ldtoken)
                    {
                        continue;
                    }
                    var field = instr.Operand as FieldDef;
                    if (field == null)
                    {
                        continue;
                    }
                    if (field.InitialValue == null)
                    {
                        continue;
                    }
                    if (field.InitialValue.Length == 32)
                    {
                        newKey = field.InitialValue;
                    }
                    else if (field.InitialValue.Length == 16)
                    {
                        newIv = field.InitialValue;
                    }
                }
                if (newKey == null || newIv == null)
                {
                    continue;
                }

                InitializeStringDecrypterVersion(method);
                key = newKey;
                iv  = newIv;
                return;
            }
        }