diff --git a/blocks/DotNetUtils.cs b/blocks/DotNetUtils.cs index bb69e215..5e7aa896 100644 --- a/blocks/DotNetUtils.cs +++ b/blocks/DotNetUtils.cs @@ -228,6 +228,10 @@ namespace de4dot.blocks { return method != null && method.FullName == returnType + " " + method.DeclaringType.FullName + "::" + method.Name + parameters; } + public static bool isMethod(DN.IMethod method, string returnType, string parameters) { + return method != null && method.FullName == returnType + " " + method.DeclaringType.FullName + "::" + method.Name + parameters; + } + public static bool hasPinvokeMethod(TypeDefinition type, string methodName) { return getPInvokeMethod(type, methodName) != null; } @@ -448,6 +452,17 @@ namespace de4dot.blocks { return strings; } + public static IList getCodeStrings(DN.MethodDef method) { + var strings = new List(); + if (method != null && method.CilBody != null) { + foreach (var instr in method.CilBody.Instructions) { + if (instr.OpCode.Code == DNE.Code.Ldstr) + strings.Add((string)instr.Operand); + } + } + return strings; + } + public static DN.Resource getResource(DN.ModuleDef module, string name) { return getResource(module, new List { name }); } diff --git a/de4dot.code/AssemblyModule.cs b/de4dot.code/AssemblyModule.cs index 457f5aa7..71ccde41 100644 --- a/de4dot.code/AssemblyModule.cs +++ b/de4dot.code/AssemblyModule.cs @@ -20,52 +20,47 @@ using System; using System.IO; using System.Collections.Generic; -using Mono.Cecil; -using Mono.MyStuff; +using dot10.DotNet; using de4dot.blocks; namespace de4dot.code { class AssemblyModule { string filename; - ModuleDefinition module; + ModuleDefMD module; public AssemblyModule(string filename) { this.filename = Utils.getFullPath(filename); } - ReaderParameters getReaderParameters() { - return new ReaderParameters(ReadingMode.Deferred) { - AssemblyResolver = AssemblyResolver.Instance - }; + public ModuleDefMD load() { + return setModule(ModuleDefMD.Load(filename)); } - public ModuleDefinition load() { - return setModule(ModuleDefinition.ReadModule(filename, getReaderParameters())); + public ModuleDefMD load(byte[] fileData) { + return setModule(ModuleDefMD.Load(fileData)); } - public ModuleDefinition load(byte[] fileData) { - return setModule(ModuleDefinition.ReadModule(new MemoryStream(fileData), getReaderParameters())); - } - - ModuleDefinition setModule(ModuleDefinition newModule) { + ModuleDefMD setModule(ModuleDefMD newModule) { module = newModule; AssemblyResolver.Instance.addModule(module); - module.FullyQualifiedName = filename; + module.Location = filename; return module; } public void save(string newFilename, bool updateMaxStack, IWriterListener writerListener) { - var writerParams = new WriterParameters() { - UpdateMaxStack = updateMaxStack, - WriterListener = writerListener, - }; - module.Write(newFilename, writerParams); + //TODO: var writerParams = new WriterParameters() { + //TODO: UpdateMaxStack = updateMaxStack, + //TODO: WriterListener = writerListener, + //TODO: }; + //TODO: module.Write(newFilename, writerParams); + module.Write(newFilename); } - public ModuleDefinition reload(byte[] newModuleData, DumpedMethods dumpedMethods) { - AssemblyResolver.Instance.removeModule(module); - DotNetUtils.typeCaches.invalidate(module); - return setModule(ModuleDefinition.ReadModule(new MemoryStream(newModuleData), getReaderParameters(), dumpedMethods)); + public ModuleDefMD reload(byte[] newModuleData, DumpedMethods dumpedMethods) { + //TODO: AssemblyResolver.Instance.removeModule(module); + //TODO: DotNetUtils.typeCaches.invalidate(module); + //TODO: Use dumped methods + return setModule(ModuleDefMD.Load(newModuleData)); } public override string ToString() { diff --git a/de4dot.code/AssemblyResolver.cs b/de4dot.code/AssemblyResolver.cs index 1eeb8f92..4f026c64 100644 --- a/de4dot.code/AssemblyResolver.cs +++ b/de4dot.code/AssemblyResolver.cs @@ -17,176 +17,38 @@ along with de4dot. If not, see . */ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text.RegularExpressions; -using System.Xml; -using Mono.Cecil; +using dot10.DotNet; namespace de4dot.code { - public class AssemblyResolver : DefaultAssemblyResolver { + public class AssemblyResolver : dot10.DotNet.AssemblyResolver { public static readonly AssemblyResolver Instance = new AssemblyResolver(); - Dictionary addedDirectories = new Dictionary(StringComparer.OrdinalIgnoreCase); - - static AssemblyResolver() { - Instance.resetSearchPaths(); - } - - void resetSearchPaths() { - addedDirectories.Clear(); - addOtherAssemblySearchPaths(); - } - - void addOtherAssemblySearchPaths() { - addOtherAssemblySearchPaths(Environment.GetEnvironmentVariable("ProgramFiles")); - addOtherAssemblySearchPaths(Environment.GetEnvironmentVariable("ProgramFiles(x86)")); - } - - void addOtherAssemblySearchPaths(string path) { - if (string.IsNullOrEmpty(path)) - return; - addSilverlightDirs(Path.Combine(path, @"Microsoft Silverlight")); - addIfExists(path, @"Microsoft SDKs\Silverlight\v2.0\Libraries\Client"); - addIfExists(path, @"Microsoft SDKs\Silverlight\v2.0\Libraries\Server"); - addIfExists(path, @"Microsoft SDKs\Silverlight\v2.0\Reference Assemblies"); - addIfExists(path, @"Microsoft SDKs\Silverlight\v3.0\Libraries\Client"); - addIfExists(path, @"Microsoft SDKs\Silverlight\v3.0\Libraries\Server"); - addIfExists(path, @"Microsoft SDKs\Silverlight\v4.0\Libraries\Client"); - addIfExists(path, @"Microsoft SDKs\Silverlight\v4.0\Libraries\Server"); - addIfExists(path, @"Microsoft SDKs\Silverlight\v5.0\Libraries\Client"); - addIfExists(path, @"Microsoft SDKs\Silverlight\v5.0\Libraries\Server"); - addIfExists(path, @"Microsoft.NET\SDK\CompactFramework\v2.0\WindowsCE"); - addIfExists(path, @"Microsoft.NET\SDK\CompactFramework\v3.5\WindowsCE"); - addIfExists(path, @"Reference Assemblies\Microsoft\Framework\Silverlight\v3.0"); - addIfExists(path, @"Reference Assemblies\Microsoft\Framework\Silverlight\v4.0"); - addIfExists(path, @"Reference Assemblies\Microsoft\Framework\Silverlight\v5.0"); - addIfExists(path, @"Reference Assemblies\Microsoft\FSharp\2.0\Runtime\v2.0"); - addIfExists(path, @"Reference Assemblies\Microsoft\FSharp\2.0\Runtime\v4.0"); - addIfExists(path, @"Reference Assemblies\Microsoft\WindowsPowerShell\v1.0"); - addIfExists(path, @"Microsoft Visual Studio .NET\Common7\IDE\PublicAssemblies"); - addIfExists(path, @"Microsoft Visual Studio .NET\Common7\IDE\PrivateAssemblies"); - addIfExists(path, @"Microsoft Visual Studio 8.0\Common7\IDE\PublicAssemblies"); - addIfExists(path, @"Microsoft Visual Studio 8.0\Common7\IDE\PrivateAssemblies"); - addIfExists(path, @"Microsoft Visual Studio 9.0\Common7\IDE\PublicAssemblies"); - addIfExists(path, @"Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies"); - addIfExists(path, @"Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies"); - addIfExists(path, @"Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies"); - addIfExists(path, @"Microsoft Visual Studio 11.0\Common7\IDE\PublicAssemblies"); - addIfExists(path, @"Microsoft Visual Studio 11.0\Common7\IDE\PrivateAssemblies"); - addIfExists(path, @"Microsoft XNA\XNA Game Studio\v2.0\References\Windows\x86"); - addIfExists(path, @"Microsoft XNA\XNA Game Studio\v2.0\References\Xbox360"); - addIfExists(path, @"Microsoft XNA\XNA Game Studio\v3.0\References\Windows\x86"); - addIfExists(path, @"Microsoft XNA\XNA Game Studio\v3.0\References\Xbox360"); - addIfExists(path, @"Microsoft XNA\XNA Game Studio\v3.0\References\Zune"); - addIfExists(path, @"Microsoft XNA\XNA Game Studio\v3.1\References\Windows\x86"); - addIfExists(path, @"Microsoft XNA\XNA Game Studio\v3.1\References\Xbox360"); - addIfExists(path, @"Microsoft XNA\XNA Game Studio\v3.1\References\Zune"); - addIfExists(path, @"Microsoft XNA\XNA Game Studio\v4.0\References\Windows\x86"); - addIfExists(path, @"Microsoft XNA\XNA Game Studio\v4.0\References\Xbox360"); - addIfExists(path, @"Windows CE Tools\wce500\Windows Mobile 5.0 Pocket PC SDK\Designtimereferences"); - addIfExists(path, @"Windows CE Tools\wce500\Windows Mobile 5.0 Smartphone SDK\Designtimereferences"); - addIfExists(path, @"Windows Mobile 5.0 SDK R2\Managed Libraries"); - addIfExists(path, @"Windows Mobile 6 SDK\Managed Libraries"); - addIfExists(path, @"Windows Mobile 6.5.3 DTK\Managed Libraries"); - addIfExists(path, @"Microsoft SQL Server\90\SDK\Assemblies"); - addIfExists(path, @"Microsoft SQL Server\100\SDK\Assemblies"); - addIfExists(path, @"Microsoft SQL Server\110\SDK\Assemblies"); - addIfExists(path, @"Microsoft ASP.NET\ASP.NET MVC 2\Assemblies"); - addIfExists(path, @"Microsoft ASP.NET\ASP.NET MVC 3\Assemblies"); - addIfExists(path, @"Microsoft ASP.NET\ASP.NET MVC 4\Assemblies"); - addIfExists(path, @"Microsoft ASP.NET\ASP.NET Web Pages\v1.0\Assemblies"); - addIfExists(path, @"Microsoft ASP.NET\ASP.NET Web Pages\v2.0\Assemblies"); - addIfExists(path, @"Microsoft SDKs\F#\3.0\Framework\v4.0"); - } - - // basePath is eg. "C:\Program Files (x86)\Microsoft Silverlight" - void addSilverlightDirs(string basePath) { - try { - var di = new DirectoryInfo(basePath); - foreach (var dir in di.GetDirectories()) { - if (Regex.IsMatch(dir.Name, @"^\d+(?:\.\d+){3}$")) - addIfExists(basePath, dir.Name); - } - } - catch (Exception) { - } - } - - void addIfExists(string basePath, string extraPath) { - try { - var path = Path.Combine(basePath, extraPath); - if (Utils.pathExists(path)) - Instance.addSearchDirectory(path); - } - catch (Exception) { - } - } public void addSearchDirectory(string dir) { - if (!addedDirectories.ContainsKey(dir)) { - addedDirectories[dir] = true; - AddSearchDirectory(dir); - } + if (!PostSearchPaths.Contains(dir)) + PostSearchPaths.Add(dir); } - public void addModule(ModuleDefinition module) { - if (module.FullyQualifiedName != "") { - addSearchDirectory(Path.GetDirectoryName(module.FullyQualifiedName)); - if (module.FullyQualifiedName.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)) - addConfigFile(module.FullyQualifiedName + ".config"); - } - - var assembly = module.Assembly; - if (assembly != null) { - var name = assembly.Name.FullName; - cache[name] = assembly; - } + public void addModule(ModuleDef module) { + AddToCache(module.Assembly); } - void addConfigFile(string configFilename) { - var dirName = Utils.getDirName(Utils.getFullPath(configFilename)); - addSearchDirectory(dirName); - - try { - using (var xmlStream = new FileStream(configFilename, FileMode.Open, FileAccess.Read, FileShare.Read)) { - var doc = new XmlDocument(); - doc.Load(XmlReader.Create(xmlStream)); - foreach (var tmp in doc.GetElementsByTagName("probing")) { - var probingElem = tmp as XmlElement; - if (probingElem == null) - continue; - var privatePath = probingElem.GetAttribute("privatePath"); - if (string.IsNullOrEmpty(privatePath)) - continue; - foreach (var path in privatePath.Split(';')) - addSearchDirectory(Path.Combine(dirName, path)); - } - } - } - catch (IOException) { - } - catch (XmlException) { - } - } - - public void removeModule(ModuleDefinition module) { + public void removeModule(ModuleDef module) { var assembly = module.Assembly; if (assembly == null) return; - removeModule(assembly.Name.FullName); + removeModule(assembly.FullName); } public void removeModule(string asmFullName) { if (string.IsNullOrEmpty(asmFullName)) return; - cache.Remove(asmFullName); + //TODO: Remove it from the cache } public void clearAll() { - cache.Clear(); - resetSearchPaths(); + //TODO: cache.Clear(); + //TODO: resetSearchPaths(); } } } diff --git a/de4dot.code/IObfuscatedFile.cs b/de4dot.code/IObfuscatedFile.cs index d02c900b..be2c1e0c 100644 --- a/de4dot.code/IObfuscatedFile.cs +++ b/de4dot.code/IObfuscatedFile.cs @@ -20,7 +20,9 @@ using System.Collections.Generic; using de4dot.code.deobfuscators; using Mono.Cecil; +#if PORT using de4dot.code.renamer; +#endif namespace de4dot.code { public interface IObfuscatedFile { @@ -29,7 +31,9 @@ namespace de4dot.code { IDeobfuscatorContext DeobfuscatorContext { get; set; } string Filename { get; } string NewFilename { get; } +#if PORT INameChecker NameChecker { get; } +#endif bool RenameResourcesInCode { get; } bool RemoveNamespaceWithOneType { get; } bool RenameResourceKeys { get; } diff --git a/de4dot.code/ObfuscatedFile.cs b/de4dot.code/ObfuscatedFile.cs index 42892714..300030c0 100644 --- a/de4dot.code/ObfuscatedFile.cs +++ b/de4dot.code/ObfuscatedFile.cs @@ -22,20 +22,21 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Text; -using Mono.Cecil; -using Mono.Cecil.Cil; -using Mono.MyStuff; +using dot10.DotNet; +using dot10.DotNet.Emit; using de4dot.code.deobfuscators; using de4dot.blocks; using de4dot.blocks.cflow; using de4dot.code.AssemblyClient; +#if PORT using de4dot.code.renamer; +#endif using de4dot.PE; namespace de4dot.code { public class ObfuscatedFile : IObfuscatedFile, IDeobfuscatedFile { Options options; - ModuleDefinition module; + ModuleDefMD module; IDeobfuscator deob; IDeobfuscatorContext deobfuscatorContext; AssemblyModule assemblyModule; @@ -46,14 +47,14 @@ namespace de4dot.code { bool userStringDecrypterMethods = false; class SavedMethodBodies { - Dictionary savedMethodBodies = new Dictionary(); + Dictionary savedMethodBodies = new Dictionary(); class SavedMethodBody { - MethodDefinition method; + MethodDef method; IList instructions; IList exceptionHandlers; - public SavedMethodBody(MethodDefinition method) { + public SavedMethodBody(MethodDef method) { this.method = method; DotNetUtils.copyBody(method, out instructions, out exceptionHandlers); } @@ -63,7 +64,7 @@ namespace de4dot.code { } } - public void save(MethodDefinition method) { + public void save(MethodDef method) { if (isSaved(method)) return; savedMethodBodies[method] = new SavedMethodBody(method); @@ -75,7 +76,7 @@ namespace de4dot.code { savedMethodBodies.Clear(); } - public bool isSaved(MethodDefinition method) { + public bool isSaved(MethodDef method) { return savedMethodBodies.ContainsKey(method); } } @@ -103,13 +104,15 @@ namespace de4dot.code { get { return options.NewFilename; } } - public ModuleDefinition ModuleDefinition { + public ModuleDefMD ModuleDefMD { get { return module; } } +#if PORT public INameChecker NameChecker { get { return deob; } } +#endif public bool RenameResourcesInCode { get { return deob.TheOptions.RenameResourcesInCode; } @@ -309,8 +312,8 @@ namespace de4dot.code { assemblyModule.save(options.NewFilename, options.ControlFlowDeobfuscation, deob as IWriterListener); } - IList getAllMethods() { - var list = new List(); + IList getAllMethods() { + var list = new List(); foreach (var type in module.GetTypes()) { foreach (var method in type.Methods) @@ -546,7 +549,7 @@ namespace de4dot.code { catch (Exception ex) { if (!canLoadMethodBody(method)) { Log.v("Invalid method body. {0:X8}", method.MetadataToken.ToInt32()); - method.Body = new MethodBody(method); + method.CilBody = new MethodBody(method); } else { Log.w("Could not deobfuscate method {0:X8}. Hello, E.T.: {1}", // E.T. = exception type @@ -563,9 +566,9 @@ namespace de4dot.code { } } - static bool canLoadMethodBody(MethodDefinition method) { + static bool canLoadMethodBody(MethodDef method) { try { - var body = method.Body; + var body = method.CilBody; return true; } catch { @@ -574,13 +577,13 @@ namespace de4dot.code { } #if PORT - void deobfuscate(MethodDefinition method, BlocksCflowDeobfuscator cflowDeobfuscator, MethodPrinter methodPrinter) { + void deobfuscate(MethodDef method, BlocksCflowDeobfuscator cflowDeobfuscator, MethodPrinter methodPrinter) { if (!hasNonEmptyBody(method)) return; var blocks = new Blocks(method); int numRemovedLocals = 0; - int oldNumInstructions = method.Body.Instructions.Count; + int oldNumInstructions = method.CilBody.Instructions.Count; deob.deobfuscateMethodBegin(blocks); if (options.ControlFlowDeobfuscation) { @@ -606,7 +609,7 @@ namespace de4dot.code { if (numRemovedLocals > 0) Log.v("Removed {0} unused local(s)", numRemovedLocals); - int numRemovedInstructions = oldNumInstructions - method.Body.Instructions.Count; + int numRemovedInstructions = oldNumInstructions - method.CilBody.Instructions.Count; if (numRemovedInstructions > 0) Log.v("Removed {0} dead instruction(s)", numRemovedInstructions); @@ -620,8 +623,8 @@ namespace de4dot.code { } #endif - bool hasNonEmptyBody(MethodDefinition method) { - return method.HasBody && method.Body.Instructions.Count > 0; + bool hasNonEmptyBody(MethodDef method) { + return method.HasBody && method.CilBody.Instructions.Count > 0; } void deobfuscateStrings(Blocks blocks) { @@ -643,7 +646,7 @@ namespace de4dot.code { } } - void removeNoInliningAttribute(MethodDefinition method) { + void removeNoInliningAttribute(MethodDef method) { method.ImplAttributes = method.ImplAttributes & ~MethodImplAttributes.NoInlining; for (int i = 0; i < method.CustomAttributes.Count; i++) { var cattr = method.CustomAttributes[i]; @@ -689,15 +692,15 @@ namespace de4dot.code { enum SimpleDeobFlags { HasDeobfuscated = 0x1, } - Dictionary simpleDeobfuscatorFlags = new Dictionary(); - bool check(MethodDefinition method, SimpleDeobFlags flag) { + Dictionary simpleDeobfuscatorFlags = new Dictionary(); + bool check(MethodDef method, SimpleDeobFlags flag) { SimpleDeobFlags oldFlags; simpleDeobfuscatorFlags.TryGetValue(method, out oldFlags); simpleDeobfuscatorFlags[method] = oldFlags | flag; return (oldFlags & flag) == flag; } - void deobfuscate(MethodDefinition method, string msg, Action handler) { + void deobfuscate(MethodDef method, string msg, Action handler) { if (savedMethodBodies != null) savedMethodBodies.save(method); @@ -723,11 +726,11 @@ namespace de4dot.code { Log.deIndent(); } - void ISimpleDeobfuscator.deobfuscate(MethodDefinition method) { + void ISimpleDeobfuscator.deobfuscate(MethodDef method) { ((ISimpleDeobfuscator)this).deobfuscate(method, false); } - void ISimpleDeobfuscator.deobfuscate(MethodDefinition method, bool force) { + void ISimpleDeobfuscator.deobfuscate(MethodDef method, bool force) { if (!force && check(method, SimpleDeobFlags.HasDeobfuscated)) return; @@ -740,7 +743,7 @@ namespace de4dot.code { }); } - void ISimpleDeobfuscator.decryptStrings(MethodDefinition method, IDeobfuscator theDeob) { + void ISimpleDeobfuscator.decryptStrings(MethodDef method, IDeobfuscator theDeob) { deobfuscate(method, "Static string decryption", (blocks) => theDeob.deobfuscateStrings(blocks)); } diff --git a/de4dot.code/de4dot.code.csproj b/de4dot.code/de4dot.code.csproj index eb9089bf..c67aae99 100644 --- a/de4dot.code/de4dot.code.csproj +++ b/de4dot.code/de4dot.code.csproj @@ -274,32 +274,32 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/de4dot.code/deobfuscators/DeobUtils.cs b/de4dot.code/deobfuscators/DeobUtils.cs index d7b8f272..ee54420b 100644 --- a/de4dot.code/deobfuscators/DeobUtils.cs +++ b/de4dot.code/deobfuscators/DeobUtils.cs @@ -22,19 +22,19 @@ using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Security.Cryptography; -using Mono.Cecil; -using Mono.Cecil.Cil; +using dot10.DotNet; +using dot10.DotNet.Emit; using ICSharpCode.SharpZipLib.Zip.Compression; using de4dot.blocks; namespace de4dot.code.deobfuscators { static class DeobUtils { - public static void decryptAndAddResources(ModuleDefinition module, string encryptedName, Func decryptResource) { + public static void decryptAndAddResources(ModuleDef module, string encryptedName, Func decryptResource) { Log.v("Decrypting resources, name: {0}", Utils.toCsharpString(encryptedName)); var decryptedResourceData = decryptResource(); if (decryptedResourceData == null) throw new ApplicationException("decryptedResourceData is null"); - var resourceModule = ModuleDefinition.ReadModule(new MemoryStream(decryptedResourceData)); + var resourceModule = ModuleDefMD.Load(decryptedResourceData); Log.indent(); foreach (var rsrc in resourceModule.Resources) { @@ -44,27 +44,17 @@ namespace de4dot.code.deobfuscators { Log.deIndent(); } - public static T lookup(ModuleDefinition module, T def, string errorMessage) where T : MemberReference { + public static T lookup(ModuleDefMD module, T def, string errorMessage) where T : class, ICodedToken { if (def == null) return null; - var newDef = module.LookupToken(def.MetadataToken.ToInt32()) as T; + var newDef = module.ResolveToken(def.MDToken.Raw) as T; if (newDef == null) throw new ApplicationException(errorMessage); return newDef; } - public static ModuleReference lookup(ModuleDefinition module, ModuleReference other, string errorMessage) { - if (other == null) - return null; - foreach (var modRef in module.ModuleReferences) { - if (modRef.MetadataToken.ToInt32() == other.MetadataToken.ToInt32()) - return modRef; - } - throw new ApplicationException(errorMessage); - } - - public static byte[] readModule(ModuleDefinition module) { - return Utils.readFile(module.FullyQualifiedName); + public static byte[] readModule(ModuleDef module) { + return Utils.readFile(module.Location); } public static bool isCode(short[] nativeCode, byte[] code) { @@ -190,7 +180,7 @@ namespace de4dot.code.deobfuscators { } } - public static EmbeddedResource getEmbeddedResourceFromCodeStrings(ModuleDefinition module, MethodDefinition method) { + public static EmbeddedResource getEmbeddedResourceFromCodeStrings(ModuleDef module, MethodDef method) { foreach (var s in DotNetUtils.getCodeStrings(method)) { var resource = DotNetUtils.getResource(module, s) as EmbeddedResource; if (resource != null) @@ -199,68 +189,56 @@ namespace de4dot.code.deobfuscators { return null; } - public static int readVariableLengthInt32(BinaryReader reader) { - byte b = reader.ReadByte(); - if ((b & 0x80) == 0) - return b; - if ((b & 0x40) == 0) - return (((int)b & 0x3F) << 8) + reader.ReadByte(); - return (((int)b & 0x3F) << 24) + - ((int)reader.ReadByte() << 16) + - ((int)reader.ReadByte() << 8) + - reader.ReadByte(); - } - public static int readVariableLengthInt32(byte[] data, ref int index) { byte b = data[index++]; if ((b & 0x80) == 0) return b; if ((b & 0x40) == 0) return (((int)b & 0x3F) << 8) + data[index++]; - return (((int)b & 0x3F) << 24) + + return (((int)b & 0x1F) << 24) + ((int)data[index++] << 16) + ((int)data[index++] << 8) + data[index++]; } - public static bool hasInteger(MethodDefinition method, uint value) { + public static bool hasInteger(MethodDef method, uint value) { return hasInteger(method, (int)value); } - public static bool hasInteger(MethodDefinition method, int value) { + public static bool hasInteger(MethodDef method, int value) { return indexOfLdci4Instruction(method, value) >= 0; } - public static int indexOfLdci4Instruction(MethodDefinition method, int value) { - if (method == null || method.Body == null) + public static int indexOfLdci4Instruction(MethodDef method, int value) { + if (method == null || method.CilBody == null) return -1; - var instrs = method.Body.Instructions; + var instrs = method.CilBody.Instructions; for (int i = 0; i < instrs.Count; i++) { var instr = instrs[i]; - if (!DotNetUtils.isLdcI4(instr)) + if (!instr.IsLdcI4()) continue; - if (DotNetUtils.getLdcI4Value(instr) == value) + if (instr.GetLdcI4Value() == value) return i; } return -1; } - public static IEnumerable getInitCctors(ModuleDefinition module, int maxCctors) { + public static IEnumerable getInitCctors(ModuleDef module, int maxCctors) { var cctor = DotNetUtils.getModuleTypeCctor(module); if (cctor != null) yield return cctor; - var entryPoint = module.EntryPoint; + var entryPoint = module.EntryPoint as MethodDef; if (entryPoint != null) { - cctor = DotNetUtils.getMethod(entryPoint.DeclaringType, ".cctor"); + cctor = entryPoint.DeclaringType.FindClassConstructor(); if (cctor != null) yield return cctor; } foreach (var type in module.GetTypes()) { - if (type == DotNetUtils.getModuleType(module)) + if (type == module.GlobalType) continue; - cctor = DotNetUtils.getMethod(type, ".cctor"); + cctor = type.FindClassConstructor(); if (cctor == null) continue; yield return cctor; @@ -269,14 +247,14 @@ namespace de4dot.code.deobfuscators { } } - public static List getAllResolveHandlers(MethodDefinition method) { - var list = new List(); - if (method == null || method.Body == null) + public static List getAllResolveHandlers(MethodDef method) { + var list = new List(); + if (method == null || method.CilBody == null) return list; - foreach (var instr in method.Body.Instructions) { + foreach (var instr in method.CilBody.Instructions) { if (instr.OpCode.Code != Code.Ldftn && instr.OpCode.Code != Code.Ldvirtftn) continue; - var handler = instr.Operand as MethodDefinition; + var handler = instr.Operand as MethodDef; if (handler == null) continue; if (!DotNetUtils.isMethod(handler, "System.Reflection.Assembly", "(System.Object,System.ResolveEventArgs)")) @@ -286,7 +264,7 @@ namespace de4dot.code.deobfuscators { return list; } - public static MethodDefinition getResolveMethod(MethodDefinition method) { + public static MethodDef getResolveMethod(MethodDef method) { var handlers = DeobUtils.getAllResolveHandlers(method); if (handlers.Count == 0) return null; diff --git a/de4dot.code/deobfuscators/DeobfuscatorBase.cs b/de4dot.code/deobfuscators/DeobfuscatorBase.cs index fd30566d..e652d228 100644 --- a/de4dot.code/deobfuscators/DeobfuscatorBase.cs +++ b/de4dot.code/deobfuscators/DeobfuscatorBase.cs @@ -25,17 +25,19 @@ using dot10.PE; using de4dot.blocks; using de4dot.blocks.cflow; -namespace de4dot.code.deobfuscators { +namespace de4dot.code { //TODO: I added this iface to Cecil but now you must add something similar to dot10 interface IWriterListener { - internal class MetadataBuilder { - //TODO: Dummy class. Don't use - } - // Called before adding resources, and after adding types, methods, etc. void OnBeforeAddingResources(MetadataBuilder builder); } + //TODO: REMOVE + internal class MetadataBuilder { + //TODO: Dummy class. Don't use + } +} +namespace de4dot.code.deobfuscators { abstract class DeobfuscatorBase : IDeobfuscator, IWriterListener { public const string DEFAULT_VALID_NAME_REGEX = @"^[a-zA-Z_<{$][a-zA-Z_0-9<>{}$.`-]*$"; @@ -497,8 +499,9 @@ namespace de4dot.code.deobfuscators { if (typeDef == null) continue; for (int i = 0; i < customAttrs.Count; i++) { - if (MemberReferenceHelper.compareTypes(customAttrs[i].AttributeType, typeDef)) { + if (new SigComparer().Equals(typeDef, customAttrs[i].AttributeType)) { customAttrs.RemoveAt(i); + i--; Log.v("Removed custom attribute {0} ({1:X8}) (reason: {2})", Utils.removeNewlines(typeDef), typeDef.MDToken.ToUInt32(), @@ -628,14 +631,14 @@ namespace de4dot.code.deobfuscators { return DotNetUtils.getResource(module, strings); } - protected CustomAttribute getAssemblyAttribute(TypeReference attr) { - var list = new List(DotNetUtils.findAttributes(module.Assembly, attr)); - return list.Count == 0 ? null : list[0]; + protected CustomAttribute getAssemblyAttribute(IType attr) { + if (module.Assembly == null) + return null; + return module.Assembly.CustomAttributes.Find(attr); } - protected CustomAttribute getModuleAttribute(TypeReference attr) { - var list = new List(DotNetUtils.findAttributes(module, attr)); - return list.Count == 0 ? null : list[0]; + protected CustomAttribute getModuleAttribute(IType attr) { + return module.CustomAttributes.Find(attr); } protected bool hasMetadataStream(string name) { @@ -646,7 +649,7 @@ namespace de4dot.code.deobfuscators { return false; } - List getObjectsToRemove(IList> removeThese) where T : MemberReference { + List getObjectsToRemove(IList> removeThese) where T : class, ICodedToken { var list = new List(removeThese.Count); foreach (var info in removeThese) { if (info.obj != null) @@ -705,7 +708,7 @@ namespace de4dot.code.deobfuscators { return name != null && checkValidName(name); } - public virtual void OnBeforeAddingResources(IWriterListener.MetadataBuilder builder) { + public virtual void OnBeforeAddingResources(MetadataBuilder builder) { } protected void findAndRemoveInlinedMethods() { diff --git a/de4dot.code/deobfuscators/IDeobfuscator.cs b/de4dot.code/deobfuscators/IDeobfuscator.cs index 47fde0aa..8096f9e1 100644 --- a/de4dot.code/deobfuscators/IDeobfuscator.cs +++ b/de4dot.code/deobfuscators/IDeobfuscator.cs @@ -23,7 +23,9 @@ using Mono.Cecil; using Mono.MyStuff; using de4dot.blocks; using de4dot.blocks.cflow; +#if PORT using de4dot.code.renamer; +#endif using de4dot.PE; namespace de4dot.code.deobfuscators { @@ -53,7 +55,11 @@ namespace de4dot.code.deobfuscators { RenameResourceKeys = 2, } - public interface IDeobfuscator : INameChecker { + public interface IDeobfuscator +#if PORT + : INameChecker +#endif + { string Type { get; } string TypeLong { get; } string Name { get; } diff --git a/de4dot.code/deobfuscators/MemberReferenceBuilder.cs b/de4dot.code/deobfuscators/MemberReferenceBuilder.cs index 623945e0..29bbff42 100644 --- a/de4dot.code/deobfuscators/MemberReferenceBuilder.cs +++ b/de4dot.code/deobfuscators/MemberReferenceBuilder.cs @@ -19,158 +19,167 @@ using System; using System.Collections.Generic; -using Mono.Cecil; +using dot10.DotNet; +using dot10.DotNet.MD; using de4dot.blocks; namespace de4dot.code.deobfuscators { - class MemberReferenceBuilder { - ModuleDefinition module; - Dictionary createdTypes = new Dictionary(); + class MemberReferenceBuilder : ICorLibTypes { + ModuleDefMD module; + Dictionary createdTypes = new Dictionary(TypeEqualityComparer.Instance); - public MemberReferenceBuilder(ModuleDefinition module) { + public MemberReferenceBuilder(ModuleDefMD module) { this.module = module; } - public IMetadataScope CorLib { - get { return module.TypeSystem.Corlib; } + public AssemblyRef CorLib { + get { return module.CorLibTypes.AssemblyRef; } } - public TypeReference Object { - get { return module.TypeSystem.Object; } + public AssemblyRef AssemblyRef { + get { return module.CorLibTypes.AssemblyRef; } } - public TypeReference Void { - get { return module.TypeSystem.Void; } + public CorLibTypeSig Object { + get { return module.CorLibTypes.Object; } } - public TypeReference Boolean { - get { return module.TypeSystem.Boolean; } + public CorLibTypeSig Void { + get { return module.CorLibTypes.Void; } } - public TypeReference Char { - get { return module.TypeSystem.Char; } + public CorLibTypeSig Boolean { + get { return module.CorLibTypes.Boolean; } } - public TypeReference SByte { - get { return module.TypeSystem.SByte; } + public CorLibTypeSig Char { + get { return module.CorLibTypes.Char; } } - public TypeReference Byte { - get { return module.TypeSystem.Byte; } + public CorLibTypeSig SByte { + get { return module.CorLibTypes.SByte; } } - public TypeReference Int16 { - get { return module.TypeSystem.Int16; } + public CorLibTypeSig Byte { + get { return module.CorLibTypes.Byte; } } - public TypeReference UInt16 { - get { return module.TypeSystem.UInt16; } + public CorLibTypeSig Int16 { + get { return module.CorLibTypes.Int16; } } - public TypeReference Int32 { - get { return module.TypeSystem.Int32; } + public CorLibTypeSig UInt16 { + get { return module.CorLibTypes.UInt16; } } - public TypeReference UInt32 { - get { return module.TypeSystem.UInt32; } + public CorLibTypeSig Int32 { + get { return module.CorLibTypes.Int32; } } - public TypeReference Int64 { - get { return module.TypeSystem.Int64; } + public CorLibTypeSig UInt32 { + get { return module.CorLibTypes.UInt32; } } - public TypeReference UInt64 { - get { return module.TypeSystem.UInt64; } + public CorLibTypeSig Int64 { + get { return module.CorLibTypes.Int64; } } - public TypeReference Single { - get { return module.TypeSystem.Single; } + public CorLibTypeSig UInt64 { + get { return module.CorLibTypes.UInt64; } } - public TypeReference Double { - get { return module.TypeSystem.Double; } + public CorLibTypeSig Single { + get { return module.CorLibTypes.Single; } } - public TypeReference IntPtr { - get { return module.TypeSystem.IntPtr; } + public CorLibTypeSig Double { + get { return module.CorLibTypes.Double; } } - public TypeReference UIntPtr { - get { return module.TypeSystem.UIntPtr; } + public CorLibTypeSig IntPtr { + get { return module.CorLibTypes.IntPtr; } } - public TypeReference String { - get { return module.TypeSystem.String; } + public CorLibTypeSig UIntPtr { + get { return module.CorLibTypes.UIntPtr; } } - public TypeReference TypedReference { - get { return module.TypeSystem.TypedReference; } + public CorLibTypeSig String { + get { return module.CorLibTypes.String; } } - public TypeReference type(string ns, string name, string asmSimpleName) { + public CorLibTypeSig TypedReference { + get { return module.CorLibTypes.TypedReference; } + } + + public ClassSig type(string ns, string name, string asmSimpleName) { return type(ns, name, findAssemblyReference(asmSimpleName)); } - public TypeReference type(string ns, string name) { + public ClassSig type(string ns, string name) { return type(ns, name, CorLib); } - public TypeReference type(string ns, string name, IMetadataScope asmRef) { - return type(false, ns, name, asmRef); + public ClassSig type(string ns, string name, AssemblyRef asmRef) { + return (ClassSig)type(false, ns, name, asmRef); } - public TypeReference valueType(string ns, string name, string asmSimpleName) { + public ValueTypeSig valueType(string ns, string name, string asmSimpleName) { return valueType(ns, name, findAssemblyReference(asmSimpleName)); } - public TypeReference valueType(string ns, string name) { + public ValueTypeSig valueType(string ns, string name) { return valueType(ns, name, CorLib); } - public TypeReference valueType(string ns, string name, IMetadataScope asmRef) { - return type(true, ns, name, asmRef); + public ValueTypeSig valueType(string ns, string name, AssemblyRef asmRef) { + return (ValueTypeSig)type(true, ns, name, asmRef); } - public TypeReference type(bool isValueType, string ns, string name, IMetadataScope asmRef) { - var typeRef = new TypeReference(ns, name, module, asmRef); - typeRef.IsValueType = isValueType; - return add(isValueType, typeRef); + public ClassOrValueTypeSig type(bool isValueType, string ns, string name, IResolutionScope resolutionScope) { + var typeRef = module.UpdateRowId(new TypeRefUser(module, ns, name, resolutionScope)); + ClassOrValueTypeSig type; + if (isValueType) + type = new ValueTypeSig(typeRef); + else + type = new ClassSig(typeRef); + return (ClassOrValueTypeSig)add(type); } - public TypeReference array(TypeReference typeRef) { - return add(false, new ArrayType(typeRef)); + public ArraySig array(TypeSig typeRef) { + return (ArraySig)add(new ArraySig(typeRef)); } - TypeReference add(bool isValueType, TypeReference typeRef) { - var key = new TypeReferenceKey(typeRef); - TypeReference createdTypeRef; - if (createdTypes.TryGetValue(key, out createdTypeRef)) { - if (createdTypeRef.IsValueType != isValueType) + TypeSig add(TypeSig typeRef) { + TypeSig createdTypeRef; + if (createdTypes.TryGetValue(typeRef, out createdTypeRef)) { + if (createdTypeRef.ElementType != typeRef.ElementType) throw new ApplicationException(string.Format("Type {0}'s IsValueType is not correct", createdTypeRef)); return createdTypeRef; } - createdTypes[key] = typeRef; + createdTypes[typeRef] = typeRef; return typeRef; } - public MethodReference instanceMethod(string name, TypeReference declaringType, TypeReference returnType, params TypeReference[] args) { + public MemberRef instanceMethod(string name, IMemberRefParent declaringType, TypeSig returnType, params TypeSig[] args) { return method(true, name, declaringType, returnType, args); } - public MethodReference staticMethod(string name, TypeReference declaringType, TypeReference returnType, params TypeReference[] args) { + public MemberRef staticMethod(string name, IMemberRefParent declaringType, TypeSig returnType, params TypeSig[] args) { return method(false, name, declaringType, returnType, args); } - public MethodReference method(bool isInstance, string name, TypeReference declaringType, TypeReference returnType, params TypeReference[] args) { - var method = new MethodReference(name, returnType, declaringType); - method.HasThis = isInstance; - foreach (var arg in args) - method.Parameters.Add(new ParameterDefinition(arg)); - return method; + public MemberRef method(bool isInstance, string name, IMemberRefParent declaringType, TypeSig returnType, params TypeSig[] args) { + MethodSig sig; + if (isInstance) + sig = MethodSig.CreateInstance(returnType, args); + else + sig = MethodSig.CreateStatic(returnType, args); + return module.UpdateRowId(new MemberRefUser(module, name, sig, declaringType)); } - AssemblyNameReference findAssemblyReference(string asmSimpleName) { - AssemblyNameReference asmRef = null; + AssemblyRef findAssemblyReference(string asmSimpleName) { + AssemblyRef asmRef = null; foreach (var asmRef2 in findAssemblyReferences(asmSimpleName)) { if (asmRef == null || asmRef.Version == null || (asmRef2.Version != null && asmRef2.Version > asmRef.Version)) asmRef = asmRef2; @@ -180,10 +189,11 @@ namespace de4dot.code.deobfuscators { return asmRef; } - List findAssemblyReferences(string asmSimpleName) { - var asmRefs = new List(); - foreach (var asmRef in module.AssemblyReferences) { - if (asmRef.Name == asmSimpleName) + List findAssemblyReferences(string asmSimpleName) { + var asmRefs = new List(); + var name = new UTF8String(asmSimpleName); + foreach (var asmRef in module.GetAssemblyRefs()) { + if (UTF8String.Equals(asmRef.Name, name)) asmRefs.Add(asmRef); } return asmRefs; diff --git a/de4dot.code/deobfuscators/ProxyCallFixerBase.cs b/de4dot.code/deobfuscators/ProxyCallFixerBase.cs index aaa25258..34379e50 100644 --- a/de4dot.code/deobfuscators/ProxyCallFixerBase.cs +++ b/de4dot.code/deobfuscators/ProxyCallFixerBase.cs @@ -19,15 +19,15 @@ using System; using System.Collections.Generic; -using Mono.Cecil; -using Mono.Cecil.Cil; +using dot10.DotNet; +using dot10.DotNet.Emit; using de4dot.blocks; namespace de4dot.code.deobfuscators { abstract class ProxyCallFixerBase { - protected ModuleDefinition module; - protected List delegateCreatorMethods = new List(); - protected Dictionary delegateTypesDict = new Dictionary(); + protected ModuleDefMD module; + protected List delegateCreatorMethods = new List(); + protected Dictionary delegateTypesDict = new Dictionary(); protected int errors = 0; public int Errors { @@ -35,10 +35,10 @@ namespace de4dot.code.deobfuscators { } protected class DelegateInfo { - public MethodReference methodRef; // Method we should call - public FieldDefinition field; // Field holding the Delegate instance + public IMethod methodRef; // Method we should call + public FieldDef field; // Field holding the Delegate instance public OpCode callOpcode; - public DelegateInfo(FieldDefinition field, MethodReference methodRef, OpCode callOpcode) { + public DelegateInfo(FieldDef field, IMethod methodRef, OpCode callOpcode) { this.field = field; this.methodRef = methodRef; this.callOpcode = callOpcode; @@ -47,30 +47,30 @@ namespace de4dot.code.deobfuscators { public int RemovedDelegateCreatorCalls { get; set; } - public IEnumerable DelegateTypes { + public IEnumerable DelegateTypes { get { return delegateTypesDict.Keys; } } - public IEnumerable DelegateCreatorTypes { + public IEnumerable DelegateCreatorTypes { get { foreach (var method in delegateCreatorMethods) yield return method.DeclaringType; } } - public virtual IEnumerable> OtherMethods { - get { return new List>(); } + public virtual IEnumerable> OtherMethods { + get { return new List>(); } } public bool Detected { get { return delegateCreatorMethods.Count != 0; } } - protected ProxyCallFixerBase(ModuleDefinition module) { + protected ProxyCallFixerBase(ModuleDefMD module) { this.module = module; } - protected ProxyCallFixerBase(ModuleDefinition module, ProxyCallFixerBase oldOne) { + protected ProxyCallFixerBase(ModuleDefMD module, ProxyCallFixerBase oldOne) { this.module = module; foreach (var method in oldOne.delegateCreatorMethods) delegateCreatorMethods.Add(lookup(method, "Could not find delegate creator method")); @@ -84,17 +84,17 @@ namespace de4dot.code.deobfuscators { return new DelegateInfo(field, method, di.callOpcode); } - protected T lookup(T def, string errorMessage) where T : MemberReference { + protected T lookup(T def, string errorMessage) where T : class, ICodedToken { return DeobUtils.lookup(module, def, errorMessage); } - protected void setDelegateCreatorMethod(MethodDefinition delegateCreatorMethod) { + protected void setDelegateCreatorMethod(MethodDef delegateCreatorMethod) { if (delegateCreatorMethod == null) return; delegateCreatorMethods.Add(delegateCreatorMethod); } - protected bool isDelegateCreatorMethod(MethodDefinition method) { + protected bool isDelegateCreatorMethod(MethodDef method) { foreach (var m in delegateCreatorMethods) { if (m == method) return true; @@ -102,7 +102,7 @@ namespace de4dot.code.deobfuscators { return false; } - protected virtual IEnumerable getDelegateTypes() { + protected virtual IEnumerable getDelegateTypes() { foreach (var type in module.Types) { if (type.BaseType == null || type.BaseType.FullName != "System.MulticastDelegate") continue; @@ -182,11 +182,11 @@ namespace de4dot.code.deobfuscators { abstract class ProxyCallFixer1 : ProxyCallFixerBase { FieldDefinitionAndDeclaringTypeDict fieldToDelegateInfo = new FieldDefinitionAndDeclaringTypeDict(); - protected ProxyCallFixer1(ModuleDefinition module) + protected ProxyCallFixer1(ModuleDefMD module) : base(module) { } - protected ProxyCallFixer1(ModuleDefinition module, ProxyCallFixer1 oldOne) + protected ProxyCallFixer1(ModuleDefMD module, ProxyCallFixer1 oldOne) : base(module, oldOne) { foreach (var key in oldOne.fieldToDelegateInfo.getKeys()) fieldToDelegateInfo.add(lookup(key, "Could not find field"), copy(oldOne.fieldToDelegateInfo.find(key))); @@ -196,7 +196,7 @@ namespace de4dot.code.deobfuscators { fieldToDelegateInfo.add(di.field, di); } - protected DelegateInfo getDelegateInfo(FieldReference field) { + protected DelegateInfo getDelegateInfo(IField field) { if (field == null) return null; return fieldToDelegateInfo.find(field); @@ -209,8 +209,8 @@ namespace de4dot.code.deobfuscators { Log.v("Finding all proxy delegates"); foreach (var tmp in getDelegateTypes()) { var type = tmp; - var cctor = DotNetUtils.getMethod(type, ".cctor"); - if (cctor == null || !cctor.HasBody) + var cctor = type.FindClassConstructor(); + if (cctor == null || !cctor.HasCilBody) continue; if (!type.HasFields) continue; @@ -219,7 +219,7 @@ namespace de4dot.code.deobfuscators { if (context == null) continue; - Log.v("Found proxy delegate: {0} ({1:X8})", Utils.removeNewlines(type), type.MetadataToken.ToUInt32()); + Log.v("Found proxy delegate: {0} ({1:X8})", Utils.removeNewlines(type), type.MDToken.ToUInt32()); RemovedDelegateCreatorCalls++; Log.indent(); @@ -227,7 +227,7 @@ namespace de4dot.code.deobfuscators { if (!field.IsStatic) continue; - MethodReference calledMethod; + IMethod calledMethod; OpCode callOpcode; getCallInfo(context, field, out calledMethod, out callOpcode); @@ -238,15 +238,15 @@ namespace de4dot.code.deobfuscators { Utils.removeNewlines(field.Name), callOpcode, Utils.removeNewlines(calledMethod), - calledMethod.MetadataToken.ToUInt32()); + calledMethod.MDToken.Raw); } Log.deIndent(); delegateTypesDict[type] = true; } } - protected abstract object checkCctor(ref TypeDefinition type, MethodDefinition cctor); - protected abstract void getCallInfo(object context, FieldDefinition field, out MethodReference calledMethod, out OpCode callOpcode); + protected abstract object checkCctor(ref TypeDef type, MethodDef cctor); + protected abstract void getCallInfo(object context, FieldDef field, out IMethod calledMethod, out OpCode callOpcode); protected override bool deobfuscate(Blocks blocks, IList allBlocks) { var removeInfos = new Dictionary>(); @@ -258,7 +258,7 @@ namespace de4dot.code.deobfuscators { if (instr.OpCode != OpCodes.Ldsfld) continue; - var di = getDelegateInfo(instr.Operand as FieldReference); + var di = getDelegateInfo(instr.Operand as IField); if (di == null) continue; @@ -271,9 +271,9 @@ namespace de4dot.code.deobfuscators { errors++; Log.w("Could not fix proxy call. Method: {0} ({1:X8}), Proxy type: {2} ({3:X8})", Utils.removeNewlines(blocks.Method), - blocks.Method.MetadataToken.ToInt32(), + blocks.Method.MDToken.ToInt32(), Utils.removeNewlines(di.field.DeclaringType), - di.field.DeclaringType.MetadataToken.ToInt32()); + di.field.DeclaringType.MDToken.ToInt32()); } } } @@ -296,7 +296,7 @@ namespace de4dot.code.deobfuscators { if (stack <= 0) return null; var instr = instrs[i]; - DotNetUtils.updateStack(instr.Instruction, ref stack, false); + instr.Instruction.UpdateStack(ref stack, false); if (stack < 0) return null; @@ -305,7 +305,7 @@ namespace de4dot.code.deobfuscators { return null; continue; } - var calledMethod = instr.Operand as MethodReference; + var calledMethod = instr.Operand as IMethod; if (calledMethod == null) return null; if (stack != (DotNetUtils.hasReturnValue(calledMethod) ? 1 : 0)) @@ -336,28 +336,25 @@ namespace de4dot.code.deobfuscators { // The obfuscator could be buggy and call a proxy delegate without pushing the // instance field. SA has done it, so let's fix it. - void fixBrokenCalls(MethodDefinition obfuscatedMethod, IList allBlocks) { + void fixBrokenCalls(MethodDef obfuscatedMethod, IList allBlocks) { foreach (var block in allBlocks) { var instrs = block.Instructions; for (int i = 0; i < instrs.Count; i++) { var call = instrs[i]; if (call.OpCode != OpCodes.Call && call.OpCode != OpCodes.Callvirt) continue; - var methodRef = call.Operand as MethodReference; + var methodRef = call.Operand as IMethod; if (methodRef == null || methodRef.Name != "Invoke") continue; - var method = DotNetUtils.getMethod(module, methodRef); - if (method == null) + MethodDef method = DotNetUtils.getMethod2(module, methodRef); + if (method == null || method.DeclaringType == null) continue; - var declaringType = DotNetUtils.getType(module, method.DeclaringType); - if (declaringType == null) - continue; - if (!delegateTypesDict.ContainsKey(declaringType)) + if (!delegateTypesDict.ContainsKey(method.DeclaringType)) continue; // Oooops!!! The obfuscator is buggy. Well, let's hope it is, or it's my code. ;) - Log.w("Holy obfuscator bugs, Batman! Found a proxy delegate call with no instance push in {0:X8}. Replacing it with a throw...", obfuscatedMethod.MetadataToken.ToInt32()); + Log.w("Holy obfuscator bugs, Batman! Found a proxy delegate call with no instance push in {0:X8}. Replacing it with a throw...", obfuscatedMethod.MDToken.ToInt32()); block.insert(i, Instruction.Create(OpCodes.Ldnull)); block.replace(i + 1, 1, Instruction.Create(OpCodes.Throw)); i++; @@ -373,11 +370,11 @@ namespace de4dot.code.deobfuscators { abstract class ProxyCallFixer2 : ProxyCallFixerBase { MethodDefinitionAndDeclaringTypeDict proxyMethodToDelegateInfo = new MethodDefinitionAndDeclaringTypeDict(); - protected ProxyCallFixer2(ModuleDefinition module) + protected ProxyCallFixer2(ModuleDefMD module) : base(module) { } - protected ProxyCallFixer2(ModuleDefinition module, ProxyCallFixer2 oldOne) + protected ProxyCallFixer2(ModuleDefMD module, ProxyCallFixer2 oldOne) : base(module, oldOne) { foreach (var oldMethod in oldOne.proxyMethodToDelegateInfo.getKeys()) { var oldDi = oldOne.proxyMethodToDelegateInfo.find(oldMethod); @@ -396,8 +393,8 @@ namespace de4dot.code.deobfuscators { protected void find2() { foreach (var type in getDelegateTypes()) { - var cctor = DotNetUtils.getMethod(type, ".cctor"); - if (cctor == null || !cctor.HasBody) + var cctor = type.FindClassConstructor(); + if (cctor == null || !cctor.HasCilBody) continue; if (!type.HasFields) continue; @@ -406,17 +403,17 @@ namespace de4dot.code.deobfuscators { if (context == null) continue; - Log.v("Found proxy delegate: {0} ({1:X8})", Utils.removeNewlines(type), type.MetadataToken.ToUInt32()); + Log.v("Found proxy delegate: {0} ({1:X8})", Utils.removeNewlines(type), type.MDToken.ToUInt32()); RemovedDelegateCreatorCalls++; var fieldToMethod = getFieldToMethodDictionary(type); Log.indent(); foreach (var field in type.Fields) { - MethodDefinition proxyMethod; + MethodDef proxyMethod; if (!fieldToMethod.TryGetValue(field, out proxyMethod)) continue; - MethodReference calledMethod; + IMethod calledMethod; OpCode callOpcode; getCallInfo(context, field, out calledMethod, out callOpcode); @@ -427,32 +424,32 @@ namespace de4dot.code.deobfuscators { Utils.removeNewlines(field.Name), callOpcode, Utils.removeNewlines(calledMethod), - calledMethod.MetadataToken.ToUInt32()); + calledMethod.MDToken.ToUInt32()); } Log.deIndent(); delegateTypesDict[type] = true; } } - protected void add(MethodDefinition method, DelegateInfo di) { + protected void add(MethodDef method, DelegateInfo di) { proxyMethodToDelegateInfo.add(method, di); } - protected abstract object checkCctor(TypeDefinition type, MethodDefinition cctor); - protected abstract void getCallInfo(object context, FieldDefinition field, out MethodReference calledMethod, out OpCode callOpcode); + protected abstract object checkCctor(TypeDef type, MethodDef cctor); + protected abstract void getCallInfo(object context, FieldDef field, out IMethod calledMethod, out OpCode callOpcode); - Dictionary getFieldToMethodDictionary(TypeDefinition type) { - var dict = new Dictionary(); + Dictionary getFieldToMethodDictionary(TypeDef type) { + var dict = new Dictionary(); foreach (var method in type.Methods) { - if (!method.IsStatic || !method.HasBody || method.Name == ".cctor") + if (!method.IsStatic || !method.HasCilBody || method.Name == ".cctor") continue; - var instructions = method.Body.Instructions; + var instructions = method.CilBody.Instructions; for (int i = 0; i < instructions.Count; i++) { var instr = instructions[i]; if (instr.OpCode.Code != Code.Ldsfld) continue; - var field = instr.Operand as FieldDefinition; + var field = instr.Operand as FieldDef; if (field == null) continue; @@ -473,7 +470,7 @@ namespace de4dot.code.deobfuscators { if (instr.OpCode != OpCodes.Call) continue; - var method = instr.Operand as MethodReference; + var method = instr.Operand as IMethod; if (method == null) continue; var di = proxyMethodToDelegateInfo.find(method); @@ -493,11 +490,11 @@ namespace de4dot.code.deobfuscators { // ldsfld delegate instance // call static method abstract class ProxyCallFixer3 : ProxyCallFixer1 { - protected ProxyCallFixer3(ModuleDefinition module) + protected ProxyCallFixer3(ModuleDefMD module) : base(module) { } - protected ProxyCallFixer3(ModuleDefinition module, ProxyCallFixer3 oldOne) + protected ProxyCallFixer3(ModuleDefMD module, ProxyCallFixer3 oldOne) : base(module, oldOne) { } @@ -514,10 +511,10 @@ namespace de4dot.code.deobfuscators { }; } - static MethodReference getCalledMethod(Instr instr) { + static IMethod getCalledMethod(Instr instr) { if (instr.OpCode.Code != Code.Call) return null; - return instr.Operand as MethodReference; + return instr.Operand as IMethod; } } } diff --git a/de4dot.code/deobfuscators/TypesRestorer.cs b/de4dot.code/deobfuscators/TypesRestorer.cs index 2b3c003c..147d8ebc 100644 --- a/de4dot.code/deobfuscators/TypesRestorer.cs +++ b/de4dot.code/deobfuscators/TypesRestorer.cs @@ -19,9 +19,8 @@ using System; using System.Collections.Generic; -using Mono.Cecil; -using Mono.Cecil.Cil; -using Mono.Cecil.Metadata; +using dot10.DotNet; +using dot10.DotNet.Emit; using de4dot.blocks; namespace de4dot.code.deobfuscators { @@ -29,31 +28,31 @@ namespace de4dot.code.deobfuscators { // This thing requires a lot more code than I have time to do now (similar to symbol renaming) // so it will be a basic implementation only. abstract class TypesRestorerBase { - ModuleDefinition module; - List allMethods; - Dictionary> argInfos = new Dictionary>(); - TypeInfo methodReturnInfo; - Dictionary> fieldWrites = new Dictionary>(); + ModuleDef module; + List allMethods; + Dictionary> argInfos = new Dictionary>(); + TypeInfo methodReturnInfo; + Dictionary> fieldWrites = new Dictionary>(); Dictionary updatedMethods = new Dictionary(); Dictionary updatedFields = new Dictionary(); class UpdatedMethod { public int token; - public TypeReference[] newArgTypes; - public TypeReference newReturnType; + public TypeSig[] newArgTypes; + public TypeSig newReturnType; - public UpdatedMethod(MethodDefinition method) { - token = method.MetadataToken.ToInt32(); - newArgTypes = new TypeReference[DotNetUtils.getArgsCount(method)]; + public UpdatedMethod(MethodDef method) { + token = method.MDToken.ToInt32(); + newArgTypes = new TypeSig[DotNetUtils.getArgsCount(method)]; } } class UpdatedField { public int token; - public TypeReference newFieldType; + public TypeSig newFieldType; - public UpdatedField(FieldDefinition field) { - token = field.MetadataToken.ToInt32(); + public UpdatedField(FieldDef field) { + token = field.MDToken.ToInt32(); } } @@ -90,7 +89,7 @@ namespace de4dot.code.deobfuscators { types.Clear(); } - public bool updateNewType(ModuleDefinition module) { + public bool updateNewType(ModuleDef module) { if (types.Count == 0) return false; @@ -114,20 +113,20 @@ namespace de4dot.code.deobfuscators { } } - public TypesRestorerBase(ModuleDefinition module) { + public TypesRestorerBase(ModuleDef module) { this.module = module; } - UpdatedMethod getUpdatedMethod(MethodDefinition method) { - int token = method.MetadataToken.ToInt32(); + UpdatedMethod getUpdatedMethod(MethodDef method) { + int token = method.MDToken.ToInt32(); UpdatedMethod updatedMethod; if (updatedMethods.TryGetValue(token, out updatedMethod)) return updatedMethod; return updatedMethods[token] = new UpdatedMethod(method); } - UpdatedField getUpdatedField(FieldDefinition field) { - int token = field.MetadataToken.ToInt32(); + UpdatedField getUpdatedField(FieldDef field) { + int token = field.MDToken.ToInt32(); UpdatedField updatedField; if (updatedFields.TryGetValue(token, out updatedField)) return updatedField; @@ -135,7 +134,7 @@ namespace de4dot.code.deobfuscators { } public void deobfuscate() { - allMethods = new List(); + allMethods = new List(); addAllMethods(); addAllFields(); @@ -151,11 +150,11 @@ namespace de4dot.code.deobfuscators { addMethods(type.Methods); } - void addMethods(IEnumerable methods) { + void addMethods(IEnumerable methods) { allMethods.AddRange(methods); } - void addMethod(MethodDefinition method) { + void addMethod(MethodDef method) { allMethods.Add(method); } @@ -166,7 +165,7 @@ namespace de4dot.code.deobfuscators { continue; var key = new FieldReferenceAndDeclaringTypeKey(field); - fieldWrites[key] = new TypeInfo(field); + fieldWrites[key] = new TypeInfo(field); } } } @@ -190,7 +189,7 @@ namespace de4dot.code.deobfuscators { fields.Sort((a, b) => Utils.compareInt32(a.token, b.token)); Log.indent(); foreach (var updatedField in fields) - Log.v("Field {0:X8}: type {1} ({2:X8})", updatedField.token, Utils.removeNewlines(updatedField.newFieldType.FullName), updatedField.newFieldType.MetadataToken.ToInt32()); + Log.v("Field {0:X8}: type {1} ({2:X8})", updatedField.token, Utils.removeNewlines(updatedField.newFieldType.FullName), updatedField.newFieldType.MDToken.ToInt32()); Log.deIndent(); } @@ -208,7 +207,7 @@ namespace de4dot.code.deobfuscators { if (updatedMethod.newReturnType != null) { Log.v("ret: {0} ({1:X8})", Utils.removeNewlines(updatedMethod.newReturnType.FullName), - updatedMethod.newReturnType.MetadataToken.ToInt32()); + updatedMethod.newReturnType.MDToken.ToInt32()); } for (int i = 0; i < updatedMethod.newArgTypes.Length; i++) { var updatedArg = updatedMethod.newArgTypes[i]; @@ -217,7 +216,7 @@ namespace de4dot.code.deobfuscators { Log.v("arg {0}: {1} ({2:X8})", i, Utils.removeNewlines(updatedArg.FullName), - updatedArg.MetadataToken.ToInt32()); + updatedArg.MDToken.ToInt32()); } Log.deIndent(); } @@ -227,7 +226,7 @@ namespace de4dot.code.deobfuscators { bool deobfuscateMethods() { bool changed = false; foreach (var method in allMethods) { - methodReturnInfo = new TypeInfo(method.MethodReturnType.Parameter2); + methodReturnInfo = new TypeInfo(method.MethodReturnType.Parameter2); deobfuscateMethod(method); if (methodReturnInfo.updateNewType(module)) { @@ -247,14 +246,14 @@ namespace de4dot.code.deobfuscators { return changed; } - static int sortTypeInfos(TypeInfo a, TypeInfo b) { - if (a.arg.Method.MetadataToken.ToInt32() < b.arg.Method.MetadataToken.ToInt32()) return -1; - if (a.arg.Method.MetadataToken.ToInt32() > b.arg.Method.MetadataToken.ToInt32()) return 1; + static int sortTypeInfos(TypeInfo a, TypeInfo b) { + if (a.arg.Method.MDToken.ToInt32() < b.arg.Method.MDToken.ToInt32()) return -1; + if (a.arg.Method.MDToken.ToInt32() > b.arg.Method.MDToken.ToInt32()) return 1; return Utils.compareInt32(a.arg.Sequence, b.arg.Sequence); } - void deobfuscateMethod(MethodDefinition method) { + void deobfuscateMethod(MethodDef method) { if (!method.IsStatic || method.Body == null) return; @@ -264,7 +263,7 @@ namespace de4dot.code.deobfuscators { foreach (var arg in method.Parameters) { if (!isUnknownType(arg)) continue; - argInfos[arg] = new TypeInfo(arg); + argInfos[arg] = new TypeInfo(arg); } if (argInfos.Count == 0 && !fixReturnType) return; @@ -362,7 +361,7 @@ namespace de4dot.code.deobfuscators { case Code.Starg_S: case Code.Ldelema: - case Code.Ldelem_Any: + case Code.Ldelem: case Code.Ldelem_I: case Code.Ldelem_I1: case Code.Ldelem_I2: @@ -389,7 +388,7 @@ namespace de4dot.code.deobfuscators { case Code.Ldobj: - case Code.Stelem_Any: + case Code.Stelem: case Code.Stelem_I: case Code.Stelem_I1: case Code.Stelem_I2: @@ -415,7 +414,7 @@ namespace de4dot.code.deobfuscators { } } - static ParameterDefinition getParameter(IList parameters, Instruction instr) { + static Parameter getParameter(IList parameters, Instruction instr) { switch (instr.OpCode.Code) { case Code.Ldarg: case Code.Ldarg_S: @@ -430,32 +429,32 @@ namespace de4dot.code.deobfuscators { } } - bool addMethodArgType(IGenericParameterProvider gpp, ParameterDefinition methodParam, FieldReference field) { + bool addMethodArgType(IGenericParameterProvider gpp, Parameter methodParam, FieldReference field) { if (field == null) return false; return addMethodArgType(gpp, methodParam, field.FieldType); } - bool addMethodArgType(IGenericParameterProvider gpp, ParameterDefinition methodParam, VariableDefinition otherLocal) { + bool addMethodArgType(IGenericParameterProvider gpp, Parameter methodParam, VariableDefinition otherLocal) { if (otherLocal == null) return false; return addMethodArgType(gpp, methodParam, otherLocal.VariableType); } - bool addMethodArgType(IGenericParameterProvider gpp, ParameterDefinition methodParam, ParameterDefinition otherParam) { + bool addMethodArgType(IGenericParameterProvider gpp, Parameter methodParam, Parameter otherParam) { if (otherParam == null) return false; return addMethodArgType(gpp, methodParam, otherParam.ParameterType); } - bool addMethodArgType(IGenericParameterProvider gpp, ParameterDefinition methodParam, TypeReference type) { + bool addMethodArgType(IGenericParameterProvider gpp, Parameter methodParam, TypeReference type) { if (methodParam == null || type == null) return false; if (!isValidType(gpp, type)) return false; - TypeInfo info; + TypeInfo info; if (!argInfos.TryGetValue(methodParam, out info)) return false; if (info.Types.ContainsKey(new TypeReferenceKey(type))) @@ -476,7 +475,7 @@ namespace de4dot.code.deobfuscators { for (int i = 0; i < instructions.Count; i++) { var instr = instructions[i]; TypeReference fieldType = null; - TypeInfo info = null; + TypeInfo info = null; FieldReference field; switch (instr.OpCode.Code) { case Code.Stfld: @@ -527,7 +526,7 @@ namespace de4dot.code.deobfuscators { } bool changed = false; - var removeThese = new List(); + var removeThese = new List(); foreach (var info in fieldWrites.Values) { if (info.updateNewType(module)) { removeThese.Add(info.arg); @@ -541,7 +540,7 @@ namespace de4dot.code.deobfuscators { return changed; } - TypeReference getLoadedType(IGenericParameterProvider gpp, MethodDefinition method, IList instructions, int instrIndex, out bool wasNewobj) { + TypeReference getLoadedType(IGenericParameterProvider gpp, MethodDef method, IList instructions, int instrIndex, out bool wasNewobj) { var fieldType = MethodStack.getLoadedType(method, instructions, instrIndex, out wasNewobj); if (fieldType == null || !isValidType(gpp, fieldType)) return null; @@ -605,7 +604,7 @@ namespace de4dot.code.deobfuscators { protected abstract bool isUnknownType(object o); - static TypeReference getCommonBaseClass(ModuleDefinition module, TypeReference a, TypeReference b) { + static TypeReference getCommonBaseClass(ModuleDef module, TypeReference a, TypeReference b) { if (DotNetUtils.isDelegate(a) && DotNetUtils.derivesFromDelegate(DotNetUtils.getType(module, b))) return b; if (DotNetUtils.isDelegate(b) && DotNetUtils.derivesFromDelegate(DotNetUtils.getType(module, a))) @@ -615,7 +614,7 @@ namespace de4dot.code.deobfuscators { } class TypesRestorer : TypesRestorerBase { - public TypesRestorer(ModuleDefinition module) + public TypesRestorer(ModuleDef module) : base(module) { } @@ -630,11 +629,11 @@ namespace de4dot.code.deobfuscators { } protected override bool isUnknownType(object o) { - var arg = o as ParameterDefinition; + var arg = o as Parameter; if (arg != null) return MemberReferenceHelper.isSystemObject(arg.ParameterType); - var field = o as FieldDefinition; + var field = o as FieldDef; if (field != null) return MemberReferenceHelper.isSystemObject(field.FieldType); diff --git a/dot10 b/dot10 index c12a2f59..7eb0fb7e 160000 --- a/dot10 +++ b/dot10 @@ -1 +1 @@ -Subproject commit c12a2f599e25b32dfee2cc42be4f13dc2edc06d4 +Subproject commit 7eb0fb7e6e47c79eebbef0ea9ea404f9b81fde51