From 0b858c47edb89d791676245f6b20d0de62a0a870 Mon Sep 17 00:00:00 2001 From: de4dot Date: Sat, 17 Mar 2012 14:50:56 +0100 Subject: [PATCH] Support DS obfuscated SL assemblies --- .../deobfuscators/DeepSea/AssemblyResolver.cs | 57 +++++++++++++++---- .../deobfuscators/DeepSea/ResolverBase.cs | 29 ++++++++-- .../deobfuscators/DeepSea/ResourceResolver.cs | 2 +- 3 files changed, 73 insertions(+), 15 deletions(-) diff --git a/de4dot.code/deobfuscators/DeepSea/AssemblyResolver.cs b/de4dot.code/deobfuscators/DeepSea/AssemblyResolver.cs index 2f4f1207..49085928 100644 --- a/de4dot.code/deobfuscators/DeepSea/AssemblyResolver.cs +++ b/de4dot.code/deobfuscators/DeepSea/AssemblyResolver.cs @@ -71,16 +71,58 @@ namespace de4dot.code.deobfuscators.DeepSea { : base(module, simpleDeobfuscator, deob) { } + static string[] requiredLocals_sl = new string[] { + "System.Byte[]", + "System.IO.Stream", + "System.Reflection.Assembly", + "System.Security.Cryptography.SHA1Managed", + "System.Windows.AssemblyPart", + }; + protected override bool checkResolverInitMethodSilverlight(MethodDefinition resolverInitMethod) { + if (resolverInitMethod.Body.ExceptionHandlers.Count != 1) + return false; + + foreach (var info in DotNetUtils.getCalledMethods(module, resolverInitMethod)) { + var method = info.Item2; + if (!method.IsStatic || method.Body == null) + continue; + if (!method.IsPublic || method.HasGenericParameters) + continue; + if (!DotNetUtils.isMethod(method, "System.Void", "(System.String)")) + continue; + if (!new LocalTypes(method).all(requiredLocals_sl)) + continue; + + initMethod = resolverInitMethod; + resolveHandler = method; + updateVersion(resolveHandler); + return true; + } + + return false; + } + + void updateVersion(MethodDefinition handler) { + if (isV3Old(handler)) + version = Version.V3Old; + else + version = Version.V3; + } + + static bool isV3Old(MethodDefinition method) { + return DotNetUtils.callsMethod(method, "System.Int32 System.IO.Stream::Read(System.Byte[],System.Int32,System.Int32)") && + !DotNetUtils.callsMethod(method, "System.Int32 System.IO.Stream::ReadByte()") && + // Obfuscated System.Int32 System.IO.Stream::ReadByte() + !DotNetUtils.callsMethod(method, "System.Int32", "(System.IO.Stream,System.Int32,System.Int32)"); + } + protected override bool checkResolverInitMethodInternal(MethodDefinition resolverInitMethod) { return checkIfCalled(resolverInitMethod, "System.Void System.AppDomain::add_AssemblyResolve(System.ResolveEventHandler)"); } - protected override bool checkHandlerMethodInternal(MethodDefinition handler) { + protected override bool checkHandlerMethodDesktopInternal(MethodDefinition handler) { if (checkHandlerV3(handler) || checkHandlerSL(handler)) { - if (isV3Old(handler)) - version = Version.V3Old; - else - version = Version.V3; + updateVersion(handler); return true; } @@ -96,11 +138,6 @@ namespace de4dot.code.deobfuscators.DeepSea { return false; } - static bool isV3Old(MethodDefinition method) { - return DotNetUtils.callsMethod(method, "System.Int32 System.IO.Stream::Read(System.Byte[],System.Int32,System.Int32)") && - !DotNetUtils.callsMethod(method, "System.Int32 System.IO.Stream::ReadByte()"); - } - static string[] handlerLocalTypes_NET = new string[] { "System.Byte[]", "System.IO.Compression.DeflateStream", diff --git a/de4dot.code/deobfuscators/DeepSea/ResolverBase.cs b/de4dot.code/deobfuscators/DeepSea/ResolverBase.cs index 2dd0b1ae..aeb82c10 100644 --- a/de4dot.code/deobfuscators/DeepSea/ResolverBase.cs +++ b/de4dot.code/deobfuscators/DeepSea/ResolverBase.cs @@ -30,6 +30,7 @@ namespace de4dot.code.deobfuscators.DeepSea { protected IDeobfuscator deob; protected MethodDefinition initMethod; protected MethodDefinition resolveHandler; + protected FrameworkType frameworkType; public MethodDefinition InitMethod { get { return initMethod; } @@ -45,6 +46,7 @@ namespace de4dot.code.deobfuscators.DeepSea { public ResolverBase(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) { this.module = module; + this.frameworkType = DotNetUtils.getFrameworkType(module); this.simpleDeobfuscator = simpleDeobfuscator; this.deob = deob; } @@ -77,12 +79,27 @@ namespace de4dot.code.deobfuscators.DeepSea { bool checkResolverInitMethod(MethodDefinition resolverInitMethod) { if (resolverInitMethod == null || resolverInitMethod.Body == null) return false; + if (resolverInitMethod.Body.ExceptionHandlers.Count != 1) + return false; + switch (frameworkType) { + case FrameworkType.Silverlight: + return checkResolverInitMethodSilverlight(resolverInitMethod); + case FrameworkType.Unknown: + case FrameworkType.Desktop: + case FrameworkType.CompactFramework: + case FrameworkType.Zune: + default: + return checkResolverInitMethodDesktop(resolverInitMethod); + } + } + + bool checkResolverInitMethodDesktop(MethodDefinition resolverInitMethod) { if (!checkResolverInitMethodInternal(resolverInitMethod)) return false; foreach (var resolveHandlerMethod in getLdftnMethods(resolverInitMethod)) { - if (!checkHandlerMethod(resolveHandlerMethod)) + if (!checkHandlerMethodDesktop(resolveHandlerMethod)) continue; initMethod = resolverInitMethod; @@ -93,6 +110,10 @@ namespace de4dot.code.deobfuscators.DeepSea { return false; } + protected virtual bool checkResolverInitMethodSilverlight(MethodDefinition resolverInitMethod) { + return false; + } + protected abstract bool checkResolverInitMethodInternal(MethodDefinition resolverInitMethod); protected static bool checkIfCalled(MethodDefinition method, string fullName) { @@ -120,15 +141,15 @@ namespace de4dot.code.deobfuscators.DeepSea { return list; } - bool checkHandlerMethod(MethodDefinition handler) { + bool checkHandlerMethodDesktop(MethodDefinition handler) { if (handler == null || handler.Body == null || !handler.IsStatic) return false; if (!DotNetUtils.isMethod(handler, "System.Reflection.Assembly", "(System.Object,System.ResolveEventArgs)")) return false; - return checkHandlerMethodInternal(handler); + return checkHandlerMethodDesktopInternal(handler); } - protected abstract bool checkHandlerMethodInternal(MethodDefinition handler); + protected abstract bool checkHandlerMethodDesktopInternal(MethodDefinition handler); // 3.0.3.41 - 3.0.4.44 protected static byte[] decryptResourceV3Old(EmbeddedResource resource) { diff --git a/de4dot.code/deobfuscators/DeepSea/ResourceResolver.cs b/de4dot.code/deobfuscators/DeepSea/ResourceResolver.cs index 74a9f123..d8b47905 100644 --- a/de4dot.code/deobfuscators/DeepSea/ResourceResolver.cs +++ b/de4dot.code/deobfuscators/DeepSea/ResourceResolver.cs @@ -45,7 +45,7 @@ namespace de4dot.code.deobfuscators.DeepSea { return checkIfCalled(resolverInitMethod, "System.Void System.AppDomain::add_ResourceResolve(System.ResolveEventHandler)"); } - protected override bool checkHandlerMethodInternal(MethodDefinition handler) { + protected override bool checkHandlerMethodDesktopInternal(MethodDefinition handler) { if (checkHandlerV3(handler)) { isV3 = true; return true;