From c14eef2750c647741b20818130ca2be5f9ced889 Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 26 Dec 2011 20:40:18 +0100 Subject: [PATCH] Update code for SA 1.x-3.x obfuscated assemblies --- .../SmartAssembly/AssemblyResolverInfo.cs | 7 ++- .../AutomatedErrorReportingFinder.cs | 10 +++- .../SmartAssembly/StringDecrypterInfo.cs | 54 +++++++++++++------ 3 files changed, 51 insertions(+), 20 deletions(-) diff --git a/de4dot.code/deobfuscators/SmartAssembly/AssemblyResolverInfo.cs b/de4dot.code/deobfuscators/SmartAssembly/AssemblyResolverInfo.cs index 21cbca4b..d728d2b2 100644 --- a/de4dot.code/deobfuscators/SmartAssembly/AssemblyResolverInfo.cs +++ b/de4dot.code/deobfuscators/SmartAssembly/AssemblyResolverInfo.cs @@ -105,8 +105,11 @@ namespace de4dot.code.deobfuscators.SmartAssembly { return true; foreach (var field in type.Fields) { - if (!DotNetUtils.derivesFromDelegate(DotNetUtils.getType(module, field.FieldType))) - return false; + if (DotNetUtils.derivesFromDelegate(DotNetUtils.getType(module, field.FieldType))) + continue; + if (field.IsLiteral && field.FieldType.ToString() == "System.String") + continue; + return false; } return true; } diff --git a/de4dot.code/deobfuscators/SmartAssembly/AutomatedErrorReportingFinder.cs b/de4dot.code/deobfuscators/SmartAssembly/AutomatedErrorReportingFinder.cs index 68614084..6919432d 100644 --- a/de4dot.code/deobfuscators/SmartAssembly/AutomatedErrorReportingFinder.cs +++ b/de4dot.code/deobfuscators/SmartAssembly/AutomatedErrorReportingFinder.cs @@ -83,6 +83,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly { return false; if (isV0(type)) { + aerVersion = AerVersion.V0; foreach (var method in type.Methods) { if (method.IsStatic) exceptionLoggerRemover.add(method); @@ -206,9 +207,14 @@ namespace de4dot.code.deobfuscators.SmartAssembly { bool isAutomatedErrorReportingMethod(MethodDefinition method) { if (!method.HasBody || !method.IsStatic || method.Name == ".ctor") return false; - return DotNetUtils.isMethod(method, "System.Void", "(System.Exception,System.Object[])") || + return + // 5.x-6.x + DotNetUtils.isMethod(method, "System.Void", "(System.Exception,System.Object[])") || + // 5.x-6.x + DotNetUtils.isMethod(method, "System.Void", "(System.Exception,System.Int32,System.Object[])") || + // 3.x-4.x DotNetUtils.isMethod(method, "System.Exception", "(System.Exception,System.Object[])") || - // 2.x + // 2.x-4.x DotNetUtils.isMethod(method, "System.Exception", "(System.Exception,System.Int32,System.Object[])") || // 1.x DotNetUtils.isMethod(method, "System.Exception", "(System.Int32,System.Exception,System.Object[])"); diff --git a/de4dot.code/deobfuscators/SmartAssembly/StringDecrypterInfo.cs b/de4dot.code/deobfuscators/SmartAssembly/StringDecrypterInfo.cs index f32f1571..7d568db3 100644 --- a/de4dot.code/deobfuscators/SmartAssembly/StringDecrypterInfo.cs +++ b/de4dot.code/deobfuscators/SmartAssembly/StringDecrypterInfo.cs @@ -112,7 +112,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly { if (!findDecrypterMethod()) throw new ApplicationException("Could not find string decrypter method"); - if (!findStringsResource(deob, simpleDeobfuscator, cctor ?? stringDecrypterMethod)) + if (!findStringsResource(deob, simpleDeobfuscator, cctor)) return false; if (decrypterVersion <= StringDecrypterVersion.V3) { @@ -126,10 +126,12 @@ namespace de4dot.code.deobfuscators.SmartAssembly { stringOffset = 0; if (decrypterVersion != StringDecrypterVersion.V1) { - var pkt = module.Assembly.Name.PublicKeyToken; - if (pkt != null) { - for (int i = 0; i < pkt.Length - 1; i += 2) - stringOffset ^= ((int)pkt[i] << 8) + pkt[i + 1]; + if (callsGetPublicKeyToken(initMethod)) { + var pkt = module.Assembly.Name.PublicKeyToken; + if (pkt != null) { + for (int i = 0; i < pkt.Length - 1; i += 2) + stringOffset ^= ((int)pkt[i] << 8) + pkt[i + 1]; + } } if (DotNetUtils.findLdcI4Constant(initMethod, 0xFFFFFF) && @@ -146,14 +148,22 @@ namespace de4dot.code.deobfuscators.SmartAssembly { decrypterVersion = StringDecrypterVersion.V4; } - simpleZipType = cctor == null ? null : findSimpleZipType(cctor); + simpleZipType = findSimpleZipType(cctor) ?? findSimpleZipType(stringDecrypterMethod); if (simpleZipType != null) resourceDecrypter = new ResourceDecrypter(new ResourceDecrypterInfo(module, simpleZipType, simpleDeobfuscator)); return true; } - bool findStringsResource(IDeobfuscator deob, ISimpleDeobfuscator simpleDeobfuscator, MethodDefinition initMethod) { + bool callsGetPublicKeyToken(MethodDefinition method) { + foreach (var calledMethod in DotNetUtils.getMethodCalls(method)) { + if (calledMethod.ToString() == "System.Byte[] System.Reflection.AssemblyName::GetPublicKeyToken()") + return true; + } + return false; + } + + bool findStringsResource(IDeobfuscator deob, ISimpleDeobfuscator simpleDeobfuscator, MethodDefinition cctor) { if (stringsResource != null) return true; @@ -163,16 +173,26 @@ namespace de4dot.code.deobfuscators.SmartAssembly { return true; } - if (initMethod != null) { - stringsResource = findStringResource(initMethod); - if (stringsResource != null) - return true; + if (findStringsResource2(deob, simpleDeobfuscator, cctor)) + return true; + if (findStringsResource2(deob, simpleDeobfuscator, stringDecrypterMethod)) + return true; - simpleDeobfuscator.decryptStrings(initMethod, deob); - stringsResource = findStringResource(initMethod); - if (stringsResource != null) - return true; - } + return false; + } + + bool findStringsResource2(IDeobfuscator deob, ISimpleDeobfuscator simpleDeobfuscator, MethodDefinition initMethod) { + if (initMethod == null) + return false; + + stringsResource = findStringResource(initMethod); + if (stringsResource != null) + return true; + + simpleDeobfuscator.decryptStrings(initMethod, deob); + stringsResource = findStringResource(initMethod); + if (stringsResource != null) + return true; return false; } @@ -270,6 +290,8 @@ namespace de4dot.code.deobfuscators.SmartAssembly { // Find SmartAssembly.Zip.SimpleZip, which is the class that decrypts and inflates // data in the resources. TypeDefinition findSimpleZipType(MethodDefinition method) { + if (method == null || method.Body == null) + return null; var instructions = method.Body.Instructions; for (int i = 0; i <= instructions.Count - 2; i++) { var call = instructions[i];