public MethodsDecrypter(ModuleDefMD module, MethodsDecrypter oldOne) { this.module = module; this.encryptedResource = new EncryptedResource(module, oldOne.encryptedResource); this.tokenToNativeMethod = oldOne.tokenToNativeMethod; this.totalEncryptedNativeMethods = oldOne.totalEncryptedNativeMethods; this.xorKey = oldOne.xorKey; }
string DetectVersion() { /* * Methods decrypter locals (not showing its own types): * 3.7.0.3: * "System.Byte[]" * "System.Int32" * "System.Int32[]" * "System.IntPtr" * "System.IO.BinaryReader" * "System.IO.MemoryStream" * "System.Object" * "System.Reflection.Assembly" * "System.Security.Cryptography.CryptoStream" * "System.Security.Cryptography.ICryptoTransform" * "System.Security.Cryptography.RijndaelManaged" * "System.String" * * 3.9.8.0: * - "System.Int32[]" + "System.Diagnostics.StackFrame" + + 4.0.0.0: (jitter) + - "System.Diagnostics.StackFrame" + - "System.Object" + "System.Boolean" + "System.Collections.IEnumerator" + "System.Delegate" + "System.Diagnostics.Process" + "System.Diagnostics.ProcessModule" + "System.Diagnostics.ProcessModuleCollection" + "System.IDisposable" + "System.Int64" + "System.UInt32" + "System.UInt64" + + 4.1.0.0: (jitter) + "System.Reflection.Assembly" + + 4.3.1.0: (jitter) + "System.Byte&" */ LocalTypes localTypes; int minVer = -1; foreach (var info in stringDecrypter.DecrypterInfos) { if (info.key == null) { continue; } localTypes = new LocalTypes(info.method); if (!localTypes.Exists("System.IntPtr")) { return(DeobfuscatorInfo.THE_NAME + " <= 3.7"); } minVer = 3800; break; } if (methodsDecrypter.Method == null) { if (minVer >= 3800) { return(DeobfuscatorInfo.THE_NAME + " >= 3.8"); } return(DeobfuscatorInfo.THE_NAME); } localTypes = new LocalTypes(methodsDecrypter.Method); if (localTypes.Exists("System.Int32[]")) { if (minVer >= 3800) { return(DeobfuscatorInfo.THE_NAME + " 3.8.4.1 - 3.9.0.1"); } return(DeobfuscatorInfo.THE_NAME + " <= 3.9.0.1"); } if (!localTypes.Exists("System.Diagnostics.Process")) // If < 4.0 { if (localTypes.Exists("System.Diagnostics.StackFrame")) { return(DeobfuscatorInfo.THE_NAME + " 3.9.8.0"); } } var compileMethod = MethodsDecrypter.FindDnrCompileMethod(methodsDecrypter.Method.DeclaringType); if (compileMethod == null) { DeobfuscatedFile.Deobfuscate(methodsDecrypter.Method); if (!MethodsDecrypter.IsNewer45Decryption(methodsDecrypter.Method)) { return(DeobfuscatorInfo.THE_NAME + " < 4.0"); } return(DeobfuscatorInfo.THE_NAME + " 4.5+"); } DeobfuscatedFile.Deobfuscate(compileMethod); bool compileMethodHasConstant_0x70000000 = DeobUtils.HasInteger(compileMethod, 0x70000000); // 4.0-4.1 DeobfuscatedFile.Deobfuscate(methodsDecrypter.Method); bool hasCorEnableProfilingString = FindString(methodsDecrypter.Method, "Cor_Enable_Profiling"); // 4.1-4.4 bool hasCatchString = FindString(methodsDecrypter.Method, "catch: "); // <= 4.7 if (compileMethodHasConstant_0x70000000) { if (hasCorEnableProfilingString) { return(DeobfuscatorInfo.THE_NAME + " 4.1"); } return(DeobfuscatorInfo.THE_NAME + " 4.0"); } if (!hasCorEnableProfilingString) { bool callsReverse = DotNetUtils.CallsMethod(methodsDecrypter.Method, "System.Void System.Array::Reverse(System.Array)"); if (!callsReverse) { return(DeobfuscatorInfo.THE_NAME + " 4.0 - 4.4"); } int numIntPtrSizeCompares = CountCompareSystemIntPtrSize(methodsDecrypter.Method); bool hasSymmetricAlgorithm = new LocalTypes(methodsDecrypter.Method).Exists("System.Security.Cryptography.SymmetricAlgorithm"); if (module.IsClr40) { switch (numIntPtrSizeCompares) { case 7: case 9: return(DeobfuscatorInfo.THE_NAME + " 4.5"); case 10: if (!hasSymmetricAlgorithm) { return(DeobfuscatorInfo.THE_NAME + " 4.6"); } if (hasCatchString) { return(DeobfuscatorInfo.THE_NAME + " 4.7"); } return(DeobfuscatorInfo.THE_NAME + " 4.8"); } } else { switch (numIntPtrSizeCompares) { case 6: case 8: return(DeobfuscatorInfo.THE_NAME + " 4.5"); case 9: if (!hasSymmetricAlgorithm) { return(DeobfuscatorInfo.THE_NAME + " 4.6"); } if (hasCatchString) { return(DeobfuscatorInfo.THE_NAME + " 4.7"); } return(DeobfuscatorInfo.THE_NAME + " 4.8"); } } // Should never be reached unless it's a new version return(DeobfuscatorInfo.THE_NAME + " 4.5+"); } // 4.2-4.4 if (!localTypes.Exists("System.Byte&")) { return(DeobfuscatorInfo.THE_NAME + " 4.2"); } localTypes = new LocalTypes(compileMethod); if (localTypes.Exists("System.Object")) { return(DeobfuscatorInfo.THE_NAME + " 4.4"); } return(DeobfuscatorInfo.THE_NAME + " 4.3"); }
protected override void ScanForObfuscator() { methodsDecrypter = new MethodsDecrypter(module); methodsDecrypter.Find(); stringDecrypter = new StringDecrypter(module); stringDecrypter.Find(DeobfuscatedFile); booleanDecrypter = new BooleanDecrypter(module); booleanDecrypter.Find(); assemblyResolver = new AssemblyResolver(module); assemblyResolver.Find(DeobfuscatedFile); obfuscatorName = DetectVersion(); if (unpackedNativeFile) obfuscatorName += " (native)"; resourceResolver = new ResourceResolver(module); resourceResolver.Find(DeobfuscatedFile); }
string detectVersion() { /* * Methods decrypter locals (not showing its own types): * 3.7.0.3: * "System.Byte[]" * "System.Int32" * "System.Int32[]" * "System.IntPtr" * "System.IO.BinaryReader" * "System.IO.MemoryStream" * "System.Object" * "System.Reflection.Assembly" * "System.Security.Cryptography.CryptoStream" * "System.Security.Cryptography.ICryptoTransform" * "System.Security.Cryptography.RijndaelManaged" * "System.String" * * 3.9.8.0: * - "System.Int32[]" + "System.Diagnostics.StackFrame" + + 4.0.0.0: (jitter) + - "System.Diagnostics.StackFrame" + - "System.Object" + "System.Boolean" + "System.Collections.IEnumerator" + "System.Delegate" + "System.Diagnostics.Process" + "System.Diagnostics.ProcessModule" + "System.Diagnostics.ProcessModuleCollection" + "System.IDisposable" + "System.Int64" + "System.UInt32" + "System.UInt64" + + 4.1.0.0: (jitter) + "System.Reflection.Assembly" + + 4.3.1.0: (jitter) + "System.Byte&" */ LocalTypes localTypes; int minVer = -1; foreach (var info in stringDecrypter.DecrypterInfos) { if (info.key == null) { continue; } localTypes = new LocalTypes(info.method); if (!localTypes.exists("System.IntPtr")) { return(DeobfuscatorInfo.THE_NAME + " <= 3.7"); } minVer = 3800; break; } if (methodsDecrypter.Method == null) { if (minVer >= 3800) { return(DeobfuscatorInfo.THE_NAME + " >= 3.8"); } return(DeobfuscatorInfo.THE_NAME); } localTypes = new LocalTypes(methodsDecrypter.Method); if (localTypes.exists("System.Int32[]")) { if (minVer >= 3800) { return(DeobfuscatorInfo.THE_NAME + " 3.8.4.1 - 3.9.0.1"); } return(DeobfuscatorInfo.THE_NAME + " <= 3.9.0.1"); } if (!localTypes.exists("System.Diagnostics.Process")) // If < 4.0 { if (localTypes.exists("System.Diagnostics.StackFrame")) { return(DeobfuscatorInfo.THE_NAME + " 3.9.8.0"); } } var compileMethod = MethodsDecrypter.findDnrCompileMethod(methodsDecrypter.Method.DeclaringType); if (compileMethod == null) { return(DeobfuscatorInfo.THE_NAME + " < 4.0"); } DeobfuscatedFile.deobfuscate(compileMethod); bool compileMethodHasConstant_0x70000000 = DeobUtils.hasInteger(compileMethod, 0x70000000); // 4.0-4.1 DeobfuscatedFile.deobfuscate(methodsDecrypter.Method); bool hasCorEnableProfilingString = findString(methodsDecrypter.Method, "Cor_Enable_Profiling"); // 4.1-4.4 if (compileMethodHasConstant_0x70000000) { if (hasCorEnableProfilingString) { return(DeobfuscatorInfo.THE_NAME + " 4.1"); } return(DeobfuscatorInfo.THE_NAME + " 4.0"); } if (!hasCorEnableProfilingString) { return(DeobfuscatorInfo.THE_NAME); } // 4.2-4.4 if (!localTypes.exists("System.Byte&")) { return(DeobfuscatorInfo.THE_NAME + " 4.2"); } localTypes = new LocalTypes(compileMethod); if (localTypes.exists("System.Object")) { return(DeobfuscatorInfo.THE_NAME + " 4.4"); } return(DeobfuscatorInfo.THE_NAME + " 4.3"); }