diff --git a/de4dot.code/deobfuscators/CliSecure/CliSecureRtType.cs b/de4dot.code/deobfuscators/CliSecure/CliSecureRtType.cs index 7892d987..9e636974 100644 --- a/de4dot.code/deobfuscators/CliSecure/CliSecureRtType.cs +++ b/de4dot.code/deobfuscators/CliSecure/CliSecureRtType.cs @@ -80,65 +80,37 @@ namespace de4dot.code.deobfuscators.CliSecure { return; if (find2()) return; - if (findOld()) - return; findNativeCode(); } + static readonly string[] requiredFields1 = new string[] { + "System.Boolean", + }; + static readonly string[] requiredFields2 = new string[] { + "System.Boolean", + "System.Reflection.Assembly", + }; + static readonly string[] requiredFields3 = new string[] { + "System.Boolean", + "System.Reflection.Assembly", + "System.Byte[]", + }; bool find2() { - foreach (var type in module.Types) { - if (type.Namespace != "") - continue; - var typeName = type.FullName; - - MethodDefinition cs = null; - MethodDefinition initialize = null; - MethodDefinition postInitialize = null; - MethodDefinition load = null; - - int methods = 0; - foreach (var method in type.Methods) { - if (method.FullName == "System.String " + typeName + "::cs(System.String)") { - cs = method; - methods++; - } - else if (method.FullName == "System.Void " + typeName + "::Initialize()") { - initialize = method; - methods++; - } - else if (method.FullName == "System.Void " + typeName + "::PostInitialize()") { - postInitialize = method; - methods++; - } - else if (method.FullName == "System.IntPtr " + typeName + "::Load()") { - load = method; - methods++; - } - } - if (methods == 0 || (methods == 1 && initialize != null)) - continue; - - stringDecrypterMethod = cs; - initializeMethod = initialize; - postInitializeMethod = postInitialize; - loadMethod = load; - cliSecureRtType = type; - return true; - } - - return false; - } - - bool findOld() { foreach (var cctor in DeobUtils.getInitCctors(module, 3)) { foreach (var calledMethod in DotNetUtils.getCalledMethods(module, cctor)) { var type = calledMethod.DeclaringType; - if (!hasPinvokeMethod(type, "_Initialize")) + if (type.IsPublic) continue; - if (!hasPinvokeMethod(type, "_Initialize64")) + var fieldTypes = new FieldTypes(type); + if (!fieldTypes.exactly(requiredFields1) && !fieldTypes.exactly(requiredFields2) && !fieldTypes.exactly(requiredFields3)) + continue; + if (!hasInitializeMethod(type, "_Initialize")) continue; + stringDecrypterMethod = findStringDecrypterMethod(type); initializeMethod = calledMethod; + postInitializeMethod = findMethod(type, "System.Void", "PostInitialize", "()"); + loadMethod = findMethod(type, "System.IntPtr", "Load", "()"); cliSecureRtType = type; return true; } @@ -147,6 +119,47 @@ namespace de4dot.code.deobfuscators.CliSecure { return false; } + static MethodDefinition findStringDecrypterMethod(TypeDefinition type) { + foreach (var method in type.Methods) { + if (method.Body == null || !method.IsStatic) + continue; + if (!DotNetUtils.isMethod(method, "System.String", "(System.String)")) + continue; + + return method; + } + + return null; + } + + static MethodDefinition findMethod(TypeDefinition type, string returnType, string name, string parameters) { + var methodName = returnType + " " + type.FullName + "::" + name + parameters; + foreach (var method in type.Methods) { + if (method.Body == null || !method.IsStatic) + continue; + if (method.FullName != methodName) + continue; + + return method; + } + + return null; + } + + static bool hasInitializeMethod(TypeDefinition type, string name) { + var method = DotNetUtils.getPInvokeMethod(type, name); + if (method == null) + return false; + if (method.Parameters.Count != 1) + return false; + if (method.Parameters[0].ParameterType.FullName != "System.IntPtr") + return false; + var retType = method.MethodReturnType.ReturnType.FullName; + if (retType != "System.Void" && retType != "System.Int32") + return false; + return true; + } + bool findNativeCode() { if ((module.Attributes & ModuleAttributes.ILOnly) != 0) return false; @@ -157,20 +170,8 @@ namespace de4dot.code.deobfuscators.CliSecure { } } - static bool hasPinvokeMethod(TypeDefinition type, string methodName) { - if (type == null) - return false; - foreach (var method in type.Methods) { - if (method.PInvokeInfo == null) - continue; - if (method.PInvokeInfo.EntryPoint == methodName) - return true; - } - return false; - } - public bool isAtLeastVersion50() { - return hasPinvokeMethod(cliSecureRtType, "LoadLibraryA"); + return DotNetUtils.hasPinvokeMethod(cliSecureRtType, "LoadLibraryA"); } } } diff --git a/de4dot.code/deobfuscators/CliSecure/StringDecrypter.cs b/de4dot.code/deobfuscators/CliSecure/StringDecrypter.cs index 44ecf620..e59481e6 100644 --- a/de4dot.code/deobfuscators/CliSecure/StringDecrypter.cs +++ b/de4dot.code/deobfuscators/CliSecure/StringDecrypter.cs @@ -29,7 +29,7 @@ namespace de4dot.code.deobfuscators.CliSecure { byte[] stringDecrypterKey; public bool Detected { - get { return stringDecrypterKey != null; } + get { return stringDecrypterMethod != null; } } public TypeDefinition Type { @@ -57,6 +57,7 @@ namespace de4dot.code.deobfuscators.CliSecure { } public void find() { + stringDecrypterKey = new byte[1] { 0xFF }; foreach (var type in module.Types) { if (type.FullName == "" || type.FullName == "") { stringDecrypterType = type;