From 1341cc71992bf02cf91db126e2ec7b379316e30a Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 1 Nov 2012 16:42:02 +0100 Subject: [PATCH] Port more code --- blocks/DotNetUtils.cs | 10 +- blocks/cflow/MethodCallInlinerBase.cs | 2 +- de4dot.code/DeobfuscatorContext.cs | 4 +- de4dot.code/ExternalAssemblies.cs | 41 ++- de4dot.code/IDeobfuscatorContext.cs | 10 +- de4dot.code/MethodPrinter.cs | 18 +- de4dot.code/MethodReturnValueInliner.cs | 63 ++-- de4dot.code/ObfuscatedFile.cs | 46 ++- de4dot.code/StringInliner.cs | 36 +-- de4dot.code/Utils.cs | 6 - de4dot.code/de4dot.code.csproj | 1 - .../Babel_NET/BabelMethodCallInliner.cs | 2 +- .../CliSecure/vm/OpCodeHandler.cs | 2 +- .../DeepSea/ArrayBlockDeobfuscator.cs | 4 +- .../deobfuscators/ExceptionLoggerRemover.cs | 12 +- de4dot.code/deobfuscators/IDeobfuscator.cs | 7 +- .../deobfuscators/ISimpleDeobfuscator.cs | 8 +- .../deobfuscators/MethodBodyReaderBase.cs | 279 ------------------ .../deobfuscators/MethodCallRestorerBase.cs | 28 +- de4dot.code/deobfuscators/MethodStack.cs | 89 +++--- de4dot.code/deobfuscators/MethodsDecrypter.cs | 2 +- de4dot.code/deobfuscators/StringCounts.cs | 24 +- de4dot.code/deobfuscators/TypesRestorer.cs | 6 +- de4dot.code/deobfuscators/ValueInlinerBase.cs | 28 +- de4dot.code/resources/ResourceDataCreator.cs | 2 +- de4dot.code/resources/ResourceReader.cs | 2 +- dot10 | 2 +- 27 files changed, 223 insertions(+), 511 deletions(-) delete mode 100644 de4dot.code/deobfuscators/MethodBodyReaderBase.cs diff --git a/blocks/DotNetUtils.cs b/blocks/DotNetUtils.cs index 5e7aa896..36be5578 100644 --- a/blocks/DotNetUtils.cs +++ b/blocks/DotNetUtils.cs @@ -933,11 +933,11 @@ namespace de4dot.blocks { return args; } - public static List getArgs(DN.IMethod method) { + public static List getArgs(DN.IMethod method) { var sig = method.MethodSig; - var args = new List(sig.Params.Count + 1); - if (sig.HasThis && !sig.ExplicitThis) - args.Add(method.DeclaringType); + var args = new List(sig.Params.Count + 1); + if (sig.ImplicitThis) + args.Add(DN.Extensions.ToTypeSig(method.DeclaringType)); foreach (var arg in sig.Params) args.Add(arg); return args; @@ -969,7 +969,7 @@ namespace de4dot.blocks { if (sig == null) return 0; int count = sig.Params.Count; - if (sig.HasThis && !sig.ExplicitThis) + if (sig.ImplicitThis) count++; return count; } diff --git a/blocks/cflow/MethodCallInlinerBase.cs b/blocks/cflow/MethodCallInlinerBase.cs index 4e0b3d44..b4a787c9 100644 --- a/blocks/cflow/MethodCallInlinerBase.cs +++ b/blocks/cflow/MethodCallInlinerBase.cs @@ -198,7 +198,7 @@ namespace de4dot.blocks.cflow { protected bool checkSameMethods(IMethod method, MethodDef methodToInline, int ignoreLastMethodToInlineArgs) { var methodToInlineArgs = methodToInline.Parameters; var methodArgs = DotNetUtils.getArgs(method); - bool hasImplicitThis = method.MethodSig.HasThis && !method.MethodSig.ExplicitThis; + bool hasImplicitThis = method.MethodSig.ImplicitThis; if (methodToInlineArgs.Length - ignoreLastMethodToInlineArgs != methodArgs.Count) return false; for (int i = 0; i < methodArgs.Count; i++) { diff --git a/de4dot.code/DeobfuscatorContext.cs b/de4dot.code/DeobfuscatorContext.cs index 6b1ecbb1..2b42c90c 100644 --- a/de4dot.code/DeobfuscatorContext.cs +++ b/de4dot.code/DeobfuscatorContext.cs @@ -19,7 +19,7 @@ using System; using System.Collections.Generic; -using Mono.Cecil; +using dot10.DotNet; using de4dot.blocks; namespace de4dot.code { @@ -48,6 +48,7 @@ namespace de4dot.code { dataDict.Remove(name); } +#if PORT static TypeReference getNonGenericTypeReference(TypeReference typeReference) { if (typeReference == null) return null; @@ -104,5 +105,6 @@ namespace de4dot.code { return null; } +#endif } } diff --git a/de4dot.code/ExternalAssemblies.cs b/de4dot.code/ExternalAssemblies.cs index 8c29764b..2dd0307f 100644 --- a/de4dot.code/ExternalAssemblies.cs +++ b/de4dot.code/ExternalAssemblies.cs @@ -19,20 +19,20 @@ using System; using System.Collections.Generic; -using Mono.Cecil; +using dot10.DotNet; using de4dot.blocks; namespace de4dot.code { class ExternalAssembly { - AssemblyDefinition asmDef; + AssemblyDef asmDef; - public ExternalAssembly(AssemblyDefinition asmDef) { + public ExternalAssembly(AssemblyDef asmDef) { this.asmDef = asmDef; } - public TypeDefinition resolve(TypeReference type) { + public TypeDef resolve(ITypeDefOrRef type) { foreach (var module in asmDef.Modules) { - var typeDef = DotNetUtils.getType(module, type); + var typeDef = module.Find(type); if (typeDef != null) return typeDef; } @@ -42,7 +42,7 @@ namespace de4dot.code { public void unload(string asmFullName) { foreach (var module in asmDef.Modules) { - DotNetUtils.typeCaches.invalidate(module); + //TODO: DotNetUtils.typeCaches.invalidate(module); AssemblyResolver.Instance.removeModule(module); } AssemblyResolver.Instance.removeModule(asmFullName); @@ -54,45 +54,38 @@ namespace de4dot.code { Dictionary assemblies = new Dictionary(StringComparer.Ordinal); Dictionary failedLoads = new Dictionary(StringComparer.Ordinal); - ExternalAssembly load(TypeReference type) { - var asmFullName = DotNetUtils.getFullAssemblyName(type); - if (asmFullName == null) + ExternalAssembly load(TypeRef type) { + if (type == null || type.DefinitionAssembly == null) return null; + var asmFullName = type.DefinitionAssembly.FullName; ExternalAssembly asm; if (assemblies.TryGetValue(asmFullName, out asm)) return asm; - AssemblyDefinition asmDef = null; - try { - asmDef = AssemblyResolver.Instance.Resolve(asmFullName); - } - catch (ResolutionException) { - } - catch (AssemblyResolutionException) { - } + var asmDef = AssemblyResolver.Instance.Resolve(type.DefinitionAssembly, type.OwnerModule); if (asmDef == null) { if (!failedLoads.ContainsKey(asmFullName)) Log.w("Could not load assembly {0}", asmFullName); failedLoads[asmFullName] = true; return null; } - if (assemblies.ContainsKey(asmDef.Name.FullName)) { - assemblies[asmFullName] = assemblies[asmDef.Name.FullName]; - return assemblies[asmDef.Name.FullName]; + if (assemblies.ContainsKey(asmDef.FullName)) { + assemblies[asmFullName] = assemblies[asmDef.FullName]; + return assemblies[asmDef.FullName]; } - if (asmFullName == asmDef.Name.FullName) + if (asmFullName == asmDef.FullName) Log.v("Loaded assembly {0}", asmFullName); else - Log.v("Loaded assembly {0} (but wanted {1})", asmDef.Name.FullName, asmFullName); + Log.v("Loaded assembly {0} (but wanted {1})", asmDef.FullName, asmFullName); asm = new ExternalAssembly(asmDef); assemblies[asmFullName] = asm; - assemblies[asmDef.Name.FullName] = asm; + assemblies[asmDef.FullName] = asm; return asm; } - public TypeDefinition resolve(TypeReference type) { + public TypeDef resolve(TypeRef type) { if (type == null) return null; var asm = load(type); diff --git a/de4dot.code/IDeobfuscatorContext.cs b/de4dot.code/IDeobfuscatorContext.cs index 8a666876..4e7a2611 100644 --- a/de4dot.code/IDeobfuscatorContext.cs +++ b/de4dot.code/IDeobfuscatorContext.cs @@ -17,7 +17,7 @@ along with de4dot. If not, see . */ -using Mono.Cecil; +using dot10.DotNet; namespace de4dot.code { public interface IDeobfuscatorContext { @@ -25,8 +25,10 @@ namespace de4dot.code { void setData(string name, object data); object getData(string name); void clearData(string name); - TypeDefinition resolve(TypeReference type); - MethodDefinition resolve(MethodReference method); - FieldDefinition resolve(FieldReference field); +#if PORT + TypeDef resolve(TypeRef type); + MethodDef resolve(IMethod method); + FieldDef resolve(IField field); +#endif } } diff --git a/de4dot.code/MethodPrinter.cs b/de4dot.code/MethodPrinter.cs index d6ed2881..cb981c18 100644 --- a/de4dot.code/MethodPrinter.cs +++ b/de4dot.code/MethodPrinter.cs @@ -19,8 +19,8 @@ using System.Collections.Generic; using System.Text; -using Mono.Cecil; -using Mono.Cecil.Cil; +using dot10.DotNet; +using dot10.DotNet.Emit; using de4dot.blocks; namespace de4dot.code { @@ -83,7 +83,7 @@ namespace de4dot.code { } var sortedTargets = new List(targets.Keys); - sortedTargets.Sort((a, b) => Utils.compareInt32(a.Offset, b.Offset)); + sortedTargets.Sort((a, b) => a.Offset.CompareTo(b.Offset)); for (int i = 0; i < sortedTargets.Count; i++) labels[sortedTargets[i]] = string.Format("label_{0}", i); } @@ -131,13 +131,13 @@ namespace de4dot.code { ExInfo exInfo; if (exInfos.TryGetValue(instr, out exInfo)) printExInfo(exInfo); - var instrString = instr.GetOpCodeString(); + var instrString = instr.OpCode.Name; var operandString = getOperandString(instr); - var memberReference = instr.Operand as MemberReference; + var memberReference = instr.Operand as ITokenOperand; if (operandString == "") Log.log(logLevel, "{0}", instrString); else if (memberReference != null) - Log.log(logLevel, "{0,-9} {1} // {2:X8}", instrString, Utils.removeNewlines(operandString), memberReference.MetadataToken.ToUInt32()); + Log.log(logLevel, "{0,-9} {1} // {2:X8}", instrString, Utils.removeNewlines(operandString), memberReference.MDToken.ToUInt32()); else Log.log(logLevel, "{0,-9} {1}", instrString, Utils.removeNewlines(operandString)); } @@ -160,12 +160,12 @@ namespace de4dot.code { } else if (instr.Operand is string) return Utils.toCsharpString((string)instr.Operand); - else if (instr.Operand is ParameterDefinition) { - var arg = (ParameterDefinition)instr.Operand; + else if (instr.Operand is Parameter) { + var arg = (Parameter)instr.Operand; var s = instr.GetOperandString(); if (s != "") return s; - return string.Format("", DotNetUtils.getArgIndex(arg)); + return string.Format("", arg.Index); } else return instr.GetOperandString(); diff --git a/de4dot.code/MethodReturnValueInliner.cs b/de4dot.code/MethodReturnValueInliner.cs index 309a4827..a13d7ca6 100644 --- a/de4dot.code/MethodReturnValueInliner.cs +++ b/de4dot.code/MethodReturnValueInliner.cs @@ -19,17 +19,16 @@ 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 { // A simple class that statically detects the values of some local variables class VariableValues { IList allBlocks; - IList locals; - Dictionary variableToValue = new Dictionary(); + IList locals; + Dictionary variableToValue = new Dictionary(); public class Variable { int writes = 0; @@ -58,7 +57,7 @@ namespace de4dot.code { } } - public VariableValues(IList locals, IList allBlocks) { + public VariableValues(IList locals, IList allBlocks) { this.locals = locals; this.allBlocks = allBlocks; init(); @@ -136,7 +135,7 @@ namespace de4dot.code { } } - public Variable getValue(VariableDefinition variable) { + public Variable getValue(Local variable) { return variableToValue[variable]; } } @@ -144,7 +143,7 @@ namespace de4dot.code { abstract class MethodReturnValueInliner { protected List callResults; List allBlocks; - MethodDefinition theMethod; + MethodDef theMethod; VariableValues variableValues; int errors = 0; bool useUnknownArgs = false; @@ -166,8 +165,8 @@ namespace de4dot.code { this.callEndIndex = callEndIndex; } - public MethodReference getMethodReference() { - return (MethodReference)block.Instructions[callEndIndex].Operand; + public IMethod getMethodReference() { + return (IMethod)block.Instructions[callEndIndex].Operand; } } @@ -177,14 +176,14 @@ namespace de4dot.code { public abstract bool HasHandlers { get; } - public MethodDefinition Method { + public MethodDef Method { get { return theMethod; } } protected abstract void inlineAllCalls(); // Returns null if method is not a method we should inline - protected abstract CallResult createCallResult(MethodReference method, GenericInstanceMethod gim, Block block, int callInstrIndex); + protected abstract CallResult createCallResult(IMethod method, MethodSpec gim, Block block, int callInstrIndex); public int decrypt(Blocks blocks) { if (!HasHandlers) @@ -192,7 +191,7 @@ namespace de4dot.code { return decrypt(blocks.Method, blocks.MethodBlocks.getAllBlocks()); } - public int decrypt(MethodDefinition method, List allBlocks) { + public int decrypt(MethodDef method, List allBlocks) { if (!HasHandlers) return 0; try { @@ -217,9 +216,9 @@ namespace de4dot.code { } } - bool getLocalVariableValue(VariableDefinition variable, out object value) { + bool getLocalVariableValue(Local variable, out object value) { if (variableValues == null) - variableValues = new VariableValues(theMethod.Body.Variables, allBlocks); + variableValues = new VariableValues(theMethod.CilBody.LocalList, allBlocks); var val = variableValues.getValue(variable); if (!val.isValid()) { value = null; @@ -239,14 +238,14 @@ namespace de4dot.code { var instr = block.Instructions[i]; if (instr.OpCode != OpCodes.Call) continue; - var method = instr.Operand as MethodReference; + var method = instr.Operand as IMethod; if (method == null) continue; - MethodReference elementMethod = method; - var gim = method as GenericInstanceMethod; + IMethod elementMethod = method; + var gim = method as MethodSpec; if (gim != null) - elementMethod = gim.ElementMethod; + elementMethod = gim.Method; var callResult = createCallResult(elementMethod, gim, block, i); if (callResult == null) continue; @@ -259,7 +258,7 @@ namespace de4dot.code { bool findArgs(CallResult callResult) { var block = callResult.block; var method = callResult.getMethodReference(); - var methodArgs = DotNetUtils.getParameters(method); + var methodArgs = DotNetUtils.getArgs(method); int numArgs = methodArgs.Count; var args = new object[numArgs]; @@ -269,9 +268,9 @@ namespace de4dot.code { if (!getArg(method, block, ref arg, ref instrIndex)) return false; if (arg is int) - arg = fixIntArg(methodArgs[i].ParameterType, (int)arg); + arg = fixIntArg(methodArgs[i], (int)arg); else if (arg is long) - arg = fixIntArg(methodArgs[i].ParameterType, (long)arg); + arg = fixIntArg(methodArgs[i], (long)arg); args[i] = arg; } @@ -280,8 +279,8 @@ namespace de4dot.code { return true; } - object fixIntArg(TypeReference type, long value) { - switch (type.EType) { + object fixIntArg(TypeSig type, long value) { + switch (type.ElementType) { case ElementType.Boolean: return value != 0; case ElementType.Char: return (char)value; case ElementType.I1: return (sbyte)value; @@ -296,7 +295,7 @@ namespace de4dot.code { throw new ApplicationException(string.Format("Wrong type {0}", type)); } - bool getArg(MethodReference method, Block block, ref object arg, ref int instrIndex) { + bool getArg(IMethod method, Block block, ref object arg, ref int instrIndex) { while (true) { if (instrIndex < 0) { // We're here if there were no cflow deobfuscation, or if there are two or @@ -304,7 +303,7 @@ namespace de4dot.code { // merged because one is outside the exception handler (eg. buggy obfuscator). Log.w("Could not find all arguments to method {0} ({1:X8})", Utils.removeNewlines(method), - method.MetadataToken.ToInt32()); + method.MDToken.ToInt32()); errors++; return false; } @@ -343,7 +342,7 @@ namespace de4dot.code { case Code.Ldloc_1: case Code.Ldloc_2: case Code.Ldloc_3: - getLocalVariableValue(Instr.getLocalVar(theMethod.Body.Variables, instr), out arg); + getLocalVariableValue(instr.Instruction.GetLocal(theMethod.CilBody.LocalList), out arg); break; case Code.Ldfld: @@ -353,11 +352,11 @@ namespace de4dot.code { default: int pushes, pops; - DotNetUtils.calculateStackUsage(instr.Instruction, false, out pushes, out pops); + instr.Instruction.CalculateStackUsage(false, out pushes, out pops); if (!useUnknownArgs || pushes != 1) { Log.w("Could not find all arguments to method {0} ({1:X8}), instr: {2}", Utils.removeNewlines(method), - method.MetadataToken.ToInt32(), + method.MDToken.ToInt32(), instr); errors++; return false; @@ -381,10 +380,10 @@ namespace de4dot.code { callResults.Sort((a, b) => { int i1 = allBlocks.FindIndex((x) => a.block == x); int i2 = allBlocks.FindIndex((x) => b.block == x); - if (i1 < i2) return -1; - if (i1 > i2) return 1; + if (i1 != i2) + return i1.CompareTo(i2); - return Utils.compareInt32(a.callStartIndex, b.callStartIndex); + return a.callStartIndex.CompareTo(b.callStartIndex); }); callResults.Reverse(); inlineReturnValues(callResults); diff --git a/de4dot.code/ObfuscatedFile.cs b/de4dot.code/ObfuscatedFile.cs index 300030c0..013f1d7e 100644 --- a/de4dot.code/ObfuscatedFile.cs +++ b/de4dot.code/ObfuscatedFile.cs @@ -432,26 +432,28 @@ namespace de4dot.code { if (typeString != null && typeString != type.FullName) continue; foreach (var method in type.Methods) { - if (!method.IsStatic || method.MethodReturnType.ReturnType.FullName != "System.String") + if (!method.IsStatic) + continue; + if (method.MethodSig.RetType.ElementType != ElementType.String && method.MethodSig.RetType.ElementType != ElementType.Object) continue; if (methodName != null && methodName != method.Name) continue; if (argsStrings == null) { - if (method.Parameters.Count == 0) + if (method.Parameters.Length == 0) continue; } else { - if (argsStrings.Length != method.Parameters.Count) + if (argsStrings.Length != method.Parameters.Length) continue; for (int i = 0; i < argsStrings.Length; i++) { - if (argsStrings[i] != method.Parameters[i].ParameterType.FullName) + if (argsStrings[i] != method.Parameters[i].Type.FullName) continue; } } - Log.v("Adding string decrypter; token: {0:X8}, method: {1}", method.MetadataToken.ToInt32(), Utils.removeNewlines(method.FullName)); - tokens.Add(method.MetadataToken.ToInt32()); + Log.v("Adding string decrypter; token: {0:X8}, method: {1}", method.MDToken.ToInt32(), Utils.removeNewlines(method.FullName)); + tokens.Add(method.MDToken.ToInt32()); } } @@ -530,30 +532,26 @@ namespace de4dot.code { Log.v("Deobfuscating methods"); var methodPrinter = new MethodPrinter(); -#if PORT var cflowDeobfuscator = new BlocksCflowDeobfuscator(deob.BlocksDeobfuscators); -#endif foreach (var method in getAllMethods()) { - Log.v("Deobfuscating {0} ({1:X8})", Utils.removeNewlines(method), method.MetadataToken.ToUInt32()); + Log.v("Deobfuscating {0} ({1:X8})", Utils.removeNewlines(method), method.MDToken.ToUInt32()); Log.indent(); int oldIndentLevel = Log.indentLevel; try { -#if PORT deobfuscate(method, cflowDeobfuscator, methodPrinter); -#endif } catch (ApplicationException) { throw; } catch (Exception ex) { if (!canLoadMethodBody(method)) { - Log.v("Invalid method body. {0:X8}", method.MetadataToken.ToInt32()); - method.CilBody = new MethodBody(method); + Log.v("Invalid method body. {0:X8}", method.MDToken.ToInt32()); + method.CilBody = new CilBody(); } else { Log.w("Could not deobfuscate method {0:X8}. Hello, E.T.: {1}", // E.T. = exception type - method.MetadataToken.ToInt32(), + method.MDToken.ToInt32(), ex.GetType()); } } @@ -576,7 +574,6 @@ namespace de4dot.code { } } -#if PORT void deobfuscate(MethodDef method, BlocksCflowDeobfuscator cflowDeobfuscator, MethodPrinter methodPrinter) { if (!hasNonEmptyBody(method)) return; @@ -621,10 +618,9 @@ namespace de4dot.code { Log.deIndent(); } } -#endif bool hasNonEmptyBody(MethodDef method) { - return method.HasBody && method.CilBody.Instructions.Count > 0; + return method.HasCilBody && method.CilBody.Instructions.Count > 0; } void deobfuscateStrings(Blocks blocks) { @@ -647,10 +643,10 @@ namespace de4dot.code { } void removeNoInliningAttribute(MethodDef method) { - method.ImplAttributes = method.ImplAttributes & ~MethodImplAttributes.NoInlining; + method.IsNoInlining = false; for (int i = 0; i < method.CustomAttributes.Count; i++) { var cattr = method.CustomAttributes[i]; - if (cattr.AttributeType.FullName != "System.Runtime.CompilerServices.MethodImplAttribute") + if (cattr.TypeFullName != "System.Runtime.CompilerServices.MethodImplAttribute") continue; int options = 0; if (!getMethodImplOptions(cattr, ref options)) @@ -663,13 +659,13 @@ namespace de4dot.code { } static bool getMethodImplOptions(CustomAttribute cattr, ref int value) { - if (cattr.ConstructorArguments.Count != 1) + if (cattr.Arguments.Count != 1) return false; - if (cattr.ConstructorArguments[0].Type.FullName != "System.Int16" && - cattr.ConstructorArguments[0].Type.FullName != "System.Runtime.CompilerServices.MethodImplOptions") + if (cattr.Arguments[0].Type.ElementType != ElementType.I2 && + cattr.Arguments[0].Type.FullName != "System.Runtime.CompilerServices.MethodImplOptions") return false; - var arg = cattr.ConstructorArguments[0].Value; + var arg = cattr.Arguments[0].Value; if (arg is short) { value = (short)arg; return true; @@ -704,7 +700,7 @@ namespace de4dot.code { if (savedMethodBodies != null) savedMethodBodies.save(method); - Log.v("{0}: {1} ({2:X8})", msg, Utils.removeNewlines(method), method.MetadataToken.ToUInt32()); + Log.v("{0}: {1} ({2:X8})", msg, Utils.removeNewlines(method), method.MDToken.ToUInt32()); Log.indent(); if (hasNonEmptyBody(method)) { @@ -719,7 +715,7 @@ namespace de4dot.code { DotNetUtils.restoreBody(method, allInstructions, allExceptionHandlers); } catch { - Log.v("Could not deobfuscate {0:X8}", method.MetadataToken.ToInt32()); + Log.v("Could not deobfuscate {0:X8}", method.MDToken.ToInt32()); } } diff --git a/de4dot.code/StringInliner.cs b/de4dot.code/StringInliner.cs index 7e0e6147..07e5eee6 100644 --- a/de4dot.code/StringInliner.cs +++ b/de4dot.code/StringInliner.cs @@ -19,8 +19,8 @@ using System; using System.Collections.Generic; -using Mono.Cecil; -using Mono.Cecil.Cil; +using dot10.DotNet; +using dot10.DotNet.Emit; using de4dot.code.AssemblyClient; using de4dot.blocks; @@ -49,7 +49,7 @@ namespace de4dot.code { if (ldstrIndex + 1 < block.Instructions.Count) { var instr = block.Instructions[ldstrIndex + 1]; if (instr.OpCode.Code == Code.Call) { - var calledMethod = instr.Operand as MethodReference; + var calledMethod = instr.Operand as IMethod; if (calledMethod != null && calledMethod.FullName == "System.String System.String::Intern(System.String)") { block.remove(ldstrIndex + 1, 1); @@ -68,8 +68,8 @@ namespace de4dot.code { class MyCallResult : CallResult { public int methodId; - public GenericInstanceMethod gim; - public MyCallResult(Block block, int callEndIndex, int methodId, GenericInstanceMethod gim) + public MethodSpec gim; + public MyCallResult(Block block, int callEndIndex, int methodId, MethodSpec gim) : base(block, callEndIndex) { this.methodId = methodId; this.gim = gim; @@ -93,9 +93,9 @@ namespace de4dot.code { } } - protected override CallResult createCallResult(MethodReference method, GenericInstanceMethod gim, Block block, int callInstrIndex) { + protected override CallResult createCallResult(IMethod method, MethodSpec gim, Block block, int callInstrIndex) { int methodId; - if (!methodTokenToId.TryGetValue(method.MetadataToken.ToInt32(), out methodId)) + if (!methodTokenToId.TryGetValue(method.MDToken.ToInt32(), out methodId)) return null; return new MyCallResult(block, callInstrIndex, methodId, gim); } @@ -117,7 +117,7 @@ namespace de4dot.code { AssemblyData.SimpleData.pack(list[i].args); args[i] = list[i].args; } - var decryptedStrings = assemblyClient.Service.decryptStrings(methodId, args, Method.MetadataToken.ToInt32()); + var decryptedStrings = assemblyClient.Service.decryptStrings(methodId, args, Method.MDToken.ToInt32()); if (decryptedStrings.Length != args.Length) throw new ApplicationException("Invalid decrypted strings array length"); AssemblyData.SimpleData.unpack(decryptedStrings); @@ -128,27 +128,27 @@ namespace de4dot.code { } class StaticStringInliner : StringInlinerBase { - MethodDefinitionAndDeclaringTypeDict> stringDecrypters = new MethodDefinitionAndDeclaringTypeDict>(); + MethodDefinitionAndDeclaringTypeDict> stringDecrypters = new MethodDefinitionAndDeclaringTypeDict>(); public override bool HasHandlers { get { return stringDecrypters.Count != 0; } } - public IEnumerable Methods { + public IEnumerable Methods { get { return stringDecrypters.getKeys(); } } class MyCallResult : CallResult { - public MethodReference methodReference; - public GenericInstanceMethod gim; - public MyCallResult(Block block, int callEndIndex, MethodReference method, GenericInstanceMethod gim) + public IMethod IMethod; + public MethodSpec gim; + public MyCallResult(Block block, int callEndIndex, IMethod method, MethodSpec gim) : base(block, callEndIndex) { - this.methodReference = method; + this.IMethod = method; this.gim = gim; } } - public void add(MethodDefinition method, Func handler) { + public void add(MethodDef method, Func handler) { if (method != null) stringDecrypters.add(method, handler); } @@ -156,12 +156,12 @@ namespace de4dot.code { protected override void inlineAllCalls() { foreach (var tmp in callResults) { var callResult = (MyCallResult)tmp; - var handler = stringDecrypters.find(callResult.methodReference); - callResult.returnValue = handler((MethodDefinition)callResult.methodReference, callResult.gim, callResult.args); + var handler = stringDecrypters.find(callResult.IMethod); + callResult.returnValue = handler((MethodDef)callResult.IMethod, callResult.gim, callResult.args); } } - protected override CallResult createCallResult(MethodReference method, GenericInstanceMethod gim, Block block, int callInstrIndex) { + protected override CallResult createCallResult(IMethod method, MethodSpec gim, Block block, int callInstrIndex) { if (stringDecrypters.find(method) == null) return null; return new MyCallResult(block, callInstrIndex, method, gim); diff --git a/de4dot.code/Utils.cs b/de4dot.code/Utils.cs index 7f440ab0..1179f6de 100644 --- a/de4dot.code/Utils.cs +++ b/de4dot.code/Utils.cs @@ -214,12 +214,6 @@ namespace de4dot.code { return true; } - public static int compareInt32(int a, int b) { - if (a < b) return -1; - if (a > b) return 1; - return 0; - } - public static byte[] readFile(string filename) { // If the file is on the network, and we read more than 2MB, we'll read from the wrong // offset in the file! Tested: VMware 8, Win7 x64. diff --git a/de4dot.code/de4dot.code.csproj b/de4dot.code/de4dot.code.csproj index c67aae99..ca247b7e 100644 --- a/de4dot.code/de4dot.code.csproj +++ b/de4dot.code/de4dot.code.csproj @@ -219,7 +219,6 @@ - diff --git a/de4dot.code/deobfuscators/Babel_NET/BabelMethodCallInliner.cs b/de4dot.code/deobfuscators/Babel_NET/BabelMethodCallInliner.cs index 10d9c955..0bc17b71 100644 --- a/de4dot.code/deobfuscators/Babel_NET/BabelMethodCallInliner.cs +++ b/de4dot.code/deobfuscators/Babel_NET/BabelMethodCallInliner.cs @@ -120,7 +120,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { return false; block.Instructions[instrIndex - 1] = new Instr(Instruction.Create(OpCodes.Nop)); - block.Instructions[instrIndex] = new Instr(DotNetUtils.createLdci4(newValue)); + block.Instructions[instrIndex] = new Instr(Instruction.CreateLdcI4(newValue)); return true; } diff --git a/de4dot.code/deobfuscators/CliSecure/vm/OpCodeHandler.cs b/de4dot.code/deobfuscators/CliSecure/vm/OpCodeHandler.cs index d3aceec1..f8a43ab5 100644 --- a/de4dot.code/deobfuscators/CliSecure/vm/OpCodeHandler.cs +++ b/de4dot.code/deobfuscators/CliSecure/vm/OpCodeHandler.cs @@ -392,7 +392,7 @@ namespace de4dot.code.deobfuscators.CliSecure.vm { static Instruction ldc_read(BinaryReader reader) { switch ((ElementType)reader.ReadByte()) { - case ElementType.I4: return DotNetUtils.createLdci4(reader.ReadInt32()); + case ElementType.I4: return Instruction.CreateLdcI4(reader.ReadInt32()); case ElementType.I8: return Instruction.Create(OpCodes.Ldc_I8, reader.ReadInt64()); case ElementType.R4: return Instruction.Create(OpCodes.Ldc_R4, reader.ReadSingle()); case ElementType.R8: return Instruction.Create(OpCodes.Ldc_R8, reader.ReadDouble()); diff --git a/de4dot.code/deobfuscators/DeepSea/ArrayBlockDeobfuscator.cs b/de4dot.code/deobfuscators/DeepSea/ArrayBlockDeobfuscator.cs index 79bf6340..3cf42f89 100644 --- a/de4dot.code/deobfuscators/DeepSea/ArrayBlockDeobfuscator.cs +++ b/de4dot.code/deobfuscators/DeepSea/ArrayBlockDeobfuscator.cs @@ -115,7 +115,7 @@ namespace de4dot.code.deobfuscators.DeepSea { return false; block.remove(i, 3 - 1); - instrs[i] = new Instr(DotNetUtils.createLdci4(info.array[ldci4.getLdcI4Value()])); + instrs[i] = new Instr(Instruction.CreateLdcI4(info.array[ldci4.getLdcI4Value()])); return true; } @@ -140,7 +140,7 @@ namespace de4dot.code.deobfuscators.DeepSea { return false; block.remove(i, 3 - 1); - instrs[i] = new Instr(DotNetUtils.createLdci4(info.array[ldci4.getLdcI4Value()])); + instrs[i] = new Instr(Instruction.CreateLdcI4(info.array[ldci4.getLdcI4Value()])); return true; } diff --git a/de4dot.code/deobfuscators/ExceptionLoggerRemover.cs b/de4dot.code/deobfuscators/ExceptionLoggerRemover.cs index d3b204c9..34cc2c87 100644 --- a/de4dot.code/deobfuscators/ExceptionLoggerRemover.cs +++ b/de4dot.code/deobfuscators/ExceptionLoggerRemover.cs @@ -18,8 +18,8 @@ */ 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 { @@ -28,7 +28,7 @@ namespace de4dot.code.deobfuscators { public int NumRemovedExceptionLoggers { get; set; } - public void add(MethodDefinition exceptionLogger) { + public void add(MethodDef exceptionLogger) { exceptionLoggerMethods.add(exceptionLogger, true); } @@ -42,7 +42,7 @@ namespace de4dot.code.deobfuscators { if (tryBlock.TryHandlerBlocks.Count != 1) continue; var catchBlock = tryBlock.TryHandlerBlocks[0]; - if (catchBlock.HandlerType != ExceptionHandlerType.Catch || + if (catchBlock.HandlerType != ExceptionClause.Catch || catchBlock.CatchType.FullName != "System.Exception") { continue; } @@ -74,7 +74,7 @@ namespace de4dot.code.deobfuscators { } if (failed || calls != 1 || callInstr.OpCode.Code != Code.Call) continue; - var calledMethod = callInstr.Operand as MethodReference; + var calledMethod = callInstr.Operand as IMethod; if (calledMethod == null) continue; if (!isExceptionLogger(calledMethod)) @@ -86,7 +86,7 @@ namespace de4dot.code.deobfuscators { return false; } - protected virtual bool isExceptionLogger(MethodReference method) { + protected virtual bool isExceptionLogger(IMethod method) { return exceptionLoggerMethods.find(method); } diff --git a/de4dot.code/deobfuscators/IDeobfuscator.cs b/de4dot.code/deobfuscators/IDeobfuscator.cs index 8096f9e1..09b6cb36 100644 --- a/de4dot.code/deobfuscators/IDeobfuscator.cs +++ b/de4dot.code/deobfuscators/IDeobfuscator.cs @@ -19,8 +19,7 @@ using System; using System.Collections.Generic; -using Mono.Cecil; -using Mono.MyStuff; +using dot10.DotNet; using de4dot.blocks; using de4dot.blocks.cflow; #if PORT @@ -78,7 +77,7 @@ namespace de4dot.code.deobfuscators { // Returns null or the unpacked .NET PE file byte[] unpackNativeFile(PeImage peImage); - void init(ModuleDefinition module); + void init(ModuleDefMD module); // Returns 0 if it's not detected, or > 0 if detected (higher value => more likely true). // This method is always called. @@ -90,7 +89,7 @@ namespace de4dot.code.deobfuscators { // This is only called if getDecryptedModule() != null, and after the module has been // reloaded. Should return a new IDeobfuscator with the same options and the new module. - IDeobfuscator moduleReloaded(ModuleDefinition module); + IDeobfuscator moduleReloaded(ModuleDefMD module); // Called before all other deobfuscation methods void deobfuscateBegin(); diff --git a/de4dot.code/deobfuscators/ISimpleDeobfuscator.cs b/de4dot.code/deobfuscators/ISimpleDeobfuscator.cs index 6b028100..a1749e38 100644 --- a/de4dot.code/deobfuscators/ISimpleDeobfuscator.cs +++ b/de4dot.code/deobfuscators/ISimpleDeobfuscator.cs @@ -17,12 +17,12 @@ along with de4dot. If not, see . */ -using Mono.Cecil; +using dot10.DotNet; namespace de4dot.code.deobfuscators { public interface ISimpleDeobfuscator { - void deobfuscate(MethodDefinition method); - void deobfuscate(MethodDefinition method, bool force); - void decryptStrings(MethodDefinition method, IDeobfuscator deob); + void deobfuscate(MethodDef method); + void deobfuscate(MethodDef method, bool force); + void decryptStrings(MethodDef method, IDeobfuscator deob); } } diff --git a/de4dot.code/deobfuscators/MethodBodyReaderBase.cs b/de4dot.code/deobfuscators/MethodBodyReaderBase.cs deleted file mode 100644 index 7c3fe0ea..00000000 --- a/de4dot.code/deobfuscators/MethodBodyReaderBase.cs +++ /dev/null @@ -1,279 +0,0 @@ -/* - Copyright (C) 2011-2012 de4dot@gmail.com - - This file is part of de4dot. - - de4dot is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - de4dot is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with de4dot. If not, see . -*/ - -using System; -using System.Collections.Generic; -using System.IO; -using Mono.Cecil; -using Mono.Cecil.Cil; -using de4dot.blocks; - -namespace de4dot.code.deobfuscators { - abstract class MethodBodyReaderBase { - protected BinaryReader reader; - public IList Locals { get; set; } - public IList Instructions { get; set; } - public IList ExceptionHandlers { get; set; } - protected IList parameters; - int currentOffset; - - public MethodBodyReaderBase(BinaryReader reader) { - this.reader = reader; - } - - protected void setLocals(IList types) { - Locals = new List(types.Count); - foreach (var type in types) - Locals.Add(new VariableDefinition(type)); - } - - protected void readInstructions(int numInstrs) { - Instructions = new Instruction[numInstrs]; - currentOffset = 0; - for (int i = 0; i < Instructions.Count; i++) - Instructions[i] = readOneInstruction(); - fixBranches(); - } - - protected void readInstructionsNumBytes(uint codeSize) { - var instrs = new List(); - long endOffs = reader.BaseStream.Position + codeSize; - while (reader.BaseStream.Position < endOffs) - instrs.Add(readOneInstruction()); - if (reader.BaseStream.Position != endOffs) - throw new ApplicationException("Could not read all instructions"); - Instructions = instrs; - fixBranches(); - } - - Instruction readOneInstruction() { - var instr = readInstruction(); - if (instr.OpCode.Code == Code.Switch) { - int[] targets = (int[])instr.Operand; - currentOffset += instr.OpCode.Size + 4 + 4 * targets.Length; - } - else - currentOffset += instr.GetSize(); - return instr; - } - - void fixBranches() { - foreach (var instr in Instructions) { - switch (instr.OpCode.OperandType) { - case OperandType.InlineBrTarget: - case OperandType.ShortInlineBrTarget: - instr.Operand = getInstruction((int)instr.Operand); - break; - - case OperandType.InlineSwitch: - var intTargets = (int[])instr.Operand; - var targets = new Instruction[intTargets.Length]; - for (int i = 0; i < intTargets.Length; i++) - targets[i] = getInstruction(intTargets[i]); - instr.Operand = targets; - break; - } - } - } - - protected Instruction getInstructionOrNull(int offset) { - foreach (var instr in Instructions) { - if (instr.Offset == offset) - return instr; - } - return null; - } - - protected Instruction getInstruction(int offset) { - var instr = getInstructionOrNull(offset); - if (instr != null) - return instr; - throw new ApplicationException(string.Format("No instruction found at offset {0:X4}", offset)); - } - - Instruction readInstruction() { - int offset = currentOffset; - var opcode = readOpCode(); - var instr = new Instruction { - OpCode = opcode, - Offset = offset, - }; - instr.Operand = readOperand(instr); - return instr; - } - - object readOperand(Instruction instr) { - switch (instr.OpCode.OperandType) { - case OperandType.InlineBrTarget: - return readInlineBrTarget(instr); - case OperandType.InlineField: - return readInlineField(instr); - case OperandType.InlineI: - return readInlineI(instr); - case OperandType.InlineI8: - return readInlineI8(instr); - case OperandType.InlineMethod: - return readInlineMethod(instr); - case OperandType.InlineNone: - return readInlineNone(instr); - case OperandType.InlinePhi: - return readInlinePhi(instr); - case OperandType.InlineR: - return readInlineR(instr); - case OperandType.InlineSig: - return readInlineSig(instr); - case OperandType.InlineString: - return readInlineString(instr); - case OperandType.InlineSwitch: - return readInlineSwitch(instr); - case OperandType.InlineTok: - return readInlineTok(instr); - case OperandType.InlineType: - return readInlineType(instr); - case OperandType.InlineVar: - return readInlineVar(instr); - case OperandType.InlineArg: - return readInlineArg(instr); - case OperandType.ShortInlineBrTarget: - return readShortInlineBrTarget(instr); - case OperandType.ShortInlineI: - return readShortInlineI(instr); - case OperandType.ShortInlineR: - return readShortInlineR(instr); - case OperandType.ShortInlineVar: - return readShortInlineVar(instr); - case OperandType.ShortInlineArg: - return readShortInlineArg(instr); - default: - throw new ApplicationException(string.Format("Unknown operand type {0}", instr.OpCode.OperandType)); - } - } - - protected virtual int readInlineBrTarget(Instruction instr) { - return currentOffset + instr.GetSize() + reader.ReadInt32(); - } - - protected abstract FieldReference readInlineField(Instruction instr); - - protected virtual int readInlineI(Instruction instr) { - return reader.ReadInt32(); - } - - protected virtual long readInlineI8(Instruction instr) { - return reader.ReadInt64(); - } - - protected abstract MethodReference readInlineMethod(Instruction instr); - - protected virtual object readInlineNone(Instruction instr) { - return null; - } - - protected virtual object readInlinePhi(Instruction instr) { - return null; - } - - protected virtual double readInlineR(Instruction instr) { - return reader.ReadDouble(); - } - - protected abstract CallSite readInlineSig(Instruction instr); - - protected abstract string readInlineString(Instruction instr); - - protected virtual int[] readInlineSwitch(Instruction instr) { - var targets = new int[reader.ReadInt32()]; - int offset = currentOffset + instr.OpCode.Size + 4 + 4 * targets.Length; - for (int i = 0; i < targets.Length; i++) - targets[i] = offset + reader.ReadInt32(); - return targets; - } - - protected abstract MemberReference readInlineTok(Instruction instr); - - protected abstract TypeReference readInlineType(Instruction instr); - - protected virtual VariableDefinition readInlineVar(Instruction instr) { - return Locals[reader.ReadUInt16()]; - } - - protected virtual ParameterDefinition readInlineArg(Instruction instr) { - return parameters[reader.ReadUInt16()]; - } - - protected virtual int readShortInlineBrTarget(Instruction instr) { - return currentOffset + instr.GetSize() + reader.ReadSByte(); - } - - protected virtual object readShortInlineI(Instruction instr) { - if (instr.OpCode.Code == Code.Ldc_I4_S) - return reader.ReadSByte(); - return reader.ReadByte(); - } - - protected virtual float readShortInlineR(Instruction instr) { - return reader.ReadSingle(); - } - - protected virtual VariableDefinition readShortInlineVar(Instruction instr) { - return Locals[reader.ReadByte()]; - } - - protected virtual ParameterDefinition readShortInlineArg(Instruction instr) { - return parameters[reader.ReadByte()]; - } - - OpCode readOpCode() { - var op = reader.ReadByte(); - if (op != 0xFE) - return OpCodes.OneByteOpCode[op]; - return OpCodes.TwoBytesOpCode[reader.ReadByte()]; - } - - protected void readExceptionHandlers(int numExceptionHandlers) { - ExceptionHandlers = new ExceptionHandler[numExceptionHandlers]; - for (int i = 0; i < ExceptionHandlers.Count; i++) - ExceptionHandlers[i] = readExceptionHandler(); - } - - protected abstract ExceptionHandler readExceptionHandler(); - - public virtual void restoreMethod(MethodDefinition method) { - var body = method.Body; - - body.Variables.Clear(); - if (Locals != null) { - foreach (var local in Locals) - body.Variables.Add(local); - } - - body.Instructions.Clear(); - if (Instructions != null) { - foreach (var instr in Instructions) - body.Instructions.Add(instr); - } - - body.ExceptionHandlers.Clear(); - if (ExceptionHandlers != null) { - foreach (var eh in ExceptionHandlers) - body.ExceptionHandlers.Add(eh); - } - } - } -} diff --git a/de4dot.code/deobfuscators/MethodCallRestorerBase.cs b/de4dot.code/deobfuscators/MethodCallRestorerBase.cs index 6fd39010..dead9901 100644 --- a/de4dot.code/deobfuscators/MethodCallRestorerBase.cs +++ b/de4dot.code/deobfuscators/MethodCallRestorerBase.cs @@ -18,32 +18,32 @@ */ 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 { class MethodCallRestorerBase { protected MemberReferenceBuilder builder; - protected ModuleDefinition module; + protected ModuleDefMD module; MethodDefinitionAndDeclaringTypeDict oldToNewMethod = new MethodDefinitionAndDeclaringTypeDict(); class NewMethodInfo { public OpCode opCode; - public MethodReference method; + public IMethod method; - public NewMethodInfo(OpCode opCode, MethodReference method) { + public NewMethodInfo(OpCode opCode, IMethod method) { this.opCode = opCode; this.method = method; } } - public MethodCallRestorerBase(ModuleDefinition module) { + public MethodCallRestorerBase(ModuleDefMD module) { this.module = module; this.builder = new MemberReferenceBuilder(module); } - public void createGetManifestResourceStream1(MethodDefinition oldMethod) { + public void createGetManifestResourceStream1(MethodDef oldMethod) { if (oldMethod == null) return; var assemblyType = builder.type("System.Reflection", "Assembly", builder.CorLib); @@ -52,7 +52,7 @@ namespace de4dot.code.deobfuscators { add(oldMethod, newMethod, OpCodes.Callvirt); } - public void createGetManifestResourceStream2(MethodDefinition oldMethod) { + public void createGetManifestResourceStream2(MethodDef oldMethod) { if (oldMethod == null) return; var assemblyType = builder.type("System.Reflection", "Assembly", builder.CorLib); @@ -62,7 +62,7 @@ namespace de4dot.code.deobfuscators { add(oldMethod, newMethod, OpCodes.Callvirt); } - public void createGetManifestResourceNames(MethodDefinition oldMethod) { + public void createGetManifestResourceNames(MethodDef oldMethod) { if (oldMethod == null) return; var assemblyType = builder.type("System.Reflection", "Assembly", builder.CorLib); @@ -71,7 +71,7 @@ namespace de4dot.code.deobfuscators { add(oldMethod, newMethod, OpCodes.Callvirt); } - public void createBitmapCtor(MethodDefinition oldMethod) { + public void createBitmapCtor(MethodDef oldMethod) { if (oldMethod == null) return; var bitmapType = builder.type("System.Drawing", "Bitmap", "System.Drawing"); @@ -80,7 +80,7 @@ namespace de4dot.code.deobfuscators { add(oldMethod, newMethod, OpCodes.Newobj); } - public void createIconCtor(MethodDefinition oldMethod) { + public void createIconCtor(MethodDef oldMethod) { if (oldMethod == null) return; var iconType = builder.type("System.Drawing", "Icon", "System.Drawing"); @@ -89,11 +89,11 @@ namespace de4dot.code.deobfuscators { add(oldMethod, newMethod, OpCodes.Newobj); } - protected void add(MethodDefinition oldMethod, MethodReference newMethod) { + protected void add(MethodDef oldMethod, IMethod newMethod) { add(oldMethod, newMethod, OpCodes.Callvirt); } - protected void add(MethodDefinition oldMethod, MethodReference newMethod, OpCode opCode) { + protected void add(MethodDef oldMethod, IMethod newMethod, OpCode opCode) { if (oldMethod == null) return; oldToNewMethod.add(oldMethod, new NewMethodInfo(opCode, newMethod)); @@ -106,7 +106,7 @@ namespace de4dot.code.deobfuscators { var call = instrs[i]; if (call.OpCode.Code != Code.Call) continue; - var calledMethod = call.Operand as MethodDefinition; + var calledMethod = call.Operand as MethodDef; if (calledMethod == null) continue; diff --git a/de4dot.code/deobfuscators/MethodStack.cs b/de4dot.code/deobfuscators/MethodStack.cs index e4280bbb..3979c93a 100644 --- a/de4dot.code/deobfuscators/MethodStack.cs +++ b/de4dot.code/deobfuscators/MethodStack.cs @@ -18,8 +18,8 @@ */ 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 { @@ -79,7 +79,7 @@ namespace de4dot.code.deobfuscators { public static PushedArgs getPushedArgInstructions(IList instructions, int index) { try { int pushes, pops; - DotNetUtils.calculateStackUsage(instructions[index], false, out pushes, out pops); + instructions[index].CalculateStackUsage(false, out pushes, out pops); if (pops != -1) return getPushedArgInstructions(instructions, index, pops); } @@ -101,7 +101,7 @@ namespace de4dot.code.deobfuscators { break; int pushes, pops; - DotNetUtils.calculateStackUsage(instr, false, out pushes, out pops); + instr.CalculateStackUsage(false, out pushes, out pops); if (pops == -1) break; if (instr.OpCode.Code == Code.Dup) { @@ -128,7 +128,7 @@ namespace de4dot.code.deobfuscators { instr = getPreviousInstruction(instructions, ref index); if (instr != null) { int pushes, pops; - DotNetUtils.calculateStackUsage(instr, false, out pushes, out pops); + instr.CalculateStackUsage(false, out pushes, out pops); if (pushes == 1 && pops == 0) pushedArgs.set(0, instr); } @@ -138,96 +138,97 @@ namespace de4dot.code.deobfuscators { return pushedArgs; } - public static TypeReference getLoadedType(MethodDefinition method, IList instructions, int instrIndex) { + public static TypeSig getLoadedType(MethodDef method, IList instructions, int instrIndex) { bool wasNewobj; return getLoadedType(method, instructions, instrIndex, 0, out wasNewobj); } - public static TypeReference getLoadedType(MethodDefinition method, IList instructions, int instrIndex, int argIndexFromEnd) { + public static TypeSig getLoadedType(MethodDef method, IList instructions, int instrIndex, int argIndexFromEnd) { bool wasNewobj; return getLoadedType(method, instructions, instrIndex, argIndexFromEnd, out wasNewobj); } - public static TypeReference getLoadedType(MethodDefinition method, IList instructions, int instrIndex, out bool wasNewobj) { + public static TypeSig getLoadedType(MethodDef method, IList instructions, int instrIndex, out bool wasNewobj) { return getLoadedType(method, instructions, instrIndex, 0, out wasNewobj); } - public static TypeReference getLoadedType(MethodDefinition method, IList instructions, int instrIndex, int argIndexFromEnd, out bool wasNewobj) { + public static TypeSig getLoadedType(MethodDef method, IList instructions, int instrIndex, int argIndexFromEnd, out bool wasNewobj) { wasNewobj = false; var pushedArgs = MethodStack.getPushedArgInstructions(instructions, instrIndex); var pushInstr = pushedArgs.getEnd(argIndexFromEnd); if (pushInstr == null) return null; - TypeReference type; - VariableDefinition local; + TypeSig type; + Local local; + var corLibTypes = method.DeclaringType.OwnerModule.CorLibTypes; switch (pushInstr.OpCode.Code) { case Code.Ldstr: - type = method.Module.TypeSystem.String; + type = corLibTypes.String; break; case Code.Conv_I: case Code.Conv_Ovf_I: case Code.Conv_Ovf_I_Un: - type = method.Module.TypeSystem.IntPtr; + type = corLibTypes.IntPtr; break; case Code.Conv_U: case Code.Conv_Ovf_U: case Code.Conv_Ovf_U_Un: - type = method.Module.TypeSystem.UIntPtr; + type = corLibTypes.UIntPtr; break; case Code.Conv_I8: case Code.Conv_Ovf_I8: case Code.Conv_Ovf_I8_Un: - type = method.Module.TypeSystem.Int64; + type = corLibTypes.Int64; break; case Code.Conv_U8: case Code.Conv_Ovf_U8: case Code.Conv_Ovf_U8_Un: - type = method.Module.TypeSystem.UInt64; + type = corLibTypes.UInt64; break; case Code.Conv_R8: case Code.Ldc_R8: case Code.Ldelem_R8: case Code.Ldind_R8: - type = method.Module.TypeSystem.Double; + type = corLibTypes.Double; break; case Code.Call: case Code.Calli: case Code.Callvirt: - var calledMethod = pushInstr.Operand as MethodReference; + var calledMethod = pushInstr.Operand as IMethod; if (calledMethod == null) return null; - type = calledMethod.MethodReturnType.ReturnType; + type = calledMethod.MethodSig.RetType; break; case Code.Newarr: - type = pushInstr.Operand as TypeReference; - if (type == null) + var type2 = pushInstr.Operand as ITypeDefOrRef; + if (type2 == null) return null; - type = new ArrayType(type); + type = new SZArraySig(type2.ToTypeSig()); wasNewobj = true; break; case Code.Newobj: - var ctor = pushInstr.Operand as MethodReference; + var ctor = pushInstr.Operand as IMethod; if (ctor == null) return null; - type = ctor.DeclaringType; + type = ctor.DeclaringType.ToTypeSig(); wasNewobj = true; break; case Code.Castclass: case Code.Isinst: case Code.Unbox_Any: - case Code.Ldelem_Any: + case Code.Ldelem: case Code.Ldobj: - type = pushInstr.Operand as TypeReference; + type = (pushInstr.Operand as ITypeDefOrRef).ToTypeSig(); break; case Code.Ldarg: @@ -236,7 +237,7 @@ namespace de4dot.code.deobfuscators { case Code.Ldarg_1: case Code.Ldarg_2: case Code.Ldarg_3: - type = DotNetUtils.getArgType(method, pushInstr); + type = pushInstr.GetArgumentType(method.MethodSig, method.DeclaringType); break; case Code.Ldloc: @@ -245,44 +246,44 @@ namespace de4dot.code.deobfuscators { case Code.Ldloc_1: case Code.Ldloc_2: case Code.Ldloc_3: - local = DotNetUtils.getLocalVar(method.Body.Variables, pushInstr); + local = pushInstr.GetLocal(method.CilBody.LocalList); if (local == null) return null; - type = local.VariableType; + type = local.Type.RemovePinned(); break; case Code.Ldloca: case Code.Ldloca_S: - local = pushInstr.Operand as VariableDefinition; + local = pushInstr.Operand as Local; if (local == null) return null; - type = createByReferenceType(local.VariableType); + type = createByReferenceType(local.Type.RemovePinned()); break; case Code.Ldarga: case Code.Ldarga_S: - type = createByReferenceType(DotNetUtils.getArgType(method, pushInstr)); + type = createByReferenceType(pushInstr.GetArgumentType(method.MethodSig, method.DeclaringType)); break; case Code.Ldfld: case Code.Ldsfld: - var field = pushInstr.Operand as FieldReference; - if (field == null) + var field = pushInstr.Operand as IField; + if (field == null || field.FieldSig == null) return null; - type = field.FieldType; + type = field.FieldSig.Type; break; case Code.Ldflda: case Code.Ldsflda: - var field2 = pushInstr.Operand as FieldReference; - if (field2 == null) + var field2 = pushInstr.Operand as IField; + if (field2 == null || field2.FieldSig == null) return null; - type = createByReferenceType(field2.FieldType); + type = createByReferenceType(field2.FieldSig.Type); break; case Code.Ldelema: case Code.Unbox: - type = createByReferenceType(pushInstr.Operand as TypeReference); + type = createByReferenceType(pushInstr.Operand as ITypeDefOrRef); break; default: @@ -292,10 +293,16 @@ namespace de4dot.code.deobfuscators { return type; } - static ByReferenceType createByReferenceType(TypeReference elementType) { + static ByRefSig createByReferenceType(ITypeDefOrRef elementType) { if (elementType == null) return null; - return new ByReferenceType(elementType); + return new ByRefSig(elementType.ToTypeSig()); + } + + static ByRefSig createByReferenceType(TypeSig elementType) { + if (elementType == null) + return null; + return new ByRefSig(elementType); } static Instruction getPreviousInstruction(IList instructions, ref int instrIndex) { diff --git a/de4dot.code/deobfuscators/MethodsDecrypter.cs b/de4dot.code/deobfuscators/MethodsDecrypter.cs index 82441ff7..7267a356 100644 --- a/de4dot.code/deobfuscators/MethodsDecrypter.cs +++ b/de4dot.code/deobfuscators/MethodsDecrypter.cs @@ -17,7 +17,7 @@ along with de4dot. If not, see . */ -using Mono.MyStuff; +using dot10.DotNet; using de4dot.code.AssemblyClient; using de4dot.mdecrypt; diff --git a/de4dot.code/deobfuscators/StringCounts.cs b/de4dot.code/deobfuscators/StringCounts.cs index 130c439f..96580e5b 100644 --- a/de4dot.code/deobfuscators/StringCounts.cs +++ b/de4dot.code/deobfuscators/StringCounts.cs @@ -19,8 +19,8 @@ using System; using System.Collections.Generic; -using Mono.Cecil; -using Mono.Cecil.Cil; +using dot10.DotNet; +using dot10.DotNet.Emit; namespace de4dot.code.deobfuscators { class StringCounts { @@ -66,37 +66,37 @@ namespace de4dot.code.deobfuscators { } class FieldTypes : StringCounts { - public FieldTypes(TypeDefinition type) { + public FieldTypes(TypeDef type) { init(type.Fields); } - public FieldTypes(IEnumerable fields) { + public FieldTypes(IEnumerable fields) { init(fields); } - void init(IEnumerable fields) { + void init(IEnumerable fields) { if (fields == null) return; foreach (var field in fields) - add(field.FieldType.FullName); + add(field.FieldSig.Type.FullName); } } class LocalTypes : StringCounts { - public LocalTypes(MethodDefinition method) { - if (method != null && method.Body != null) - init(method.Body.Variables); + public LocalTypes(MethodDef method) { + if (method != null && method.CilBody != null) + init(method.CilBody.LocalList); } - public LocalTypes(IEnumerable locals) { + public LocalTypes(IEnumerable locals) { init(locals); } - void init(IEnumerable locals) { + void init(IEnumerable locals) { if (locals == null) return; foreach (var local in locals) - add(local.VariableType.FullName); + add(local.Type.FullName); } } } diff --git a/de4dot.code/deobfuscators/TypesRestorer.cs b/de4dot.code/deobfuscators/TypesRestorer.cs index 147d8ebc..d55fbf0b 100644 --- a/de4dot.code/deobfuscators/TypesRestorer.cs +++ b/de4dot.code/deobfuscators/TypesRestorer.cs @@ -186,7 +186,7 @@ namespace de4dot.code.deobfuscators { return; Log.v("Changing field types to real type"); - fields.Sort((a, b) => Utils.compareInt32(a.token, b.token)); + fields.Sort((a, b) => a.token.CompareTo(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.MDToken.ToInt32()); @@ -199,7 +199,7 @@ namespace de4dot.code.deobfuscators { return; Log.v("Changing method args and return types to real type"); - methods.Sort((a, b) => Utils.compareInt32(a.token, b.token)); + methods.Sort((a, b) => a.token.CompareTo(b.token)); Log.indent(); foreach (var updatedMethod in methods) { Log.v("Method {0:X8}", updatedMethod.token); @@ -250,7 +250,7 @@ namespace de4dot.code.deobfuscators { 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); + return a.arg.Sequence.CompareTo(b.arg.Sequence); } void deobfuscateMethod(MethodDef method) { diff --git a/de4dot.code/deobfuscators/ValueInlinerBase.cs b/de4dot.code/deobfuscators/ValueInlinerBase.cs index 1ad85168..c382259c 100644 --- a/de4dot.code/deobfuscators/ValueInlinerBase.cs +++ b/de4dot.code/deobfuscators/ValueInlinerBase.cs @@ -19,19 +19,19 @@ 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 ValueInlinerBase : MethodReturnValueInliner { - MethodDefinitionAndDeclaringTypeDict> decrypterMethods = new MethodDefinitionAndDeclaringTypeDict>(); + MethodDefinitionAndDeclaringTypeDict> decrypterMethods = new MethodDefinitionAndDeclaringTypeDict>(); bool removeUnbox = false; class MyCallResult : CallResult { - public MethodReference methodReference; - public GenericInstanceMethod gim; - public MyCallResult(Block block, int callEndIndex, MethodReference method, GenericInstanceMethod gim) + public IMethod methodReference; + public MethodSpec gim; + public MyCallResult(Block block, int callEndIndex, IMethod method, MethodSpec gim) : base(block, callEndIndex) { this.methodReference = method; this.gim = gim; @@ -47,15 +47,15 @@ namespace de4dot.code.deobfuscators { get { return decrypterMethods.Count != 0; } } - public IEnumerable Methods { + public IEnumerable Methods { get { return decrypterMethods.getKeys(); } } - public void add(MethodDefinition method, Func handler) { + public void add(MethodDef method, Func handler) { if (method == null) return; if (decrypterMethods.find(method) != null) - throw new ApplicationException(string.Format("Handler for method {0:X8} has already been added", method.MetadataToken.ToInt32())); + throw new ApplicationException(string.Format("Handler for method {0:X8} has already been added", method.MDToken.ToInt32())); if (method != null) decrypterMethods.add(method, handler); } @@ -64,11 +64,11 @@ namespace de4dot.code.deobfuscators { foreach (var tmp in callResults) { var callResult = (MyCallResult)tmp; var handler = decrypterMethods.find(callResult.methodReference); - callResult.returnValue = handler((MethodDefinition)callResult.methodReference, callResult.gim, callResult.args); + callResult.returnValue = handler((MethodDef)callResult.methodReference, callResult.gim, callResult.args); } } - protected override CallResult createCallResult(MethodReference method, GenericInstanceMethod gim, Block block, int callInstrIndex) { + protected override CallResult createCallResult(IMethod method, MethodSpec gim, Block block, int callInstrIndex) { if (decrypterMethods.find(method) == null) return null; return new MyCallResult(block, callInstrIndex, method, gim); @@ -83,7 +83,7 @@ namespace de4dot.code.deobfuscators { var unbox = instrs[index]; if (unbox.OpCode.Code != Code.Unbox_Any) return false; - var type = unbox.Operand as TypeReference; + var type = unbox.Operand as ITypeDefOrRef; if (type == null || type.FullName != unboxType) return false; block.remove(index, 1); @@ -97,7 +97,7 @@ namespace de4dot.code.deobfuscators { var block = callResult.block; int num = callResult.callEndIndex - callResult.callStartIndex + 1; - block.replace(callResult.callStartIndex, num, DotNetUtils.createLdci4((bool)callResult.returnValue ? 1 : 0)); + block.replace(callResult.callStartIndex, num, Instruction.CreateLdcI4((bool)callResult.returnValue ? 1 : 0)); removeUnboxInstruction(block, callResult.callStartIndex + 1, "System.Boolean"); Log.v("Decrypted boolean: {0}", callResult.returnValue); } @@ -110,7 +110,7 @@ namespace de4dot.code.deobfuscators { var block = callResult.block; int num = callResult.callEndIndex - callResult.callStartIndex + 1; - block.replace(callResult.callStartIndex, num, DotNetUtils.createLdci4((int)callResult.returnValue)); + block.replace(callResult.callStartIndex, num, Instruction.CreateLdcI4((int)callResult.returnValue)); removeUnboxInstruction(block, callResult.callStartIndex + 1, "System.Int32"); Log.v("Decrypted int32: {0}", callResult.returnValue); } diff --git a/de4dot.code/resources/ResourceDataCreator.cs b/de4dot.code/resources/ResourceDataCreator.cs index a00278da..8269c860 100644 --- a/de4dot.code/resources/ResourceDataCreator.cs +++ b/de4dot.code/resources/ResourceDataCreator.cs @@ -227,7 +227,7 @@ namespace de4dot.code.resources { public List getSortedTypes() { var list = new List(dict.Values); - list.Sort((a, b) => Utils.compareInt32((int)a.Code, (int)b.Code)); + list.Sort((a, b) => ((int)a.Code).CompareTo((int)b.Code)); return list; } } diff --git a/de4dot.code/resources/ResourceReader.cs b/de4dot.code/resources/ResourceReader.cs index e56c0746..57806aa6 100644 --- a/de4dot.code/resources/ResourceReader.cs +++ b/de4dot.code/resources/ResourceReader.cs @@ -109,7 +109,7 @@ namespace de4dot.code.resources { } static int sortResourceInfo(ResourceInfo a, ResourceInfo b) { - return Utils.compareInt32((int)a.offset, (int)b.offset); + return ((int)a.offset).CompareTo((int)b.offset); } class ResourceInfo { diff --git a/dot10 b/dot10 index 7eb0fb7e..3b128874 160000 --- a/dot10 +++ b/dot10 @@ -1 +1 @@ -Subproject commit 7eb0fb7e6e47c79eebbef0ea9ea404f9b81fde51 +Subproject commit 3b128874ff6bd531f588c487e9aeb76fb62acfec