From 5d25a499aa3ddc02f699890ad2c2793bf3e6ae77 Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 8 Nov 2012 22:24:13 +0100 Subject: [PATCH] Port CryptoObfuscator deobfuscator --- blocks/DotNetUtils.cs | 20 ++--- de4dot.code/de4dot.code.csproj | 24 +++--- .../CryptoObfuscator/AntiDebugger.cs | 4 +- .../CryptoObfuscator/AssemblyResolver.cs | 12 +-- .../deobfuscators/CryptoObfuscator/CoUtils.cs | 4 +- .../CryptoObfuscator/ConstantsDecrypter.cs | 9 +- .../CryptoObfuscator/Deobfuscator.cs | 8 +- .../CryptoObfuscator/MethodBodyReader.cs | 82 ++++++++++--------- .../CryptoObfuscator/MethodsDecrypter.cs | 42 +++++----- .../CryptoObfuscator/ProxyCallFixer.cs | 24 +++--- .../CryptoObfuscator/ResourceDecrypter.cs | 38 ++++----- .../CryptoObfuscator/ResourceResolver.cs | 23 +++--- .../CryptoObfuscator/StringDecrypter.cs | 8 +- .../CryptoObfuscator/TamperDetection.cs | 4 +- de4dot.cui/Program.cs | 2 +- dot10 | 2 +- 16 files changed, 154 insertions(+), 152 deletions(-) diff --git a/blocks/DotNetUtils.cs b/blocks/DotNetUtils.cs index f72b4a80..f447f029 100644 --- a/blocks/DotNetUtils.cs +++ b/blocks/DotNetUtils.cs @@ -181,17 +181,15 @@ namespace de4dot.blocks { return true; } -#if PORT - public static FieldDefinition findFieldType(TypeDefinition typeDefinition, string typeName, bool isStatic) { + public static FieldDef findFieldType(TypeDef typeDefinition, string typeName, bool isStatic) { if (typeDefinition == null) return null; foreach (var field in typeDefinition.Fields) { - if (field.FieldType.FullName == typeName && field.IsStatic == isStatic) + if (field.IsStatic == isStatic && field.FieldSig.GetFieldType().GetFullName() == typeName) return field; } return null; } -#endif public static IEnumerable findMethods(IEnumerable methods, string returnType, string[] argsTypes) { return findMethods(methods, returnType, argsTypes, true); @@ -1233,14 +1231,13 @@ namespace de4dot.blocks { return new ClassSig(typeRef); } -#if PORT - public static FrameworkType getFrameworkType(ModuleDefinition module) { - foreach (var modRef in module.AssemblyReferences) { + public static FrameworkType getFrameworkType(ModuleDefMD module) { + foreach (var modRef in module.GetAssemblyRefs()) { if (modRef.Name != "mscorlib") continue; - if (modRef.PublicKeyToken == null || modRef.PublicKeyToken.Length == 0) + if (PublicKeyBase.IsNullOrEmpty2(modRef.PublicKeyOrToken)) continue; - switch (BitConverter.ToString(modRef.PublicKeyToken).Replace("-", "").ToLowerInvariant()) { + switch (BitConverter.ToString(modRef.PublicKeyOrToken.Data).Replace("-", "").ToLowerInvariant()) { case "b77a5c561934e089": return FrameworkType.Desktop; case "7cec85d7bea7798e": @@ -1256,7 +1253,6 @@ namespace de4dot.blocks { return FrameworkType.Unknown; } -#endif public static int getMethodCalls(MethodDef method, string methodFullName) { if (method == null || method.Body == null) @@ -1293,7 +1289,6 @@ namespace de4dot.blocks { return false; } -#if PORT public static bool callsMethod(MethodDef method, string returnType, string parameters) { if (method == null || method.Body == null) return false; @@ -1301,13 +1296,14 @@ namespace de4dot.blocks { foreach (var instr in method.Body.Instructions) { if (instr.OpCode.Code != Code.Call && instr.OpCode.Code != Code.Callvirt && instr.OpCode.Code != Code.Newobj) continue; - if (isMethod(instr.Operand as MethodReference, returnType, parameters)) + if (isMethod(instr.Operand as IMethod, returnType, parameters)) return true; } return false; } +#if PORT public static IList getArgPushes(IList instrs, int index) { return getArgPushes(instrs, ref index); } diff --git a/de4dot.code/de4dot.code.csproj b/de4dot.code/de4dot.code.csproj index 545079ac..c93591eb 100644 --- a/de4dot.code/de4dot.code.csproj +++ b/de4dot.code/de4dot.code.csproj @@ -123,18 +123,18 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/de4dot.code/deobfuscators/CryptoObfuscator/AntiDebugger.cs b/de4dot.code/deobfuscators/CryptoObfuscator/AntiDebugger.cs index 79838171..389c103e 100644 --- a/de4dot.code/deobfuscators/CryptoObfuscator/AntiDebugger.cs +++ b/de4dot.code/deobfuscators/CryptoObfuscator/AntiDebugger.cs @@ -22,7 +22,7 @@ using de4dot.blocks; namespace de4dot.code.deobfuscators.CryptoObfuscator { class AntiDebugger { - ModuleDefinition module; + ModuleDefMD module; ISimpleDeobfuscator simpleDeobfuscator; IDeobfuscator deob; TypeDef antiDebuggerType; @@ -36,7 +36,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { get { return antiDebuggerMethod; } } - public AntiDebugger(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) { + public AntiDebugger(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) { this.module = module; this.simpleDeobfuscator = simpleDeobfuscator; this.deob = deob; diff --git a/de4dot.code/deobfuscators/CryptoObfuscator/AssemblyResolver.cs b/de4dot.code/deobfuscators/CryptoObfuscator/AssemblyResolver.cs index 0d7e5ab8..c2dd5bcb 100644 --- a/de4dot.code/deobfuscators/CryptoObfuscator/AssemblyResolver.cs +++ b/de4dot.code/deobfuscators/CryptoObfuscator/AssemblyResolver.cs @@ -26,7 +26,7 @@ using de4dot.blocks; namespace de4dot.code.deobfuscators.CryptoObfuscator { class AssemblyResolver { - ModuleDefinition module; + ModuleDefMD module; TypeDef resolverType; MethodDef resolverMethod; List assemblyInfos = new List(); @@ -62,7 +62,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { get { return resolverMethod; } } - public AssemblyResolver(ModuleDefinition module) { + public AssemblyResolver(ModuleDefMD module) { this.module = module; } @@ -112,15 +112,15 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { if (instrs == null) continue; - MethodReference methodRef; + IMethod methodRef; var ldftn = instrs[1]; var newobj = instrs[2]; - methodRef = ldftn.Operand as MethodReference; - if (methodRef == null || !MemberReferenceHelper.compareTypes(initMethod.DeclaringType, methodRef.DeclaringType)) + methodRef = ldftn.Operand as IMethod; + if (methodRef == null || !new SigComparer().Equals(initMethod.DeclaringType, methodRef.DeclaringType)) continue; - methodRef = newobj.Operand as MethodReference; + methodRef = newobj.Operand as IMethod; if (methodRef == null || methodRef.FullName != "System.Void System.ResolveEventHandler::.ctor(System.Object,System.IntPtr)") continue; diff --git a/de4dot.code/deobfuscators/CryptoObfuscator/CoUtils.cs b/de4dot.code/deobfuscators/CryptoObfuscator/CoUtils.cs index 8e566561..393ba849 100644 --- a/de4dot.code/deobfuscators/CryptoObfuscator/CoUtils.cs +++ b/de4dot.code/deobfuscators/CryptoObfuscator/CoUtils.cs @@ -25,13 +25,13 @@ using de4dot.blocks; namespace de4dot.code.deobfuscators.CryptoObfuscator { static class CoUtils { - public static EmbeddedResource getResource(ModuleDefinition module, MethodDef method) { + public static EmbeddedResource getResource(ModuleDefMD module, MethodDef method) { if (method == null || method.Body == null) return null; return getResource(module, DotNetUtils.getCodeStrings(method)); } - public static EmbeddedResource getResource(ModuleDefinition module, IEnumerable names) { + public static EmbeddedResource getResource(ModuleDefMD module, IEnumerable names) { foreach (var name in names) { var resource = DotNetUtils.getResource(module, name) as EmbeddedResource; if (resource != null) diff --git a/de4dot.code/deobfuscators/CryptoObfuscator/ConstantsDecrypter.cs b/de4dot.code/deobfuscators/CryptoObfuscator/ConstantsDecrypter.cs index 91ac2f6d..e11a2abc 100644 --- a/de4dot.code/deobfuscators/CryptoObfuscator/ConstantsDecrypter.cs +++ b/de4dot.code/deobfuscators/CryptoObfuscator/ConstantsDecrypter.cs @@ -20,12 +20,13 @@ using System; using System.Collections.Generic; using System.Text; +using dot10.IO; using dot10.DotNet; using de4dot.blocks; namespace de4dot.code.deobfuscators.CryptoObfuscator { class ConstantsDecrypter { - ModuleDefinition module; + ModuleDefMD module; TypeDef decrypterType; MethodDef methodI4; MethodDef methodI8; @@ -62,7 +63,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { get { return decrypterType != null; } } - public ConstantsDecrypter(ModuleDefinition module) { + public ConstantsDecrypter(ModuleDefMD module) { this.module = module; } @@ -106,8 +107,8 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { if (decrypterType == null) return; - encryptedResource = CoUtils.getResource(module, DotNetUtils.getCodeStrings(DotNetUtils.getMethod(decrypterType, ".cctor"))); - constantsData = resourceDecrypter.decrypt(encryptedResource.GetResourceStream()); + encryptedResource = CoUtils.getResource(module, DotNetUtils.getCodeStrings(decrypterType.FindClassConstructor())); + constantsData = resourceDecrypter.decrypt(encryptedResource.Data.CreateStream()); } public int decryptInt32(int index) { diff --git a/de4dot.code/deobfuscators/CryptoObfuscator/Deobfuscator.cs b/de4dot.code/deobfuscators/CryptoObfuscator/Deobfuscator.cs index 07a2e682..94dd2999 100644 --- a/de4dot.code/deobfuscators/CryptoObfuscator/Deobfuscator.cs +++ b/de4dot.code/deobfuscators/CryptoObfuscator/Deobfuscator.cs @@ -105,7 +105,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { StringFeatures = StringFeatures.AllowStaticDecryption | StringFeatures.AllowDynamicDecryption; } - public override void init(ModuleDefinition module) { + public override void init(ModuleDefMD module) { base.init(module); } @@ -146,7 +146,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { tamperDetection.find(); constantsDecrypter = new ConstantsDecrypter(module); constantsDecrypter.find(); - foundObfuscatorUserString = Utils.StartsWith(module.GetUserString(0x70000001), "\u0011\"3D9B94A98B-76A8-4810-B1A0-4BE7C4F9C98D", StringComparison.Ordinal); + foundObfuscatorUserString = Utils.StartsWith(module.ReadUserString(0x70000001), "\u0011\"3D9B94A98B-76A8-4810-B1A0-4BE7C4F9C98D", StringComparison.Ordinal); } void initializeVersion(TypeDef attr) { @@ -166,9 +166,9 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { foreach (var type in module.Types) { if (type.Namespace != "A") continue; - if (Regex.IsMatch(type.Name, "^c[0-9a-f]{32}$")) + if (Regex.IsMatch(type.Name.String, "^c[0-9a-f]{32}$")) return true; - else if (Regex.IsMatch(type.Name, "^A[A-Z]*$")) { + else if (Regex.IsMatch(type.Name.String, "^A[A-Z]*$")) { if (++matched >= 10) return true; } diff --git a/de4dot.code/deobfuscators/CryptoObfuscator/MethodBodyReader.cs b/de4dot.code/deobfuscators/CryptoObfuscator/MethodBodyReader.cs index 2230e5a8..d3c27d7d 100644 --- a/de4dot.code/deobfuscators/CryptoObfuscator/MethodBodyReader.cs +++ b/de4dot.code/deobfuscators/CryptoObfuscator/MethodBodyReader.cs @@ -19,27 +19,28 @@ using System; using System.Collections.Generic; -using System.IO; +using dot10.IO; using dot10.DotNet; +using dot10.DotNet.MD; using dot10.DotNet.Emit; using de4dot.blocks; namespace de4dot.code.deobfuscators.CryptoObfuscator { class MethodBodyReader : MethodBodyReaderBase { - ModuleDefinition module; + ModuleDefMD module; ushort maxStackSize; - public MethodBodyReader(ModuleDefinition module, BinaryReader reader) + public MethodBodyReader(ModuleDefMD module, IBinaryReader reader) : base(reader) { this.module = module; } public void read(MethodDef method) { - this.parameters = getParameters(method); - this.Locals = getLocals(method); + this.parameters = method.Parameters; + this.locals = getLocals(method); maxStackSize = (ushort)reader.ReadInt32(); - readInstructionsNumBytes(reader.ReadUInt32()); + ReadInstructionsNumBytes(reader.ReadUInt32()); readExceptionHandlers(); } @@ -51,73 +52,76 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { readExceptionHandlers((totalSize - 4) / 24); } - static IList getParameters(MethodReference method) { - return DotNetUtils.getParameters(method); - } - - static IList getLocals(MethodDef method) { + static IList getLocals(MethodDef method) { if (method.Body == null) - return new List(); - return new List(method.Body.Variables); + return new List(); + return method.Body.LocalList; } - protected override FieldReference readInlineField(Instruction instr) { - return (FieldReference)module.LookupToken(reader.ReadInt32()); + protected override IField ReadInlineField(Instruction instr) { + return module.ResolveToken(reader.ReadUInt32()) as IField; } - protected override MethodReference readInlineMethod(Instruction instr) { - return (MethodReference)module.LookupToken(reader.ReadInt32()); + protected override IMethod ReadInlineMethod(Instruction instr) { + return module.ResolveToken(reader.ReadUInt32()) as IMethod; } - protected override CallSite readInlineSig(Instruction instr) { - return module.ReadCallSite(new MetadataToken(reader.ReadUInt32())); + protected override MethodSig ReadInlineSig(Instruction instr) { + var sas = module.ResolveStandAloneSig(MDToken.ToRID(reader.ReadUInt32())); + return sas == null ? null : sas.MethodSig; } - protected override string readInlineString(Instruction instr) { - return module.GetUserString(reader.ReadUInt32()); + protected override string ReadInlineString(Instruction instr) { + return module.ReadUserString(reader.ReadUInt32()); } - protected override MemberReference readInlineTok(Instruction instr) { - return (MemberReference)module.LookupToken(reader.ReadInt32()); + protected override ITokenOperand ReadInlineTok(Instruction instr) { + return module.ResolveToken(reader.ReadUInt32()) as ITokenOperand; } - protected override TypeReference readInlineType(Instruction instr) { - return (TypeReference)module.LookupToken(reader.ReadInt32()); + protected override ITypeDefOrRef ReadInlineType(Instruction instr) { + return module.ResolveToken(reader.ReadUInt32()) as ITypeDefOrRef; } - protected override ExceptionHandler readExceptionHandler() { - var eh = new ExceptionHandler((ExceptionHandlerType)reader.ReadInt32()); + void readExceptionHandlers(int numExceptionHandlers) { + exceptionHandlers = new ExceptionHandler[numExceptionHandlers]; + for (int i = 0; i < exceptionHandlers.Count; i++) + exceptionHandlers[i] = readExceptionHandler(); + } - int tryOffset = reader.ReadInt32(); - eh.TryStart = getInstruction(tryOffset); - eh.TryEnd = getInstructionOrNull(tryOffset + reader.ReadInt32()); + ExceptionHandler readExceptionHandler() { + var eh = new ExceptionHandler((ExceptionHandlerType)reader.ReadUInt32()); - int handlerOffset = reader.ReadInt32(); - eh.HandlerStart = getInstruction(handlerOffset); - eh.HandlerEnd = getInstructionOrNull(handlerOffset + reader.ReadInt32()); + uint tryOffset = reader.ReadUInt32(); + eh.TryStart = GetInstructionThrow(tryOffset); + eh.TryEnd = GetInstruction(tryOffset + reader.ReadUInt32()); + + uint handlerOffset = reader.ReadUInt32(); + eh.HandlerStart = GetInstructionThrow(handlerOffset); + eh.HandlerEnd = GetInstruction(handlerOffset + reader.ReadUInt32()); switch (eh.HandlerType) { case ExceptionHandlerType.Catch: - eh.CatchType = (TypeReference)module.LookupToken(reader.ReadInt32()); + eh.CatchType = module.ResolveToken(reader.ReadUInt32()) as ITypeDefOrRef; break; case ExceptionHandlerType.Filter: - eh.FilterStart = getInstruction(reader.ReadInt32()); + eh.FilterStart = GetInstructionThrow(reader.ReadUInt32()); break; case ExceptionHandlerType.Finally: case ExceptionHandlerType.Fault: default: - reader.ReadInt32(); + reader.ReadUInt32(); break; } return eh; } - public override void restoreMethod(MethodDef method) { - base.restoreMethod(method); - method.Body.MaxStackSize = maxStackSize; + public new void RestoreMethod(MethodDef method) { + base.RestoreMethod(method); + method.Body.MaxStack = maxStackSize; } } } diff --git a/de4dot.code/deobfuscators/CryptoObfuscator/MethodsDecrypter.cs b/de4dot.code/deobfuscators/CryptoObfuscator/MethodsDecrypter.cs index 2de8c43b..545745a5 100644 --- a/de4dot.code/deobfuscators/CryptoObfuscator/MethodsDecrypter.cs +++ b/de4dot.code/deobfuscators/CryptoObfuscator/MethodsDecrypter.cs @@ -19,14 +19,14 @@ using System; using System.Collections.Generic; -using System.IO; +using dot10.IO; using dot10.DotNet; using dot10.DotNet.Emit; using de4dot.blocks; namespace de4dot.code.deobfuscators.CryptoObfuscator { class MethodsDecrypter { - ModuleDefinition module; + ModuleDefMD module; TypeDef decrypterType; MethodDef decryptMethod; MethodDef decrypterCctor; @@ -49,7 +49,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { get { return decrypterType != null; } } - public MethodsDecrypter(ModuleDefinition module) { + public MethodsDecrypter(ModuleDefMD module) { this.module = module; } @@ -73,7 +73,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { if (!new FieldTypes(type).all(requiredFields)) return false; - var cctor = DotNetUtils.getMethod(type, ".cctor"); + var cctor = type.FindClassConstructor(); if (cctor == null) return false; var decryptMethodTmp = findDecryptMethod(type); @@ -120,23 +120,23 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { if (resource == null) return; var decrypted = resourceDecrypter.decrypt(resource.GetResourceStream()); - var reader = new BinaryReader(new MemoryStream(decrypted)); + var reader = MemoryImageStream.Create(decrypted); int numEncrypted = reader.ReadInt32(); Log.v("Restoring {0} encrypted methods", numEncrypted); Log.indent(); for (int i = 0; i < numEncrypted; i++) { int delegateTypeToken = reader.ReadInt32(); uint codeOffset = reader.ReadUInt32(); - var origOffset = reader.BaseStream.Position; - reader.BaseStream.Position = codeOffset; + var origOffset = reader.Position; + reader.Position = codeOffset; decrypt(reader, delegateTypeToken); - reader.BaseStream.Position = origOffset; + reader.Position = origOffset; } Log.deIndent(); } - void decrypt(BinaryReader reader, int delegateTypeToken) { - var delegateType = module.LookupToken(delegateTypeToken) as TypeDef; + void decrypt(IBinaryReader reader, int delegateTypeToken) { + var delegateType = module.ResolveToken(delegateTypeToken) as TypeDef; if (delegateType == null) throw new ApplicationException("Couldn't find delegate type"); @@ -145,21 +145,21 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { throw new ApplicationException("Could not find encrypted method tokens"); if (delToken != delegateTypeToken) throw new ApplicationException("Invalid delegate type token"); - var encType = module.LookupToken(encDeclToken) as TypeReference; + var encType = module.ResolveToken(encDeclToken) as ITypeDefOrRef; if (encType == null) throw new ApplicationException("Invalid declaring type token"); - var encMethod = module.LookupToken(encMethToken) as MethodDef; + var encMethod = module.ResolveToken(encMethToken) as MethodDef; if (encMethod == null) throw new ApplicationException("Invalid encrypted method token"); var bodyReader = new MethodBodyReader(module, reader); bodyReader.read(encMethod); - bodyReader.restoreMethod(encMethod); + bodyReader.RestoreMethod(encMethod); Log.v("Restored method {0} ({1:X8}). Instrs:{2}, Locals:{3}, Exceptions:{4}", Utils.removeNewlines(encMethod.FullName), encMethod.MDToken.ToInt32(), encMethod.Body.Instructions.Count, - encMethod.Body.Variables.Count, + encMethod.Body.LocalList.Count, encMethod.Body.ExceptionHandlers.Count); delegateTypes.Add(delegateType); } @@ -169,20 +169,20 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { encMethodToken = 0; encDeclaringTypeToken = 0; - var cctor = DotNetUtils.getMethod(delegateType, ".cctor"); + var cctor = delegateType.FindClassConstructor(); if (cctor == null) return false; var instrs = cctor.Body.Instructions; for (int i = 0; i < instrs.Count - 3; i++) { var ldci4_1 = instrs[i]; - if (!DotNetUtils.isLdcI4(ldci4_1)) + if (!ldci4_1.IsLdcI4()) continue; var ldci4_2 = instrs[i + 1]; - if (!DotNetUtils.isLdcI4(ldci4_2)) + if (!ldci4_2.IsLdcI4()) continue; var ldci4_3 = instrs[i + 2]; - if (!DotNetUtils.isLdcI4(ldci4_3)) + if (!ldci4_3.IsLdcI4()) continue; var call = instrs[i + 3]; if (call.OpCode.Code != Code.Call) @@ -193,9 +193,9 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { if (calledMethod != decryptMethod) continue; - delegateToken = DotNetUtils.getLdcI4Value(ldci4_1); - encMethodToken = DotNetUtils.getLdcI4Value(ldci4_2); - encDeclaringTypeToken = DotNetUtils.getLdcI4Value(ldci4_3); + delegateToken = ldci4_1.GetLdcI4Value(); + encMethodToken = ldci4_2.GetLdcI4Value(); + encDeclaringTypeToken = ldci4_3.GetLdcI4Value(); return true; } diff --git a/de4dot.code/deobfuscators/CryptoObfuscator/ProxyCallFixer.cs b/de4dot.code/deobfuscators/CryptoObfuscator/ProxyCallFixer.cs index 66eefde6..97449d66 100644 --- a/de4dot.code/deobfuscators/CryptoObfuscator/ProxyCallFixer.cs +++ b/de4dot.code/deobfuscators/CryptoObfuscator/ProxyCallFixer.cs @@ -27,7 +27,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { class ProxyCallFixer : ProxyCallFixer2 { Dictionary methodToType = new Dictionary(); - public ProxyCallFixer(ModuleDefinition module) + public ProxyCallFixer(ModuleDefMD module) : base(module) { } @@ -39,11 +39,11 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { } class Context { - public int typeToken; - public int methodToken; - public int declaringTypeToken; + public uint typeToken; + public uint methodToken; + public uint declaringTypeToken; public ProxyCreatorType proxyCreatorType; - public Context(int typeToken, int methodToken, int declaringTypeToken, ProxyCreatorType proxyCreatorType) { + public Context(uint typeToken, uint methodToken, uint declaringTypeToken, ProxyCreatorType proxyCreatorType) { this.typeToken = typeToken; this.methodToken = methodToken; this.declaringTypeToken = declaringTypeToken; @@ -58,9 +58,9 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { if (instrs == null) continue; - int typeToken = (int)instrs[0].Operand; - int methodToken = (int)instrs[1].Operand; - int declaringTypeToken = (int)instrs[2].Operand; + uint typeToken = (uint)(int)instrs[0].Operand; + uint methodToken = (uint)(int)instrs[1].Operand; + uint declaringTypeToken = (uint)(int)instrs[2].Operand; var createMethod = instrs[3].Operand as MethodDef; ProxyCreatorType proxyCreatorType; @@ -73,12 +73,12 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { return null; } - protected override void getCallInfo(object context, FieldDef field, out MethodReference calledMethod, out OpCode callOpcode) { + protected override void getCallInfo(object context, FieldDef field, out IMethod calledMethod, out OpCode callOpcode) { var ctx = (Context)context; switch (ctx.proxyCreatorType) { case ProxyCreatorType.CallOrCallvirt: - callOpcode = field.IsFamilyOrAssembly ? OpCodes.Callvirt : OpCodes.Call; + callOpcode = field.IsFamORAssem ? OpCodes.Callvirt : OpCodes.Call; break; case ProxyCreatorType.CallCtor: callOpcode = OpCodes.Call; @@ -90,7 +90,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { throw new ApplicationException(string.Format("Invalid proxy creator type: {0}", ctx.proxyCreatorType)); } - calledMethod = module.LookupToken(ctx.methodToken) as MethodReference; + calledMethod = module.ResolveToken(ctx.methodToken) as IMethod; } public void findDelegateCreator() { @@ -136,7 +136,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { foreach (var instr in createMethod.Body.Instructions) { if (instr.OpCode.Code != Code.Ldsfld) continue; - var field = instr.Operand as FieldReference; + var field = instr.Operand as IField; if (field == null) continue; switch (field.FullName) { diff --git a/de4dot.code/deobfuscators/CryptoObfuscator/ResourceDecrypter.cs b/de4dot.code/deobfuscators/CryptoObfuscator/ResourceDecrypter.cs index d2a08c4a..48b5f4f5 100644 --- a/de4dot.code/deobfuscators/CryptoObfuscator/ResourceDecrypter.cs +++ b/de4dot.code/deobfuscators/CryptoObfuscator/ResourceDecrypter.cs @@ -29,7 +29,7 @@ using de4dot.blocks; namespace de4dot.code.deobfuscators.CryptoObfuscator { class ResourceDecrypter { const int BUFLEN = 0x8000; - ModuleDefinition module; + ModuleDefMD module; TypeDef resourceDecrypterType; byte[] buffer1 = new byte[BUFLEN]; byte[] buffer2 = new byte[BUFLEN]; @@ -40,7 +40,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { bool flipFlagsBits; int skipBytes; - public ResourceDecrypter(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator) { + public ResourceDecrypter(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator) { this.module = module; frameworkType = DotNetUtils.getFrameworkType(module); find(simpleDeobfuscator); @@ -49,7 +49,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { void find(ISimpleDeobfuscator simpleDeobfuscator) { switch (frameworkType) { case FrameworkType.Desktop: - if (module.Runtime >= TargetRuntime.Net_2_0) + if (!module.IsClr1x) findDesktopOrCompactFramework(); else findDesktopOrCompactFrameworkV1(); @@ -60,7 +60,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { break; case FrameworkType.CompactFramework: - if (module.Runtime >= TargetRuntime.Net_2_0) { + if (!module.IsClr1x) { if (findDesktopOrCompactFramework()) break; } @@ -84,7 +84,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { if (!new FieldTypes(type).exactly(requiredTypes)) continue; - var cctor = DotNetUtils.getMethod(type, ".cctor"); + var cctor = type.FindClassConstructor(); if (cctor == null) continue; @@ -103,8 +103,8 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { int stsfldCount = 0; foreach (var instr in cctor.Body.Instructions) { if (instr.OpCode.Code == Code.Stsfld) { - var field = instr.Operand as FieldReference; - if (!MemberReferenceHelper.compareTypes(cctor.DeclaringType, field.DeclaringType)) + var field = instr.Operand as IField; + if (!new SigComparer().Equals(cctor.DeclaringType, field.DeclaringType)) return false; stsfldCount++; } @@ -186,10 +186,10 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { var instrs = method.Body.Instructions; for (int i = 0; i < instrs.Count - 1; i++) { var ldloc = instrs[i]; - if (!DotNetUtils.isLdloc(ldloc)) + if (!ldloc.IsLdloc()) continue; - var local = DotNetUtils.getLocalVar(method.Body.Variables, ldloc); - if (local == null || !local.VariableType.IsPrimitive) + var local = ldloc.GetLocal(method.Body.LocalList); + if (local == null || local.Type.GetElementType().GetPrimitiveSize() < 0) continue; var not = instrs[i + 1]; @@ -214,16 +214,16 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { if (and.OpCode.Code != Code.And) continue; var ldci4 = instructions[i - 1]; - if (!DotNetUtils.isLdcI4(ldci4)) + if (!ldci4.IsLdcI4()) continue; - int flagValue = DotNetUtils.getLdcI4Value(ldci4); + int flagValue = ldci4.GetLdcI4Value(); if (!isFlag(flagValue)) continue; var ldloc = instructions[i - 2]; - if (!DotNetUtils.isLdloc(ldloc)) + if (!ldloc.IsLdloc()) continue; - var local = DotNetUtils.getLocalVar(method.Body.Variables, ldloc); - if (!local.VariableType.IsPrimitive) + var local = ldloc.GetLocal(method.Body.LocalList); + if (local.Type.GetElementType().GetPrimitiveSize() < 0) continue; constants.Add(flagValue); } @@ -233,7 +233,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { switch (frameworkType) { case FrameworkType.Desktop: - if (module.Runtime >= TargetRuntime.Net_2_0) { + if (!module.IsClr1x) { if (constants.Count == 2) { desEncryptedFlag = (byte)constants[0]; deflatedFlag = (byte)constants[1]; @@ -270,9 +270,9 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { var instrs = method.Body.Instructions; for (int i = 0; i < instrs.Count - 1; i++) { var ldci4 = instrs[i]; - if (!DotNetUtils.isLdcI4(ldci4)) + if (!ldci4.IsLdcI4()) continue; - int loopCount = DotNetUtils.getLdcI4Value(ldci4); + int loopCount = ldci4.GetLdcI4Value(); if (loopCount < 2 || loopCount > 3) continue; var blt = instrs[i + 1]; @@ -402,7 +402,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { if (key[i] != 0) return key; } - key = module.Assembly.Name.PublicKeyToken; + key = PublicKeyBase.GetRawData(module.Assembly.PublicKeyToken); if (key == null) throw new ApplicationException("PublicKeyToken is null, can't decrypt resources"); return key; diff --git a/de4dot.code/deobfuscators/CryptoObfuscator/ResourceResolver.cs b/de4dot.code/deobfuscators/CryptoObfuscator/ResourceResolver.cs index 70b3442a..3a546a5b 100644 --- a/de4dot.code/deobfuscators/CryptoObfuscator/ResourceResolver.cs +++ b/de4dot.code/deobfuscators/CryptoObfuscator/ResourceResolver.cs @@ -19,13 +19,14 @@ using System; using System.Collections.Generic; +using dot10.IO; using dot10.DotNet; using dot10.DotNet.Emit; using de4dot.blocks; namespace de4dot.code.deobfuscators.CryptoObfuscator { class ResourceResolver { - ModuleDefinition module; + ModuleDefMD module; ResourceDecrypter resourceDecrypter; TypeDef resolverType; MethodDef resolverMethod; @@ -46,7 +47,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { get { return resolverMethod; } } - public ResourceResolver(ModuleDefinition module, ResourceDecrypter resourceDecrypter) { + public ResourceResolver(ModuleDefMD module, ResourceDecrypter resourceDecrypter) { this.module = module; this.resourceDecrypter = resourceDecrypter; } @@ -74,7 +75,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { if (resource == null) return null; - DeobUtils.decryptAndAddResources(module, resource.Name, () => resourceDecrypter.decrypt(resource.GetResourceStream())); + DeobUtils.decryptAndAddResources(module, resource.Name.String, () => resourceDecrypter.decrypt(resource.Data.CreateStream())); mergedIt = true; return resource; } @@ -84,12 +85,12 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { switch (resolverVersion) { case ResolverVersion.V1: - names.Add(module.Assembly.Name.Name); + names.Add(module.Assembly.Name.String); break; case ResolverVersion.V2: - names.Add(string.Format("{0}{0}{0}", module.Assembly.Name.Name)); - names.Add(string.Format("{0}&", module.Assembly.Name.Name)); + names.Add(string.Format("{0}{0}{0}", module.Assembly.Name.String)); + names.Add(string.Format("{0}&", module.Assembly.Name.String)); break; default: @@ -107,7 +108,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { resolverVersion = checkSetupMethod(initMethod); if (resolverVersion == ResolverVersion.None) - resolverVersion = checkSetupMethod(DotNetUtils.getMethod(initMethod.DeclaringType, ".cctor")); + resolverVersion = checkSetupMethod(initMethod.DeclaringType.FindClassConstructor()); if (resolverVersion == ResolverVersion.None) return false; @@ -124,15 +125,15 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { if (instrs == null) continue; - MethodReference methodRef; + IMethod methodRef; var ldftn = instrs[1]; var newobj = instrs[2]; - methodRef = ldftn.Operand as MethodReference; - if (methodRef == null || !MemberReferenceHelper.compareTypes(setupMethod.DeclaringType, methodRef.DeclaringType)) + methodRef = ldftn.Operand as IMethod; + if (methodRef == null || !new SigComparer().Equals(setupMethod.DeclaringType, methodRef.DeclaringType)) continue; - methodRef = newobj.Operand as MethodReference; + methodRef = newobj.Operand as IMethod; if (methodRef == null || methodRef.FullName != "System.Void System.ResolveEventHandler::.ctor(System.Object,System.IntPtr)") continue; diff --git a/de4dot.code/deobfuscators/CryptoObfuscator/StringDecrypter.cs b/de4dot.code/deobfuscators/CryptoObfuscator/StringDecrypter.cs index 96dd017a..e46da176 100644 --- a/de4dot.code/deobfuscators/CryptoObfuscator/StringDecrypter.cs +++ b/de4dot.code/deobfuscators/CryptoObfuscator/StringDecrypter.cs @@ -24,7 +24,7 @@ using de4dot.blocks; namespace de4dot.code.deobfuscators.CryptoObfuscator { class StringDecrypter { - ModuleDefinition module; + ModuleDefMD module; EmbeddedResource stringResource; TypeDef stringDecrypterType; MethodDef stringDecrypterMethod; @@ -46,7 +46,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { get { return stringResource; } } - public StringDecrypter(ModuleDefinition module) { + public StringDecrypter(ModuleDefMD module) { this.module = module; } @@ -74,9 +74,9 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { } string getResourceName() { - var defaultName = module.Assembly.Name.Name + module.Assembly.Name.Name; + var defaultName = module.Assembly.Name.String + module.Assembly.Name.String; - var cctor = DotNetUtils.getMethod(stringDecrypterType, ".cctor"); + var cctor = stringDecrypterType.FindClassConstructor(); if (cctor == null) return defaultName; diff --git a/de4dot.code/deobfuscators/CryptoObfuscator/TamperDetection.cs b/de4dot.code/deobfuscators/CryptoObfuscator/TamperDetection.cs index c975df70..5d109be5 100644 --- a/de4dot.code/deobfuscators/CryptoObfuscator/TamperDetection.cs +++ b/de4dot.code/deobfuscators/CryptoObfuscator/TamperDetection.cs @@ -22,7 +22,7 @@ using de4dot.blocks; namespace de4dot.code.deobfuscators.CryptoObfuscator { class TamperDetection { - ModuleDefinition module; + ModuleDefMD module; TypeDef tamperType; MethodDef tamperMethod; FrameworkType frameworkType; @@ -39,7 +39,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator { get { return tamperMethod; } } - public TamperDetection(ModuleDefinition module) { + public TamperDetection(ModuleDefMD module) { this.module = module; frameworkType = DotNetUtils.getFrameworkType(module); } diff --git a/de4dot.cui/Program.cs b/de4dot.cui/Program.cs index 035caee1..30b5433c 100644 --- a/de4dot.cui/Program.cs +++ b/de4dot.cui/Program.cs @@ -42,8 +42,8 @@ namespace de4dot.cui { new de4dot.code.deobfuscators.CodeFort.DeobfuscatorInfo(), new de4dot.code.deobfuscators.CodeVeil.DeobfuscatorInfo(), new de4dot.code.deobfuscators.CodeWall.DeobfuscatorInfo(), -#if PORT new de4dot.code.deobfuscators.CryptoObfuscator.DeobfuscatorInfo(), +#if PORT new de4dot.code.deobfuscators.DeepSea.DeobfuscatorInfo(), #endif new de4dot.code.deobfuscators.Dotfuscator.DeobfuscatorInfo(), diff --git a/dot10 b/dot10 index da98052a..ba1fa213 160000 --- a/dot10 +++ b/dot10 @@ -1 +1 @@ -Subproject commit da98052a05288943bcb29e813b3c3ba448ae2101 +Subproject commit ba1fa2135fec435ecee2ea041c9a7dae56e5dd47