diff --git a/de4dot.code/de4dot.code.csproj b/de4dot.code/de4dot.code.csproj index 9dfa25a2..ddd2ba13 100644 --- a/de4dot.code/de4dot.code.csproj +++ b/de4dot.code/de4dot.code.csproj @@ -250,11 +250,11 @@ - - - - - + + + + + diff --git a/de4dot.code/deobfuscators/Spices_Net/ResourceNamesRestorer.cs b/de4dot.code/deobfuscators/Spices_Net/ResourceNamesRestorer.cs index c1881fa1..0e370b8c 100644 --- a/de4dot.code/deobfuscators/Spices_Net/ResourceNamesRestorer.cs +++ b/de4dot.code/deobfuscators/Spices_Net/ResourceNamesRestorer.cs @@ -24,11 +24,11 @@ using de4dot.blocks; namespace de4dot.code.deobfuscators.Spices_Net { class ResourceNamesRestorer { - ModuleDefinition module; + ModuleDefMD module; TypeDef resourceManagerType; TypeDef componentResourceManagerType; - MethodDefinitionAndDeclaringTypeDict resourceManagerCtors = new MethodDefinitionAndDeclaringTypeDict(); - MethodDefinitionAndDeclaringTypeDict componentManagerCtors = new MethodDefinitionAndDeclaringTypeDict(); + MethodDefinitionAndDeclaringTypeDict resourceManagerCtors = new MethodDefinitionAndDeclaringTypeDict(); + MethodDefinitionAndDeclaringTypeDict componentManagerCtors = new MethodDefinitionAndDeclaringTypeDict(); public TypeDef ResourceManagerType { get { return resourceManagerType; } @@ -38,7 +38,7 @@ namespace de4dot.code.deobfuscators.Spices_Net { get { return componentResourceManagerType; } } - public ResourceNamesRestorer(ModuleDefinition module) { + public ResourceNamesRestorer(ModuleDefMD module) { this.module = module; } @@ -54,7 +54,7 @@ namespace de4dot.code.deobfuscators.Spices_Net { initializeCtors(componentResourceManagerType, componentManagerCtors); } - static void initializeCtors(TypeDef manager, MethodDefinitionAndDeclaringTypeDict ctors) { + void initializeCtors(TypeDef manager, MethodDefinitionAndDeclaringTypeDict ctors) { if (manager == null) return; @@ -62,10 +62,8 @@ namespace de4dot.code.deobfuscators.Spices_Net { if (ctor.Name != ".ctor") continue; - var newCtor = new MethodReference(ctor.Name, ctor.MethodReturnType.ReturnType, manager.BaseType); - newCtor.HasThis = true; - foreach (var param in ctor.Parameters) - newCtor.Parameters.Add(new ParameterDefinition(param.ParameterType)); + var newCtor = new MemberRefUser(module, ctor.Name, ctor.MethodSig.Clone(), manager.BaseType); + module.UpdateRowId(newCtor); ctors.add(ctor, newCtor); } } @@ -75,9 +73,9 @@ namespace de4dot.code.deobfuscators.Spices_Net { return false; if (type.HasProperties || type.HasEvents || type.HasFields) return false; - if (type.Interfaces.Count > 0) + if (type.InterfaceImpls.Count > 0) return false; - var method = DotNetUtils.getMethod(type, "GetResourceFileName"); + var method = type.FindMethod("GetResourceFileName"); if (!DotNetUtils.isMethod(method, "System.String", "(System.Globalization.CultureInfo)")) return false; @@ -90,7 +88,7 @@ namespace de4dot.code.deobfuscators.Spices_Net { var numToResource = new Dictionary(module.Resources.Count); foreach (var resource in module.Resources) { - var name = resource.Name; + var name = resource.Name.String; int index = name.LastIndexOf('.'); string ext; if (index < 0) @@ -106,12 +104,12 @@ namespace de4dot.code.deobfuscators.Spices_Net { foreach (var type in module.GetTypes()) { rename(numToResource, "", type.FullName); rename(numToResource, "", type.FullName + ".g"); - rename(numToResource, type.Namespace, type.Name); - rename(numToResource, type.Namespace, type.Name + ".g"); + rename(numToResource, type.Namespace.String, type.Name.String); + rename(numToResource, type.Namespace.String, type.Name.String + ".g"); } if (module.Assembly != null) - rename(numToResource, "", module.Assembly.Name.Name + ".g"); + rename(numToResource, "", module.Assembly.Name.String + ".g"); } static void rename(Dictionary numToResource, string ns, string name) { @@ -121,14 +119,14 @@ namespace de4dot.code.deobfuscators.Spices_Net { if (!numToResource.TryGetValue(hash, out resource)) return; - int index = resource.Name.LastIndexOf('.'); + int index = resource.Name.String.LastIndexOf('.'); string resourceNamespace, newName; if (index < 0) { resourceNamespace = ""; newName = resourceName; } else { - resourceNamespace = resource.Name.Substring(0, index); + resourceNamespace = resource.Name.String.Substring(0, index); newName = resourceNamespace + "." + resourceName; } if (resourceNamespace != ns) @@ -137,7 +135,7 @@ namespace de4dot.code.deobfuscators.Spices_Net { Logger.v("Restoring resource name: '{0}' => '{1}'", Utils.removeNewlines(resource.Name), Utils.removeNewlines(newName)); - resource.Name = newName; + resource.Name = new UTF8String(newName); numToResource.Remove(hash); } @@ -153,13 +151,16 @@ namespace de4dot.code.deobfuscators.Spices_Net { } public void deobfuscate(Blocks blocks) { + if (resourceManagerType == null && componentResourceManagerType == null) + return; + foreach (var block in blocks.MethodBlocks.getAllBlocks()) { var instrs = block.Instructions; for (int i = 0; i < instrs.Count; i++) { var instr = instrs[i]; if (instr.OpCode.Code != Code.Newobj) continue; - var ctor = instr.Operand as MethodReference; + var ctor = instr.Operand as IMethod; if (ctor == null) continue; var newCtor = resourceManagerCtors.find(ctor); diff --git a/de4dot.code/deobfuscators/Spices_Net/SpicesMethodCallInliner.cs b/de4dot.code/deobfuscators/Spices_Net/SpicesMethodCallInliner.cs index 90b41ca6..99a378a5 100644 --- a/de4dot.code/deobfuscators/Spices_Net/SpicesMethodCallInliner.cs +++ b/de4dot.code/deobfuscators/Spices_Net/SpicesMethodCallInliner.cs @@ -20,29 +20,28 @@ using System.Collections.Generic; using dot10.DotNet; using dot10.DotNet.Emit; -using Mono.Cecil.Metadata; using de4dot.blocks; using de4dot.blocks.cflow; namespace de4dot.code.deobfuscators.Spices_Net { class SpicesMethodCallInliner : MethodCallInliner { - ModuleDefinition module; + ModuleDefMD module; TypeDefinitionDict methodsTypes = new TypeDefinitionDict(); MethodDefinitionAndDeclaringTypeDict classMethods = new MethodDefinitionAndDeclaringTypeDict(); - public SpicesMethodCallInliner(ModuleDefinition module) + public SpicesMethodCallInliner(ModuleDefMD module) : base(false) { this.module = module; } - protected override bool isCompatibleType(int paramIndex, TypeReference origType, TypeReference newType) { - if (MemberReferenceHelper.compareTypes(origType, newType)) + protected override bool isCompatibleType(int paramIndex, IType origType, IType newType) { + if (new SigComparer().Equals(origType, newType)) return true; if (paramIndex == -1) { - if (newType.IsValueType || origType.IsValueType) + if (isValueType(newType) || isValueType(origType)) return false; } - return newType.EType == ElementType.Object; + return newType.FullName == "System.Object"; } public bool checkCanInline(MethodDef method) { @@ -61,7 +60,7 @@ namespace de4dot.code.deobfuscators.Spices_Net { void restoreMethodBodies() { var methodToOrigMethods = new MethodDefinitionAndDeclaringTypeDict>(); foreach (var t in module.Types) { - var types = new List(TypeDef.GetTypes(new List { t })); + var types = new List(AllTypesHelper.Types(new List { t })); foreach (var type in types) { if (methodsTypes.find(type)) continue; @@ -103,7 +102,7 @@ namespace de4dot.code.deobfuscators.Spices_Net { calledMethod = null; if (method.Body == null) return false; - if (method.Body.Variables.Count > 0) + if (method.Body.LocalList.Count > 0) return false; if (method.Body.ExceptionHandlers.Count > 0) return false; @@ -114,7 +113,7 @@ namespace de4dot.code.deobfuscators.Spices_Net { return false; if (!calledMethod.IsStatic) return false; - if (calledMethod.GenericParameters.Count > 0) + if (calledMethod.GenericParams.Count > 0) return false; if (calledMethod.Body == null || calledMethod.Body.Instructions.Count == 0) return false; @@ -128,7 +127,7 @@ namespace de4dot.code.deobfuscators.Spices_Net { var instrs = instanceMethod.Body.Instructions; int index; for (index = 0; index < instrs.Count; index++) { - if (DotNetUtils.getArgIndex(instrs[index]) != index) + if (instrs[index].GetParameterIndex() != index) break; } var call = instrs[index++]; @@ -155,17 +154,17 @@ namespace de4dot.code.deobfuscators.Spices_Net { static bool checkMethodsType(TypeDef type) { if (!type.IsNested) return false; - if ((type.Attributes & ~TypeAttributes.BeforeFieldInit) != TypeAttributes.NestedAssembly) + if ((type.Flags & ~TypeAttributes.BeforeFieldInit) != TypeAttributes.NestedAssembly) return false; if (type.HasProperties || type.HasEvents || type.HasFields || type.HasNestedTypes) return false; - if (type.GenericParameters.Count > 0) + if (type.GenericParams.Count > 0) return false; if (type.IsValueType || type.IsInterface) return false; - if (type.BaseType == null || type.BaseType.EType != ElementType.Object) + if (type.BaseType == null || type.BaseType.FullName != "System.Object") return false; - if (type.Interfaces.Count > 0) + if (type.InterfaceImpls.Count > 0) return false; if (!checkMethods(type)) return false; @@ -181,16 +180,16 @@ namespace de4dot.code.deobfuscators.Spices_Net { if (method.Name == ".cctor") return false; if (method.Name == ".ctor") { - if (method.Parameters.Count != 0) + if (method.MethodSig.GetParamCount() != 0) return false; foundCtor = true; continue; } - if (method.Attributes != (MethodAttributes.Assembly | MethodAttributes.Static | MethodAttributes.HideBySig)) + if (method.Flags != (MethodAttributes.Assembly | MethodAttributes.Static | MethodAttributes.HideBySig)) return false; - if (method.HasPInvokeInfo || method.PInvokeInfo != null) + if (method.ImplMap != null) return false; - if (method.GenericParameters.Count > 0) + if (method.GenericParams.Count > 0) return false; numMethods++; @@ -236,7 +235,7 @@ namespace de4dot.code.deobfuscators.Spices_Net { var call = instrs[i]; if (call.OpCode.Code != Code.Call) continue; - var realInstanceMethod = classMethods.find(call.Operand as MethodReference); + var realInstanceMethod = classMethods.find(call.Operand as IMethod); if (realInstanceMethod == null) continue; call.Operand = realInstanceMethod; diff --git a/de4dot.code/deobfuscators/Spices_Net/StringDecrypter.cs b/de4dot.code/deobfuscators/Spices_Net/StringDecrypter.cs index 8d3711fc..af331300 100644 --- a/de4dot.code/deobfuscators/Spices_Net/StringDecrypter.cs +++ b/de4dot.code/deobfuscators/Spices_Net/StringDecrypter.cs @@ -22,12 +22,11 @@ using System.Collections.Generic; using System.Text; using dot10.DotNet; using dot10.DotNet.Emit; -using Mono.Cecil.Metadata; using de4dot.blocks; namespace de4dot.code.deobfuscators.Spices_Net { class StringDecrypter { - ModuleDefinition module; + ModuleDefMD module; TypeDef decrypterType; FieldDef encryptedDataField; StringDataFlags stringDataFlags; @@ -60,12 +59,12 @@ namespace de4dot.code.deobfuscators.Spices_Net { get { if (encryptedDataField == null) return null; - var type = encryptedDataField.FieldType as TypeDef; + var type = encryptedDataField.FieldSig.GetFieldType().TryGetTypeDef(); if (type == null || type.Fields.Count != 1 || type.Fields[0] != encryptedDataField) return null; if (type.HasMethods || type.HasEvents || type.HasProperties || type.HasNestedTypes) return null; - if (type.Interfaces.Count > 0) + if (type.InterfaceImpls.Count > 0) return null; return type; @@ -84,7 +83,7 @@ namespace de4dot.code.deobfuscators.Spices_Net { get { return methodToInfo.getValues(); } } - public StringDecrypter(ModuleDefinition module) { + public StringDecrypter(ModuleDefMD module) { this.module = module; } @@ -96,13 +95,13 @@ namespace de4dot.code.deobfuscators.Spices_Net { continue; if (type.Fields.Count != 2) continue; - if ((type.Attributes & ~TypeAttributes.Sealed) != 0) + if ((type.Flags & ~TypeAttributes.Sealed) != 0) continue; if (type.BaseType == null || type.BaseType.FullName != "System.Object") continue; if (hasInstanceMethods(type)) continue; - var cctor = DotNetUtils.getMethod(type, ".cctor"); + var cctor = type.FindClassConstructor(); if (cctor == null) continue; @@ -125,7 +124,7 @@ namespace de4dot.code.deobfuscators.Spices_Net { foreach (var method in type.Methods) { if (!method.IsStatic) return true; - if (method.PInvokeInfo != null) + if (method.ImplMap != null) return true; } return false; @@ -136,7 +135,7 @@ namespace de4dot.code.deobfuscators.Spices_Net { var instructions = cctor.Body.Instructions; for (int i = 0; i < instructions.Count; i++) { var ldci4 = instructions[i]; - if (!DotNetUtils.isLdcI4(ldci4)) + if (!ldci4.IsLdcI4()) continue; var instrs = DotNetUtils.getInstructions(instructions, i + 1, OpCodes.Newarr, OpCodes.Dup, OpCodes.Ldtoken, OpCodes.Call); @@ -166,11 +165,12 @@ namespace de4dot.code.deobfuscators.Spices_Net { StringDataFlags getStringDataFlags(MethodDef method) { if (method == null || method.Body == null) return 0; - if (method.Parameters.Count != 1) + var sig = method.MethodSig; + if (sig == null || sig.Params.Count != 1) return 0; - if (!checkClass(method.Parameters[0].ParameterType, "System.Byte[]")) + if (!checkClass(sig.Params[0], "System.Byte[]")) return 0; - if (!checkClass(method.MethodReturnType.ReturnType, "System.Byte[]")) + if (!checkClass(sig.RetType, "System.Byte[]")) return 0; StringDataFlags flags = 0; @@ -194,9 +194,10 @@ namespace de4dot.code.deobfuscators.Spices_Net { var calledMethod = instr.Operand as MethodDef; if (calledMethod == null) continue; - if (calledMethod.MethodReturnType.ReturnType.EType == ElementType.Void) + var sig = calledMethod.MethodSig; + if (sig == null || sig.RetType.GetElementType() == ElementType.Void) continue; - if (calledMethod.Parameters.Count != 0) + if (sig.Params.Count != 0) continue; if (!get3DesKeyIv(calledMethod, ref key, ref iv)) continue; @@ -211,13 +212,15 @@ namespace de4dot.code.deobfuscators.Spices_Net { return false; var instrs = method.Body.Instructions; - var arrays = ArrayFinder.getArrays(method, module.TypeSystem.Byte); + var arrays = ArrayFinder.getArrays(method, module.CorLibTypes.Byte); if (arrays.Count != 1 && arrays.Count != 2) return false; key = arrays[0]; - if (arrays.Count == 1) - iv = module.Assembly.Name.PublicKeyToken; + if (arrays.Count == 1) { + var pkt = PublicKeyBase.ToPublicKeyToken(module.Assembly.PublicKey); + iv = pkt == null ? null : pkt.Data; + } else iv = arrays[1]; return true; @@ -230,18 +233,21 @@ namespace de4dot.code.deobfuscators.Spices_Net { var called = instr.Operand as MethodDef; if (called == null) continue; - if (called.MethodReturnType.ReturnType.EType != ElementType.I4) + var sig = called.MethodSig; + if (sig == null) continue; - var parameters = called.Parameters; + if (sig.RetType.GetElementType() != ElementType.I4) + continue; + var parameters = sig.Params; if (parameters.Count != 4) continue; - if (!checkClass(parameters[0].ParameterType, "System.Byte[]")) + if (!checkClass(parameters[0], "System.Byte[]")) continue; - if (parameters[1].ParameterType.EType != ElementType.I4) + if (parameters[1].GetElementType() != ElementType.I4) continue; - if (!checkClass(parameters[2].ParameterType, "System.Byte[]")) + if (!checkClass(parameters[2], "System.Byte[]")) continue; - if (parameters[3].ParameterType.EType != ElementType.I4) + if (parameters[3].GetElementType() != ElementType.I4) continue; return true; @@ -257,21 +263,24 @@ namespace de4dot.code.deobfuscators.Spices_Net { return false; } - static bool checkClass(TypeReference type, string fullName) { - return type != null && (type.EType == ElementType.Object || type.FullName == fullName); + static bool checkClass(TypeSig type, string fullName) { + return type != null && (type.ElementType == ElementType.Object || type.FullName == fullName); } - static bool isStringType(TypeReference type) { - return type != null && (type.EType == ElementType.Object || type.EType == ElementType.String); + static bool isStringType(TypeSig type) { + return type != null && (type.ElementType == ElementType.Object || type.ElementType == ElementType.String); } bool initializeDecrypterInfos(TypeDef type) { foreach (var method in type.Methods) { if (!method.IsStatic || method.Body == null) continue; - if (method.Parameters.Count != 0) + var sig = method.MethodSig; + if (sig == null) continue; - if (!isStringType(method.MethodReturnType.ReturnType)) + if (sig.Params.Count != 0) + continue; + if (!isStringType(sig.RetType)) continue; var info = createInfo(method); @@ -289,11 +298,11 @@ namespace de4dot.code.deobfuscators.Spices_Net { for (int i = 0; i < instrs.Count - 1; i++) { var ldci4_1 = instrs[i]; var ldci4_2 = instrs[i + 1]; - if (!DotNetUtils.isLdcI4(ldci4_1) || !DotNetUtils.isLdcI4(ldci4_2)) + if (!ldci4_1.IsLdcI4() || !ldci4_2.IsLdcI4()) continue; - int offset = DotNetUtils.getLdcI4Value(ldci4_1); - int length = DotNetUtils.getLdcI4Value(ldci4_2); + int offset = ldci4_1.GetLdcI4Value(); + int length = ldci4_2.GetLdcI4Value(); return new DecrypterInfo(method, offset, length); } @@ -313,7 +322,7 @@ namespace de4dot.code.deobfuscators.Spices_Net { } if ((stringDataFlags & StringDataFlags.Encrypted2) != 0) { - var k = module.Assembly.Name.PublicKey; + var k = module.Assembly.PublicKey.Data; int mask = (byte)(~k.Length); for (int i = 0; i < decryptedData.Length; i++) decryptedData[i] ^= k[i & mask]; @@ -331,7 +340,7 @@ namespace de4dot.code.deobfuscators.Spices_Net { return; encryptedDataField.InitialValue = new byte[1]; - encryptedDataField.FieldType = module.TypeSystem.Byte; + encryptedDataField.FieldSig.Type = module.CorLibTypes.Byte; } public string decrypt(MethodDef method) { diff --git a/de4dot.cui/Program.cs b/de4dot.cui/Program.cs index 029d435c..afbf3ea0 100644 --- a/de4dot.cui/Program.cs +++ b/de4dot.cui/Program.cs @@ -59,8 +59,8 @@ namespace de4dot.cui { new de4dot.code.deobfuscators.Skater_NET.DeobfuscatorInfo(), #if PORT new de4dot.code.deobfuscators.SmartAssembly.DeobfuscatorInfo(), - new de4dot.code.deobfuscators.Spices_Net.DeobfuscatorInfo(), #endif + new de4dot.code.deobfuscators.Spices_Net.DeobfuscatorInfo(), new de4dot.code.deobfuscators.Xenocode.DeobfuscatorInfo(), }; }