From f468aebda50b4a2eb5443ccd6cd14a16b0d8dda0 Mon Sep 17 00:00:00 2001 From: de4dot Date: Mon, 26 Dec 2011 20:32:42 +0100 Subject: [PATCH] Dump resources in applications (library mode) --- de4dot.code/de4dot.code.csproj | 1 + .../dotNET_Reactor/v3/Deobfuscator.cs | 22 ++- .../dotNET_Reactor/v3/LibAssemblyResolver.cs | 129 ++++++++++++++++++ 3 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 de4dot.code/deobfuscators/dotNET_Reactor/v3/LibAssemblyResolver.cs diff --git a/de4dot.code/de4dot.code.csproj b/de4dot.code/de4dot.code.csproj index 1c2ca5ff..a728ee4a 100644 --- a/de4dot.code/de4dot.code.csproj +++ b/de4dot.code/de4dot.code.csproj @@ -83,6 +83,7 @@ + diff --git a/de4dot.code/deobfuscators/dotNET_Reactor/v3/Deobfuscator.cs b/de4dot.code/deobfuscators/dotNET_Reactor/v3/Deobfuscator.cs index fa00434d..3db68cad 100644 --- a/de4dot.code/deobfuscators/dotNET_Reactor/v3/Deobfuscator.cs +++ b/de4dot.code/deobfuscators/dotNET_Reactor/v3/Deobfuscator.cs @@ -84,6 +84,7 @@ namespace de4dot.code.deobfuscators.dotNET_Reactor.v3 { DecrypterType decrypterType; NativeLibSaver nativeLibSaver; AntiStrongName antiStrongName; + LibAssemblyResolver libAssemblyResolver; List unpackedFiles = new List(); bool unpackedNativeFile = false; @@ -255,6 +256,9 @@ namespace de4dot.code.deobfuscators.dotNET_Reactor.v3 { return decrypterType.decrypt2((string)args[0]); }); + libAssemblyResolver = new LibAssemblyResolver(module); + libAssemblyResolver.find(DeobfuscatedFile, this); + if (Operations.DecryptStrings == OpDecryptString.None) canRemoveDecrypterType = false; @@ -266,6 +270,7 @@ namespace de4dot.code.deobfuscators.dotNET_Reactor.v3 { removeInitCall(initMethod); dumpUnpackedFiles(); + dumpResourceFiles(); startedDeobfuscating = true; } @@ -277,7 +282,22 @@ namespace de4dot.code.deobfuscators.dotNET_Reactor.v3 { void dumpUnpackedFiles() { foreach (var unpackedFile in unpackedFiles) - DeobfuscatedFile.createAssemblyFile(unpackedFile.data, Win32Path.GetFileNameWithoutExtension(unpackedFile.filename), Win32Path.GetExtension(unpackedFile.filename)); + DeobfuscatedFile.createAssemblyFile(unpackedFile.data, + Win32Path.GetFileNameWithoutExtension(unpackedFile.filename), + Win32Path.GetExtension(unpackedFile.filename)); + } + + void dumpResourceFiles() { + foreach (var resource in libAssemblyResolver.Resources) { + var mod = ModuleDefinition.ReadModule(resource.GetResourceStream()); + addResourceToBeRemoved(resource, string.Format("Embedded assembly: {0}", mod.Assembly.FullName)); + DeobfuscatedFile.createAssemblyFile(resource.GetResourceData(), + Utils.getAssemblySimpleName(mod.Assembly.FullName), + DeobUtils.getExtension(mod.Kind)); + } + removeInitCall(libAssemblyResolver.InitMethod); + addCallToBeRemoved(module.EntryPoint, libAssemblyResolver.InitMethod); + addTypeToBeRemoved(libAssemblyResolver.Type, "Assembly resolver type (library mode)"); } public override void deobfuscateMethodEnd(Blocks blocks) { diff --git a/de4dot.code/deobfuscators/dotNET_Reactor/v3/LibAssemblyResolver.cs b/de4dot.code/deobfuscators/dotNET_Reactor/v3/LibAssemblyResolver.cs new file mode 100644 index 00000000..a2add66f --- /dev/null +++ b/de4dot.code/deobfuscators/dotNET_Reactor/v3/LibAssemblyResolver.cs @@ -0,0 +1,129 @@ +/* + Copyright (C) 2011 de4dot@gmail.com + + This file is part of de4dot. + + de4dot is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + de4dot is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with de4dot. If not, see . +*/ + +using System.Collections.Generic; +using Mono.Cecil; +using Mono.Cecil.Cil; +using de4dot.blocks; + +namespace de4dot.code.deobfuscators.dotNET_Reactor.v3 { + // Find the assembly resolver that's used in lib mode (3.8+) + class LibAssemblyResolver { + ModuleDefinition module; + MethodDefinition initMethod; + List resources = new List(); + + public TypeDefinition Type { + get { return initMethod == null ? null : initMethod.DeclaringType; } + } + + public MethodDefinition InitMethod { + get { return initMethod; } + } + + public IEnumerable Resources { + get { return resources; } + } + + public LibAssemblyResolver(ModuleDefinition module) { + this.module = module; + } + + public void find(ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) { + if (checkInitMethod(DotNetUtils.getMethod(DotNetUtils.getModuleType(module), ".cctor"), simpleDeobfuscator, deob)) + return; + if (checkInitMethod(module.EntryPoint, simpleDeobfuscator, deob)) + return; + } + + bool checkInitMethod(MethodDefinition checkMethod, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) { + var requiredFields = new string[] { + "System.Collections.Hashtable", + "System.Boolean", + }; + + foreach (var tuple in DotNetUtils.getCalledMethods(module, checkMethod)) { + var method = tuple.Item2; + + if (method.Body == null) + continue; + if (!method.IsStatic) + continue; + if (!DotNetUtils.isMethod(method, "System.Void", "()")) + continue; + + var type = method.DeclaringType; + if (!new FieldTypes(type).exactly(requiredFields)) + continue; + var ctor = DotNetUtils.getMethod(type, ".ctor"); + if (ctor == null) + continue; + var handler = getHandler(ctor); + if (handler == null) + continue; + simpleDeobfuscator.decryptStrings(handler, deob); + var resourcePrefix = getResourcePrefix(handler); + if (resourcePrefix == null) + continue; + + for (int i = 0; ; i++) { + var resource = DotNetUtils.getResource(module, resourcePrefix + i.ToString("D5")) as EmbeddedResource; + if (resource == null) + break; + resources.Add(resource); + } + + initMethod = method; + return true; + } + + return false; + } + + MethodDefinition getHandler(MethodDefinition ctor) { + if (ctor == null || ctor.Body == null) + return null; + foreach (var instr in ctor.Body.Instructions) { + if (instr.OpCode.Code != Code.Ldftn) + continue; + var handler = instr.Operand as MethodReference; + if (handler == null) + continue; + if (!DotNetUtils.isMethod(handler, "System.Reflection.Assembly", "(System.Object,System.ResolveEventArgs)")) + continue; + var handlerDef = DotNetUtils.getMethod(module, handler); + if (handlerDef == null) + continue; + + return handlerDef; + } + + return null; + } + + string getResourcePrefix(MethodDefinition handler) { + foreach (var s in DotNetUtils.getCodeStrings(handler)) { + var resource = DotNetUtils.getResource(module, s + "00000") as EmbeddedResource; + if (resource != null) + return s; + } + return null; + } + } +}