bool CallsMethod(MethodDef methodToCheck, MethodDef calledMethod) { foreach (var method in DotNetUtils.GetCalledMethods(module, methodToCheck)) { if (method == calledMethod) { return(true); } } return(false); }
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(); }
// 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; } } }
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); }
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); }
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; } }
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; } }
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); }
/// <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); }
/// <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); }
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); }
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); }
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); }
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); }
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); }
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; } }