diff --git a/blocks/DotNetUtils.cs b/blocks/DotNetUtils.cs index 350f5251..490f5fed 100644 --- a/blocks/DotNetUtils.cs +++ b/blocks/DotNetUtils.cs @@ -404,19 +404,17 @@ namespace de4dot.blocks { return (FieldDefinition)field; return getField(getType(module, field.DeclaringType), field); } +#endif - public static FieldDefinition getField(TypeDefinition type, FieldReference fieldReference) { + public static FieldDef getField(TypeDef type, IField fieldReference) { if (type == null || fieldReference == null) return null; - if (fieldReference is FieldDefinition) - return (FieldDefinition)fieldReference; - foreach (var field in type.Fields) { - if (MemberReferenceHelper.compareFieldReference(field, fieldReference)) - return field; - } - return null; + if (fieldReference is FieldDef) + return (FieldDef)fieldReference; + return type.FindField(fieldReference.Name, fieldReference.FieldSig); } +#if PORT public static FieldDefinition getField(TypeDefinition type, string typeFullName) { if (type == null) return null; @@ -778,7 +776,6 @@ namespace de4dot.blocks { } } -#if PORT public static IList getInstructions(IList instructions, int i, params OpCode[] opcodes) { if (i + opcodes.Length > instructions.Count) return null; @@ -797,6 +794,7 @@ namespace de4dot.blocks { return list; } +#if PORT public static bool hasReturnValue(IMethodSignature method) { var type = method.MethodReturnType.ReturnType; while (type.IsOptionalModifier || type.IsRequiredModifier) diff --git a/de4dot.code/de4dot.code.csproj b/de4dot.code/de4dot.code.csproj index 2480c28d..26c2873a 100644 --- a/de4dot.code/de4dot.code.csproj +++ b/de4dot.code/de4dot.code.csproj @@ -76,22 +76,22 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/de4dot.code/deobfuscators/Babel_NET/AssemblyResolver.cs b/de4dot.code/deobfuscators/Babel_NET/AssemblyResolver.cs index 4ed3d84f..b7078f07 100644 --- a/de4dot.code/deobfuscators/Babel_NET/AssemblyResolver.cs +++ b/de4dot.code/deobfuscators/Babel_NET/AssemblyResolver.cs @@ -19,12 +19,13 @@ using System; using System.IO; +using dot10.IO; using dot10.DotNet; using de4dot.blocks; namespace de4dot.code.deobfuscators.Babel_NET { class AssemblyResolver { - ModuleDefinition module; + ModuleDefMD module; ResourceDecrypter resourceDecrypter; TypeDef resolverType; MethodDef registerMethod; @@ -63,7 +64,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { get { return embeddedAssemblyInfos; } } - public AssemblyResolver(ModuleDefinition module, ResourceDecrypter resourceDecrypter) { + public AssemblyResolver(ModuleDefMD module, ResourceDecrypter resourceDecrypter) { this.module = module; this.resourceDecrypter = resourceDecrypter; } @@ -114,14 +115,14 @@ namespace de4dot.code.deobfuscators.Babel_NET { return; } - var decrypted = resourceDecrypter.decrypt(encryptedResource.GetResourceData()); + var decrypted = resourceDecrypter.decrypt(encryptedResource.Data.ReadAllBytes()); var reader = new BinaryReader(new MemoryStream(decrypted)); int numAssemblies = reader.ReadInt32(); embeddedAssemblyInfos = new EmbeddedAssemblyInfo[numAssemblies]; for (int i = 0; i < numAssemblies; i++) { string name = reader.ReadString(); var data = reader.ReadBytes(reader.ReadInt32()); - var mod = ModuleDefinition.ReadModule(new MemoryStream(data)); + var mod = ModuleDefMD.Load(data); embeddedAssemblyInfos[i] = new EmbeddedAssemblyInfo(name, DeobUtils.getExtension(mod.Kind), data); } } diff --git a/de4dot.code/deobfuscators/Babel_NET/BabelMethodCallInliner.cs b/de4dot.code/deobfuscators/Babel_NET/BabelMethodCallInliner.cs index b90c7ea9..c6755377 100644 --- a/de4dot.code/deobfuscators/Babel_NET/BabelMethodCallInliner.cs +++ b/de4dot.code/deobfuscators/Babel_NET/BabelMethodCallInliner.cs @@ -35,7 +35,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { branchEmulator = new BranchEmulator(emulator, this); } - public static List find(ModuleDefinition module, IEnumerable notInlinedMethods) { + public static List find(ModuleDefMD module, IEnumerable notInlinedMethods) { var notInlinedMethodsDict = new Dictionary(); foreach (var method in notInlinedMethods) notInlinedMethodsDict[method] = true; @@ -88,7 +88,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { return false; if (!method.IsAssembly) return false; - if (method.GenericParameters.Count > 0) + if (method.MethodSig.GetGenParamCount() > 0) return false; return method.IsStatic; @@ -233,8 +233,8 @@ namespace de4dot.code.deobfuscators.Babel_NET { } } - protected override bool isCompatibleType(int paramIndex, TypeReference origType, TypeReference newType) { - if (MemberReferenceHelper.compareTypes(origType, newType)) + protected override bool isCompatibleType(int paramIndex, IType origType, IType newType) { + if (new SigComparer().Equals(origType, newType)) return true; if (newType.IsValueType || origType.IsValueType) return false; diff --git a/de4dot.code/deobfuscators/Babel_NET/BabelUtils.cs b/de4dot.code/deobfuscators/Babel_NET/BabelUtils.cs index 6bd04a1c..c216959e 100644 --- a/de4dot.code/deobfuscators/Babel_NET/BabelUtils.cs +++ b/de4dot.code/deobfuscators/Babel_NET/BabelUtils.cs @@ -25,18 +25,18 @@ using de4dot.blocks; namespace de4dot.code.deobfuscators.Babel_NET { static class BabelUtils { - public static EmbeddedResource findEmbeddedResource(ModuleDefinition module, TypeDef decrypterType) { + public static EmbeddedResource findEmbeddedResource(ModuleDefMD module, TypeDef decrypterType) { return findEmbeddedResource(module, decrypterType, (method) => { }); } - public static EmbeddedResource findEmbeddedResource(ModuleDefinition module, TypeDef decrypterType, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) { + public static EmbeddedResource findEmbeddedResource(ModuleDefMD module, TypeDef decrypterType, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) { return findEmbeddedResource(module, decrypterType, (method) => { simpleDeobfuscator.deobfuscate(method); simpleDeobfuscator.decryptStrings(method, deob); }); } - public static EmbeddedResource findEmbeddedResource(ModuleDefinition module, TypeDef decrypterType, Action fixMethod) { + public static EmbeddedResource findEmbeddedResource(ModuleDefMD module, TypeDef decrypterType, Action fixMethod) { foreach (var method in decrypterType.Methods) { if (!DotNetUtils.isMethod(method, "System.String", "()")) continue; @@ -50,7 +50,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { return null; } - static EmbeddedResource findEmbeddedResource1(ModuleDefinition module, MethodDef method) { + static EmbeddedResource findEmbeddedResource1(ModuleDefMD module, MethodDef method) { foreach (var s in DotNetUtils.getCodeStrings(method)) { var resource = DotNetUtils.getResource(module, s) as EmbeddedResource; if (resource != null) @@ -59,7 +59,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { return null; } - static EmbeddedResource findEmbeddedResource2(ModuleDefinition module, MethodDef method) { + static EmbeddedResource findEmbeddedResource2(ModuleDefMD module, MethodDef method) { var strings = new List(DotNetUtils.getCodeStrings(method)); if (strings.Count != 1) return null; @@ -83,13 +83,13 @@ namespace de4dot.code.deobfuscators.Babel_NET { continue; var ldci4 = instrs[i + 1]; - if (!DotNetUtils.isLdcI4(ldci4)) + if (!ldci4.IsLdcI4()) continue; if (instrs[i + 2].OpCode.Code != Code.Xor) continue; - xorKey = DotNetUtils.getLdcI4Value(ldci4); + xorKey = ldci4.GetLdcI4Value(); return true; } @@ -107,12 +107,12 @@ namespace de4dot.code.deobfuscators.Babel_NET { foreach (var instr in method.Body.Instructions) { if (instr.OpCode.Code != Code.Ldftn) continue; - var handlerRef = instr.Operand as MethodReference; + var handlerRef = instr.Operand as IMethod; if (handlerRef == null) continue; if (!DotNetUtils.isMethod(handlerRef, "System.Reflection.Assembly", "(System.Object,System.ResolveEventArgs)")) continue; - if (!MemberReferenceHelper.compareTypes(type, handlerRef.DeclaringType)) + if (!new SigComparer().Equals(type, handlerRef.DeclaringType)) continue; handler = DotNetUtils.getMethod(type, handlerRef); if (handler == null) diff --git a/de4dot.code/deobfuscators/Babel_NET/ConstantsDecrypter.cs b/de4dot.code/deobfuscators/Babel_NET/ConstantsDecrypter.cs index 2c7bcca7..b9a9c4e1 100644 --- a/de4dot.code/deobfuscators/Babel_NET/ConstantsDecrypter.cs +++ b/de4dot.code/deobfuscators/Babel_NET/ConstantsDecrypter.cs @@ -21,13 +21,14 @@ using System; using System.Collections.Generic; using System.IO; using System.Runtime.Serialization.Formatters.Binary; +using dot10.IO; using dot10.DotNet; using dot10.DotNet.Emit; using de4dot.blocks; namespace de4dot.code.deobfuscators.Babel_NET { class ConstantsDecrypter { - ModuleDefinition module; + ModuleDefMD module; ResourceDecrypter resourceDecrypter; InitializedDataCreator initializedDataCreator; TypeDef decrypterType; @@ -78,7 +79,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { get { return arrayDecrypter; } } - public ConstantsDecrypter(ModuleDefinition module, ResourceDecrypter resourceDecrypter, InitializedDataCreator initializedDataCreator) { + public ConstantsDecrypter(ModuleDefMD module, ResourceDecrypter resourceDecrypter, InitializedDataCreator initializedDataCreator) { this.module = module; this.resourceDecrypter = resourceDecrypter; this.initializedDataCreator = initializedDataCreator; @@ -109,7 +110,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { if (!checkNestedFields(nested)) return false; - resourceDecrypter.DecryptMethod = ResourceDecrypter.findDecrypterMethod(DotNetUtils.getMethod(nested, ".ctor")); + resourceDecrypter.DecryptMethod = ResourceDecrypter.findDecrypterMethod(nested.FindMethod(".ctor")); if (DotNetUtils.getMethod(type, "System.Int32", "(System.Int32)") == null) return false; @@ -135,7 +136,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { if (!new FieldTypes(nested).all(requiredTypes)) return false; foreach (var field in nested.Fields) { - if (MemberReferenceHelper.compareTypes(nested, field.FieldType)) + if (new SigComparer().Equals(nested, field.FieldSig.GetFieldType())) return true; } return false; @@ -151,7 +152,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { return; } - var decrypted = resourceDecrypter.decrypt(encryptedResource.GetResourceData()); + var decrypted = resourceDecrypter.decrypt(encryptedResource.Data.ReadAllBytes()); var reader = new BinaryReader(new MemoryStream(decrypted)); int count; @@ -194,10 +195,10 @@ namespace de4dot.code.deobfuscators.Babel_NET { struct ArrayInfo { public FieldDef encryptedField; - public ArrayType arrayType; + public SZArraySig arrayType; public int start, len; - public ArrayInfo(int start, int len, FieldDef encryptedField, ArrayType arrayType) { + public ArrayInfo(int start, int len, FieldDef encryptedField, SZArraySig arrayType) { this.start = start; this.len = len; this.encryptedField = encryptedField; @@ -239,23 +240,23 @@ namespace de4dot.code.deobfuscators.Babel_NET { var call1 = instrs[index++]; if (call1.OpCode.Code != Code.Call && call1.OpCode.Code != Code.Callvirt) continue; - if (!DotNetUtils.isMethod(call1.Operand as MethodReference, "System.Void", "(System.Array,System.RuntimeFieldHandle)")) + if (!DotNetUtils.isMethod(call1.Operand as IMethod, "System.Void", "(System.Array,System.RuntimeFieldHandle)")) continue; var call2 = instrs[index++]; if (call2.OpCode.Code != Code.Call && call2.OpCode.Code != Code.Callvirt) continue; - if (!MemberReferenceHelper.compareMethodReferenceAndDeclaringType(call2.Operand as MethodReference, arrayDecrypter)) + if (!MethodEqualityComparer.CompareDeclaringTypes.Equals(call2.Operand as IMethod, arrayDecrypter)) continue; var castclass = instrs[index++]; if (castclass.OpCode.Code != Code.Castclass) continue; - var arrayType = castclass.Operand as ArrayType; + var arrayType = (castclass.Operand as ITypeDefOrRef).ToSZArraySig(); if (arrayType == null) continue; - if (arrayType.ElementType.GetPrimitiveSize() == -1) { - Log.w("Can't decrypt non-primitive type array in method {0}", blocks.Method.MDToken.ToInt32()); + if (arrayType.Next.ElementType.GetPrimitiveSize() == -1) { + Log.w("Can't decrypt non-primitive type array in method {0:X8}", blocks.Method.MDToken.ToInt32()); continue; } @@ -264,11 +265,11 @@ namespace de4dot.code.deobfuscators.Babel_NET { infos.Reverse(); foreach (var info in infos) { - var elemSize = info.arrayType.ElementType.GetPrimitiveSize(); + var elemSize = info.arrayType.Next.ElementType.GetPrimitiveSize(); var decrypted = decryptArray(info.encryptedField.InitialValue, elemSize); - initializedDataCreator.addInitializeArrayCode(block, info.start, info.len, info.arrayType.ElementType, decrypted); - Log.v("Decrypted {0} array: {1} elements", info.arrayType.ElementType.ToString(), decrypted.Length / elemSize); + initializedDataCreator.addInitializeArrayCode(block, info.start, info.len, info.arrayType.Next.ToTypeDefOrRef(), decrypted); + Log.v("Decrypted {0} array: {1} elements", info.arrayType.Next.ToString(), decrypted.Length / elemSize); } } } diff --git a/de4dot.code/deobfuscators/Babel_NET/Deobfuscator.cs b/de4dot.code/deobfuscators/Babel_NET/Deobfuscator.cs index 806d8a90..4e7b4ab1 100644 --- a/de4dot.code/deobfuscators/Babel_NET/Deobfuscator.cs +++ b/de4dot.code/deobfuscators/Babel_NET/Deobfuscator.cs @@ -132,7 +132,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { this.options = options; } - public override void init(ModuleDefinition module) { + public override void init(ModuleDefMD module) { base.init(module); } @@ -183,9 +183,9 @@ namespace de4dot.code.deobfuscators.Babel_NET { } void checkVersion(TypeDef attr) { - var versionField = DotNetUtils.getFieldByName(attr, "Version"); - if (versionField != null && versionField.IsLiteral && versionField.Constant != null && versionField.Constant is string) { - var val = Regex.Match((string)versionField.Constant, @"^(\d+\.\d+\.\d+\.\d+)$"); + var versionField = attr.FindField("Version"); + if (versionField != null && versionField.IsLiteral && versionField.Constant != null && versionField.Constant.Value is string) { + var val = Regex.Match((string)versionField.Constant.Value, @"^(\d+\.\d+\.\d+\.\d+)$"); if (val.Groups.Count < 2) return; obfuscatorName = string.Format("{0} {1}", DeobfuscatorInfo.THE_NAME, val.Groups[1].ToString()); diff --git a/de4dot.code/deobfuscators/Babel_NET/ImageReader.cs b/de4dot.code/deobfuscators/Babel_NET/ImageReader.cs index c2ef95c9..cd9d623d 100644 --- a/de4dot.code/deobfuscators/Babel_NET/ImageReader.cs +++ b/de4dot.code/deobfuscators/Babel_NET/ImageReader.cs @@ -22,10 +22,14 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.IO; using System.Text; +using dot10.IO; using dot10.DotNet; using dot10.DotNet.Emit; using de4dot.blocks; +using CR = System.Runtime.InteropServices; +using DR = dot10.DotNet; + namespace de4dot.code.deobfuscators.Babel_NET { class ImageReader { static int METHODS_SIG = 0x0000BEBA; @@ -43,19 +47,19 @@ namespace de4dot.code.deobfuscators.Babel_NET { ByRef = 4, } - ModuleDefinition module; - BinaryReader reader; + ModuleDefMD module; + IBinaryReader reader; string[] strings; - AssemblyNameReference[] assemblyNames; + AssemblyRef[] assemblyNames; Dictionary methodOffsets; - List typeReferences; + List typeReferences; MemberReferenceConverter memberReferenceConverter; IDeobfuscatorContext deobfuscatorContext; - public ImageReader(IDeobfuscatorContext deobfuscatorContext, ModuleDefinition module, byte[] data) { + public ImageReader(IDeobfuscatorContext deobfuscatorContext, ModuleDefMD module, byte[] data) { this.deobfuscatorContext = deobfuscatorContext; this.module = module; - this.reader = new BinaryReader(new MemoryStream(data)); + this.reader = MemoryImageStream.Create(data); this.memberReferenceConverter = new MemberReferenceConverter(module); } @@ -67,14 +71,14 @@ namespace de4dot.code.deobfuscators.Babel_NET { if (metadataOffset < 0) return false; long pos = metadataOffset + 4; - reader.BaseStream.Position = pos; + reader.Position = pos; int version = reader.ReadInt16(); // major, minor if (version == 0x0001) { initializeV10(); return true; } - reader.BaseStream.Position = pos; + reader.Position = pos; initializeV55(); return true; } @@ -108,18 +112,18 @@ namespace de4dot.code.deobfuscators.Babel_NET { var babelMethod = getMethod(name); var body = method.Body; - body.MaxStackSize = babelMethod.MaxStack; + body.MaxStack = babelMethod.MaxStack; body.InitLocals = babelMethod.InitLocals; - body.Variables.Clear(); + body.LocalList.Clear(); foreach (var local in babelMethod.Locals) - body.Variables.Add(local); + body.LocalList.Add(local); var toNewOperand = new Dictionary(); if (babelMethod.ThisParameter != null) - toNewOperand[babelMethod.ThisParameter] = body.ThisParameter; - for (int i = 0; i < method.Parameters.Count; i++) - toNewOperand[babelMethod.Parameters[i]] = method.Parameters[i]; + toNewOperand[babelMethod.ThisParameter] = method.Parameters[0]; + for (int i = 0; i < babelMethod.Parameters.Length; i++) + toNewOperand[babelMethod.Parameters[i]] = method.Parameters[i + method.Parameters.MethodSigIndexBase]; body.Instructions.Clear(); foreach (var instr in babelMethod.Instructions) { @@ -137,7 +141,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { BabelMethodDefinition getMethod(string name) { int offset = methodOffsets[name]; methodOffsets.Remove(name); - reader.BaseStream.Position = offset; + reader.Position = offset; return new MethodDefinitionReader(this, reader).read(); } @@ -145,20 +149,20 @@ namespace de4dot.code.deobfuscators.Babel_NET { return strings[readVariableLengthInt32()]; } - public TypeReference readTypeReference() { + public TypeSig readTypeSig() { return typeReferences[readVariableLengthInt32()]; } - public TypeReference[] readTypeReferences() { - var refs = new TypeReference[readVariableLengthInt32()]; + public TypeSig[] readTypeSigs() { + var refs = new TypeSig[readVariableLengthInt32()]; for (int i = 0; i < refs.Length; i++) - refs[i] = readTypeReference(); + refs[i] = readTypeSig(); return refs; } - public FieldReference readFieldReference() { + public IField readFieldReference() { var name = readString(); - var declaringType = readTypeReference(); + var declaringType = readTypeSig(); var fields = getFields(resolve(declaringType), name); if (fields == null || fields.Count != 1) { @@ -173,15 +177,10 @@ namespace de4dot.code.deobfuscators.Babel_NET { static List getFields(TypeDef type, string name) { if (type == null) return null; - var fields = new List(); - foreach (var field in type.Fields) { - if (field.Name == name) - fields.Add(field); - } - return fields; + return new List(type.FindFields(name)); } - public MethodReference readMethodReference() { + public IMethod readMethodReference() { var babelMethodRef = new MethodReferenceReader(this, reader).read(); var method = getMethodReference(babelMethodRef); @@ -191,16 +190,15 @@ namespace de4dot.code.deobfuscators.Babel_NET { Utils.removeNewlines(babelMethodRef.DeclaringType))); } - var git = babelMethodRef.DeclaringType as GenericInstanceType; + var git = babelMethodRef.DeclaringType.ToGenericInstSig(); if (git == null) return method; - var newMethod = memberReferenceConverter.copy(method); - newMethod.DeclaringType = babelMethodRef.DeclaringType; - return newMethod; + var mr = new MemberRefUser(module, method.Name, method.MethodSig.Clone(), babelMethodRef.DeclaringType.ToTypeDefOrRef()); + return module.UpdateRowId(mr); } - MethodReference getMethodReference(BabelMethodreference babelMethodRef) { + IMethod getMethodReference(BabelMethodreference babelMethodRef) { var declaringType = resolve(babelMethodRef.DeclaringType); if (declaringType == null) return null; @@ -215,20 +213,19 @@ namespace de4dot.code.deobfuscators.Babel_NET { return methods[0]; } - List getMethods(TypeDef declaringType, BabelMethodreference babelMethodRef) { - var methods = new List(); + List getMethods(TypeDef declaringType, BabelMethodreference babelMethodRef) { + var methods = new List(); - var git = babelMethodRef.DeclaringType as GenericInstanceType; - IGenericInstance gim = babelMethodRef.IsGenericMethod ? babelMethodRef : null; + var gis = babelMethodRef.DeclaringType as GenericInstSig; + var gim = babelMethodRef.GenericArguments; foreach (var method in declaringType.Methods) { - if (compareMethod(MethodReferenceInstance.make(method, git, gim), babelMethodRef)) { + if (compareMethod(GenericArgsSubstitutor.create(method, gis, gim), babelMethodRef)) { if (!babelMethodRef.IsGenericMethod) methods.Add(memberReferenceConverter.convert(method)); else { - var gim2 = new GenericInstanceMethod(memberReferenceConverter.convert(method)); - foreach (var arg in babelMethodRef.GenericArguments) - gim2.GenericArguments.Add(arg); - methods.Add(gim2); + var gim2 = new GenericInstMethodSig(babelMethodRef.GenericArguments); + var ms = module.UpdateRowId(new MethodSpecUser(memberReferenceConverter.convert(method), gim2)); + methods.Add(ms); } } } @@ -236,66 +233,71 @@ namespace de4dot.code.deobfuscators.Babel_NET { return methods; } - bool compareMethod(MethodReference method, BabelMethodreference babelMethodRef) { - if (method.Parameters.Count != babelMethodRef.Parameters.Length) + bool compareMethod(IMethod method, BabelMethodreference babelMethodRef) { + var sig = method.MethodSig; + if (sig.Params.Count != babelMethodRef.Parameters.Length) return false; if (method.Name != babelMethodRef.Name) return false; - if (method.HasThis != babelMethodRef.HasThis) + if (sig.HasThis != babelMethodRef.HasThis) return false; - if (method.GenericParameters.Count != babelMethodRef.GenericArguments.Length) + if (sig.GenParamCount != babelMethodRef.GenericArguments.Length) return false; - if (!MemberReferenceHelper.compareTypes(method.MethodReturnType.ReturnType, babelMethodRef.ReturnType)) + if (!new SigComparer().Equals(sig.RetType, babelMethodRef.ReturnType)) return false; for (int i = 0; i < babelMethodRef.Parameters.Length; i++) { - if (!MemberReferenceHelper.compareTypes(method.Parameters[i].ParameterType, babelMethodRef.Parameters[i].ParameterType)) + if (!new SigComparer().Equals(sig.Params[i], babelMethodRef.Parameters[i].Type)) return false; } return true; } - TypeDef resolve(TypeReference type) { - if (type is TypeDef) - return (TypeDef)type; + TypeDef resolve(TypeSig type) { + type = type.RemovePinnedAndModifiers(); - if (type.IsGenericInstance) - type = ((GenericInstanceType)type).ElementType; + var gis = type as GenericInstSig; + if (gis != null) + type = gis.GenericType; - if (type.Module == module && isModuleAssembly(type.Scope)) - return DotNetUtils.getType(module, type); + var tdrs = type as TypeDefOrRefSig; + if (tdrs == null) + return null; - return deobfuscatorContext.resolve(type); + var td = tdrs.TypeDef; + if (td != null) + return td; + + var tr = tdrs.TypeRef; + if (tr != null) + return tr.Resolve(); + + return null; } - public CallSite readCallSite() { - var returnType = readTypeReference(); - var paramTypes = readTypeReferences(); - var callingConvention = (CallingConvention)reader.ReadInt32(); + public MethodSig readCallSite() { + var returnType = readTypeSig(); + var paramTypes = readTypeSigs(); + var callingConvention = (CR.CallingConvention)reader.ReadInt32(); - var cs = new CallSite(returnType); - foreach (var paramType in paramTypes) - cs.Parameters.Add(new ParameterDefinition(paramType)); - cs.CallingConvention = convertCallingConvention(callingConvention); - - return cs; + return new MethodSig(convertCallingConvention(callingConvention), 0, returnType, paramTypes); } - static MethodCallingConvention convertCallingConvention(CallingConvention callingConvention) { + static DR.CallingConvention convertCallingConvention(CR.CallingConvention callingConvention) { switch (callingConvention) { - case CallingConvention.Winapi: return MethodCallingConvention.Default; - case CallingConvention.Cdecl: return MethodCallingConvention.C; - case CallingConvention.StdCall: return MethodCallingConvention.StdCall; - case CallingConvention.ThisCall: return MethodCallingConvention.ThisCall; - case CallingConvention.FastCall: return MethodCallingConvention.FastCall; + case CR.CallingConvention.Winapi: return DR.CallingConvention.Default; + case CR.CallingConvention.Cdecl: return DR.CallingConvention.C; + case CR.CallingConvention.StdCall: return DR.CallingConvention.StdCall; + case CR.CallingConvention.ThisCall: return DR.CallingConvention.ThisCall; + case CR.CallingConvention.FastCall: return DR.CallingConvention.FastCall; default: throw new ApplicationException(string.Format("Unknown CallingConvention {0}", callingConvention)); } } void initializeStrings(int headerOffset) { - reader.BaseStream.Position = headerOffset; + reader.Position = headerOffset; if (reader.ReadInt32() != STRINGS_SIG) throw new ApplicationException("Invalid strings sig"); @@ -305,27 +307,17 @@ namespace de4dot.code.deobfuscators.Babel_NET { } void initializeAssemblyNames(int headerOffset) { - reader.BaseStream.Position = headerOffset; + reader.Position = headerOffset; if (reader.ReadInt32() != ASSEMBLY_NAMES_SIG) throw new ApplicationException("Invalid assembly names sig"); - assemblyNames = new AssemblyNameReference[readVariableLengthInt32()]; + assemblyNames = new AssemblyRef[readVariableLengthInt32()]; for (int i = 0; i < assemblyNames.Length; i++) - assemblyNames[i] = getModuleAssemblyReference(AssemblyNameReference.Parse(readString())); - } - - bool isModuleAssembly(IMetadataScope scope) { - return DotNetUtils.isReferenceToModule(module, scope); - } - - AssemblyNameReference getModuleAssemblyReference(AssemblyNameReference asmRef) { - if (isModuleAssembly(asmRef)) - return module.Assembly.Name; - return memberReferenceConverter.convert(asmRef); + assemblyNames[i] = module.UpdateRowId(new AssemblyRefUser(new AssemblyNameInfo(readString()))); } void initializeMethodNames(int headerOffset) { - reader.BaseStream.Position = headerOffset; + reader.Position = headerOffset; if (reader.ReadInt32() != METHOD_NAMES_SIG) throw new ApplicationException("Invalid methods sig"); @@ -338,14 +330,14 @@ namespace de4dot.code.deobfuscators.Babel_NET { } void initializeTypeReferences(int headerOffset) { - reader.BaseStream.Position = headerOffset; + reader.Position = headerOffset; if (reader.ReadInt32() != TYPEREFS_SIG) throw new ApplicationException("Invalid typerefs sig"); int numTypeRefs = reader.ReadInt32(); - typeReferences = new List(numTypeRefs + 1); + typeReferences = new List(numTypeRefs + 1); typeReferences.Add(null); - var genericArgFixes = new Dictionary>(); + var genericArgFixes = new Dictionary>(); for (int i = 0; i < numTypeRefs; i++) { TypeId typeId = (TypeId)reader.ReadByte(); switch (typeId) { @@ -384,35 +376,30 @@ namespace de4dot.code.deobfuscators.Babel_NET { } } - TypeReference readTypeRef() { + TypeSig readTypeRef() { string ns, name; parseReflectionTypeName(readString(), out ns, out name); var asmRef = assemblyNames[readVariableLengthInt32()]; - var declaringType = readTypeReference(); - var typeReference = new TypeReference(ns, name, module, asmRef) { - DeclaringType = declaringType, - }; - typeReference.UpdateElementType(); + var declaringType = readTypeSig(); + var typeReference = new TypeRefUser(module, ns, name); + if (declaringType != null) + typeReference.ResolutionScope = getTypeRef(declaringType); + else + typeReference.ResolutionScope = asmRef; - typeReference = memberReferenceConverter.convert(typeReference); - typeReference.IsValueType = isValueType(typeReference); - return typeReference; + return memberReferenceConverter.convert(typeReference); } - bool isValueType(TypeReference typeRef) { - var typeDef = typeRef as TypeDef; - if (typeDef != null) - return typeDef.IsValueType; - - if (typeRef.Module == module && isModuleAssembly(typeRef.Scope)) - typeDef = DotNetUtils.getType(module, typeRef); - else - typeDef = resolve(typeRef); - if (typeDef != null) - return typeDef.IsValueType; - - Log.w("Could not determine whether type '{0}' is a value type", Utils.removeNewlines(typeRef)); - return false; // Assume it's a reference type + TypeRef getTypeRef(TypeSig type) { + var tdr = type as TypeDefOrRefSig; + if (tdr == null) + throw new ApplicationException("Not a type ref"); + if (tdr.TypeRef != null) + return tdr.TypeRef; + var td = tdr.TypeDef; + if (td != null) + return new Importer(module).Import(td) as TypeRef; + throw new ApplicationException("Not a type ref"); } static void parseReflectionTypeName(string fullName, out string ns, out string name) { @@ -461,8 +448,8 @@ namespace de4dot.code.deobfuscators.Babel_NET { return sb.ToString(); } - GenericInstanceType readGenericInstanceType(out List genericArgs) { - var git = new GenericInstanceType(readTypeReference()); + GenericInstSig readGenericInstanceType(out List genericArgs) { + var git = new GenericInstSig(readTypeSig() as ClassOrValueTypeSig); int numArgs = readVariableLengthInt32(); genericArgs = new List(numArgs); for (int i = 0; i < numArgs; i++) @@ -470,28 +457,40 @@ namespace de4dot.code.deobfuscators.Babel_NET { return git; } - PointerType readPointerType() { - return new PointerType(readTypeReference()); + PtrSig readPointerType() { + return new PtrSig(readTypeSig()); } - ArrayType readArrayType() { - return new ArrayType(readTypeReference(), readVariableLengthInt32()); + TypeSig readArrayType() { + var typeSig = readTypeSig(); + int rank = readVariableLengthInt32(); + if (rank == 1) + return new SZArraySig(typeSig); + return new ArraySig(typeSig, rank); } - ByReferenceType readByReferenceType() { - return new ByReferenceType(readTypeReference()); + ByRefSig readByReferenceType() { + return new ByRefSig(readTypeSig()); + } + + public uint readVariableLengthUInt32() { + uint val; + reader.ReadCompressedUInt32(out val); + return val; } public int readVariableLengthInt32() { - return DeobUtils.readVariableLengthInt32(reader); + uint val; + reader.ReadCompressedUInt32(out val); + return (int)val; } int getMetadataOffset() { - reader.BaseStream.Position = reader.BaseStream.Length - 4; + reader.Position = reader.Length - 4; for (int i = 0; i < 30; i++) { if (reader.ReadInt32() == METADATA_SIG) - return (int)reader.BaseStream.Position - 4; - reader.BaseStream.Position -= 8; + return (int)reader.Position - 4; + reader.Position -= 8; } return -1; } diff --git a/de4dot.code/deobfuscators/Babel_NET/InflaterCreator.cs b/de4dot.code/deobfuscators/Babel_NET/InflaterCreator.cs index 7420f226..0fcfadde 100644 --- a/de4dot.code/deobfuscators/Babel_NET/InflaterCreator.cs +++ b/de4dot.code/deobfuscators/Babel_NET/InflaterCreator.cs @@ -62,7 +62,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { var type = calledMethod.DeclaringType; foreach (var nested in type.NestedTypes) { - if (DeobUtils.hasInteger(DotNetUtils.getMethod(nested, ".ctor"), 0x8001)) + if (DeobUtils.hasInteger(nested.FindMethod(".ctor"), 0x8001)) return type; } } @@ -98,7 +98,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { var instrs = method.Body.Instructions; for (int i = 0; i < instrs.Count - 3; i++) { var ldci4_1 = instrs[i]; - if (!DotNetUtils.isLdcI4(ldci4_1) || DotNetUtils.getLdcI4Value(ldci4_1) != 16) + if (!ldci4_1.IsLdcI4() || ldci4_1.GetLdcI4Value() != 16) continue; var callvirt = instrs[i + 1]; @@ -106,13 +106,13 @@ namespace de4dot.code.deobfuscators.Babel_NET { continue; var ldci4_2 = instrs[i + 2]; - if (!DotNetUtils.isLdcI4(ldci4_2)) + if (!ldci4_2.IsLdcI4()) continue; if (instrs[i + 3].OpCode.Code != Code.Xor) continue; - return DotNetUtils.getLdcI4Value(ldci4_2); + return ldci4_2.GetLdcI4Value(); } return null; diff --git a/de4dot.code/deobfuscators/Babel_NET/MemberReferenceConverter.cs b/de4dot.code/deobfuscators/Babel_NET/MemberReferenceConverter.cs index 3664184c..2bdb6ff9 100644 --- a/de4dot.code/deobfuscators/Babel_NET/MemberReferenceConverter.cs +++ b/de4dot.code/deobfuscators/Babel_NET/MemberReferenceConverter.cs @@ -22,123 +22,57 @@ using dot10.DotNet; using de4dot.blocks; namespace de4dot.code.deobfuscators.Babel_NET { - class TypeReferenceConverter : TypeReferenceUpdaterBase { - MemberReferenceConverter memberReferenceConverter; - - ModuleDefinition Module { - get { return memberReferenceConverter.Module; } - } - - public TypeReferenceConverter(MemberReferenceConverter memberReferenceConverter) { - this.memberReferenceConverter = memberReferenceConverter; - } - - public TypeReference convert(TypeReference a) { - var newOne = update(a); - if (!(a is GenericParam) && !MemberReferenceHelper.compareTypes(newOne, a)) - throw new ApplicationException("Could not convert type reference"); - return newOne; - } - - protected override TypeReference updateTypeReference(TypeReference a) { - if (a.Module == Module) - return a; - - var newTypeRef = new TypeReference(a.Namespace, a.Name, Module, memberReferenceConverter.convert(a.Scope), a.IsValueType); - foreach (var gp in a.GenericParameters) - newTypeRef.GenericParameters.Add(new GenericParam(gp.Name, newTypeRef)); - newTypeRef.DeclaringType = update(a.DeclaringType); - newTypeRef.UpdateElementType(); - return newTypeRef; - } - } - // Converts type references/definitions in one module to this module class MemberReferenceConverter { - ModuleDefinition module; + ModuleDefMD module; - public ModuleDefinition Module { + public ModuleDefMD Module { get { return module; } } - public MemberReferenceConverter(ModuleDefinition module) { + public MemberReferenceConverter(ModuleDefMD module) { this.module = module; } - bool isInOurModule(MemberReference memberRef) { - return memberRef.Module == module; + bool isInOurModule(IMemberRef memberRef) { + return memberRef.OwnerModule == module; } - public TypeReference convert(TypeReference typeRef) { - if (typeRef == null) - return null; - typeRef = new TypeReferenceConverter(this).convert(typeRef); - return tryGetTypeDefinition(typeRef); + Importer createImporter() { + return new Importer(module, ImporterOptions.TryToUseTypeDefs); } - public FieldReference convert(FieldReference fieldRef) { + public TypeSig convert(TypeRef typeRef) { + return createImporter().Import(typeRef).ToTypeSig(); + } + + ITypeDefOrRef convert(ITypeDefOrRef tdr) { + return (ITypeDefOrRef)createImporter().Import(tdr); + } + + TypeSig convert2(TypeSig ts) { + return createImporter().Import(ts); + } + + public TypeSig convert(TypeSig ts) { + return createImporter().Import(ts); + } + + public IField convert(IField fieldRef) { if (isInOurModule(fieldRef)) return tryGetFieldDefinition(fieldRef); - - return new FieldReference(fieldRef.Name, convert(fieldRef.FieldType), convert(fieldRef.DeclaringType)); + return createImporter().Import(fieldRef); } - public MethodReference convert(MethodReference methodRef) { - if (methodRef.GetType() != typeof(MethodReference) && methodRef.GetType() != typeof(MethodDef)) + public IMethodDefOrRef convert(IMethod methodRef) { + if (!(methodRef is MemberRef || methodRef is MethodDef) || methodRef.MethodSig == null) throw new ApplicationException("Invalid method reference type"); if (isInOurModule(methodRef)) - return tryGetMethodDefinition(methodRef); - - return copy(methodRef); + return (IMethodDefOrRef)tryGetMethodDefinition(methodRef); + return (IMethodDefOrRef)createImporter().Import(methodRef); } - public MethodReference copy(MethodReference methodRef) { - if (methodRef.GetType() != typeof(MethodReference) && methodRef.GetType() != typeof(MethodDef)) - throw new ApplicationException("Invalid method reference type"); - - var newMethodRef = new MethodReference(methodRef.Name, convert(methodRef.MethodReturnType.ReturnType), convert(methodRef.DeclaringType)); - newMethodRef.HasThis = methodRef.HasThis; - newMethodRef.ExplicitThis = methodRef.ExplicitThis; - newMethodRef.CallingConvention = methodRef.CallingConvention; - foreach (var param in methodRef.Parameters) - newMethodRef.Parameters.Add(new ParameterDefinition(param.Name, param.Attributes, convert(param.ParameterType))); - foreach (var gp in methodRef.GenericParameters) - newMethodRef.GenericParameters.Add(new GenericParam(gp.Name, newMethodRef)); - return newMethodRef; - } - - public IMetadataScope convert(IMetadataScope scope) { - switch (scope.MetadataScopeType) { - case MetadataScopeType.AssemblyNameReference: - return convert((AssemblyNameReference)scope); - - case MetadataScopeType.ModuleDefinition: - var mod = (ModuleDefinition)scope; - if (mod.Assembly != null) - return convert((AssemblyNameReference)mod.Assembly.Name); - return convert((ModuleReference)scope); - - case MetadataScopeType.ModuleReference: - return convert((ModuleReference)scope); - - default: - throw new ApplicationException("Unknown MetadataScopeType"); - } - } - - public AssemblyNameReference convert(AssemblyNameReference asmRef) { - return DotNetUtils.addAssemblyReference(module, asmRef); - } - - public ModuleReference convert(ModuleReference modRef) { - return DotNetUtils.addModuleReference(module, modRef); - } - - public TypeReference tryGetTypeDefinition(TypeReference typeRef) { - return DotNetUtils.getType(module, typeRef) ?? typeRef; - } - - public FieldReference tryGetFieldDefinition(FieldReference fieldRef) { + public IField tryGetFieldDefinition(IField fieldRef) { var fieldDef = fieldRef as FieldDef; if (fieldDef != null) return fieldDef; @@ -149,7 +83,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { return DotNetUtils.getField(declaringType, fieldRef); } - public MethodReference tryGetMethodDefinition(MethodReference methodRef) { + public IMethod tryGetMethodDefinition(IMethod methodRef) { var methodDef = methodRef as MethodDef; if (methodDef != null) return methodDef; diff --git a/de4dot.code/deobfuscators/Babel_NET/MethodBodyReader.cs b/de4dot.code/deobfuscators/Babel_NET/MethodBodyReader.cs index 270fb758..38c17a55 100644 --- a/de4dot.code/deobfuscators/Babel_NET/MethodBodyReader.cs +++ b/de4dot.code/deobfuscators/Babel_NET/MethodBodyReader.cs @@ -18,7 +18,9 @@ */ using System; +using System.Collections.Generic; using System.IO; +using dot10.IO; using dot10.DotNet; using dot10.DotNet.Emit; @@ -26,67 +28,73 @@ namespace de4dot.code.deobfuscators.Babel_NET { class MethodBodyReader : MethodBodyReaderBase { ImageReader imageReader; public int Flags2 { get; set; } - public short MaxStack { get; set; } + public ushort MaxStack { get; set; } - public MethodBodyReader(ImageReader imageReader, BinaryReader reader) + public MethodBodyReader(ImageReader imageReader, IBinaryReader reader) : base(reader) { this.imageReader = imageReader; } - public void read(ParameterDefinition[] parameters) { + public void read(IList parameters) { this.parameters = parameters; Flags2 = reader.ReadInt16(); - MaxStack = reader.ReadInt16(); - setLocals(imageReader.readTypeReferences()); - readInstructions(imageReader.readVariableLengthInt32()); + MaxStack = reader.ReadUInt16(); + SetLocals(imageReader.readTypeSigs()); + ReadInstructions(imageReader.readVariableLengthInt32()); readExceptionHandlers(imageReader.readVariableLengthInt32()); } - protected override FieldReference readInlineField(Instruction instr) { + protected override IField ReadInlineField(Instruction instr) { return imageReader.readFieldReference(); } - protected override MethodReference readInlineMethod(Instruction instr) { + protected override IMethod ReadInlineMethod(Instruction instr) { return imageReader.readMethodReference(); } - protected override CallSite readInlineSig(Instruction instr) { + protected override MethodSig ReadInlineSig(Instruction instr) { return imageReader.readCallSite(); } - protected override string readInlineString(Instruction instr) { + protected override string ReadInlineString(Instruction instr) { return imageReader.readString(); } - protected override MemberReference readInlineTok(Instruction instr) { + protected override ITokenOperand ReadInlineTok(Instruction instr) { switch (reader.ReadByte()) { - case 0: return imageReader.readTypeReference(); + case 0: return imageReader.readTypeSig().ToTypeDefOrRef(); case 1: return imageReader.readFieldReference(); case 2: return imageReader.readMethodReference(); default: throw new ApplicationException("Unknown token type"); } } - protected override TypeReference readInlineType(Instruction instr) { - return imageReader.readTypeReference(); + protected override ITypeDefOrRef ReadInlineType(Instruction instr) { + return imageReader.readTypeSig().ToTypeDefOrRef(); } - protected override ExceptionHandler readExceptionHandler() { + void readExceptionHandlers(int numExceptionHandlers) { + exceptionHandlers = new List(numExceptionHandlers); + for (int i = 0; i < numExceptionHandlers; i++) + Add(readExceptionHandler()); + } + + ExceptionHandler readExceptionHandler() { var ehType = (ExceptionHandlerType)reader.ReadByte(); - int tryOffset = imageReader.readVariableLengthInt32(); - int tryLength = imageReader.readVariableLengthInt32(); - int handlerOffset = imageReader.readVariableLengthInt32(); - int handlerLength = imageReader.readVariableLengthInt32(); - var catchType = imageReader.readTypeReference(); - int filterOffset = imageReader.readVariableLengthInt32(); + uint tryOffset = imageReader.readVariableLengthUInt32(); + uint tryLength = imageReader.readVariableLengthUInt32(); + uint handlerOffset = imageReader.readVariableLengthUInt32(); + uint handlerLength = imageReader.readVariableLengthUInt32(); + var catchType = imageReader.readTypeSig().ToTypeDefOrRef(); + uint filterOffset = imageReader.readVariableLengthUInt32(); var eh = new ExceptionHandler(ehType); - eh.TryStart = getInstruction(tryOffset); - eh.TryEnd = getInstructionOrNull(tryOffset + tryLength); + eh.TryStart = GetInstructionThrow(tryOffset); + eh.TryEnd = GetInstruction(tryOffset + tryLength); if (ehType == ExceptionHandlerType.Filter) - eh.FilterStart = getInstruction(filterOffset); - eh.HandlerStart = getInstruction(handlerOffset); - eh.HandlerEnd = getInstructionOrNull(handlerOffset + handlerLength); + eh.FilterStart = GetInstructionThrow(filterOffset); + eh.HandlerStart = GetInstructionThrow(handlerOffset); + eh.HandlerEnd = GetInstruction(handlerOffset + handlerLength); eh.CatchType = catchType; return eh; } diff --git a/de4dot.code/deobfuscators/Babel_NET/MethodReferenceReader.cs b/de4dot.code/deobfuscators/Babel_NET/MethodReferenceReader.cs index 443d598a..92d2f45e 100644 --- a/de4dot.code/deobfuscators/Babel_NET/MethodReferenceReader.cs +++ b/de4dot.code/deobfuscators/Babel_NET/MethodReferenceReader.cs @@ -20,17 +20,17 @@ using System; using System.Collections.Generic; using System.IO; +using dot10.IO; using dot10.DotNet; using dot10.DotNet.Emit; -using Mono.Collections.Generic; namespace de4dot.code.deobfuscators.Babel_NET { - class BabelMethodreference : IGenericInstance { + class BabelMethodreference { public string Name { get; set; } - public TypeReference DeclaringType { get; set; } - public TypeReference ReturnType { get; set; } - public ParameterDefinition[] Parameters { get; set; } - public TypeReference[] GenericArguments { get; set; } + public TypeSig DeclaringType { get; set; } + public TypeSig ReturnType { get; set; } + public Parameter[] Parameters { get; set; } + public TypeSig[] GenericArguments { get; set; } public int Flags { get; set; } public bool HasThis { @@ -40,27 +40,14 @@ namespace de4dot.code.deobfuscators.Babel_NET { public bool IsGenericMethod { get { return (Flags & 2) != 0; } } - - bool IGenericInstance.HasGenericArguments { - get { return IsGenericMethod; } - } - - Collection IGenericInstance.GenericArguments { - get { return new Collection(GenericArguments); } - } - - MetadataToken IMetadataTokenProvider.MDToken { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } } class BabelMethodDefinition : BabelMethodreference { - ParameterDefinition thisParameter; + Parameter thisParameter; public int Flags2 { get; set; } - public short MaxStack { get; set; } - public IList Locals { get; set; } + public ushort MaxStack { get; set; } + public IList Locals { get; set; } public IList Instructions { get; set; } public IList ExceptionHandlers { get; set; } @@ -80,13 +67,13 @@ namespace de4dot.code.deobfuscators.Babel_NET { get { return (Flags2 & 0x80) != 0; } } - public ParameterDefinition ThisParameter { + public Parameter ThisParameter { get { if (!HasThis) return null; if (thisParameter != null) return thisParameter; - return thisParameter = new ParameterDefinition(DeclaringType); + return thisParameter = new Parameter(0, Parameter.HIDDEN_THIS_METHOD_SIG_INDEX, DeclaringType); } } @@ -98,10 +85,10 @@ namespace de4dot.code.deobfuscators.Babel_NET { ExceptionHandlers = mbr.ExceptionHandlers; } - public ParameterDefinition[] getRealParameters() { + public IList getRealParameters() { if (ThisParameter == null) return Parameters; - var parameters = new ParameterDefinition[Parameters.Length + 1]; + var parameters = new Parameter[Parameters.Length + 1]; parameters[0] = ThisParameter; Array.Copy(Parameters, 0, parameters, 1, Parameters.Length); return parameters; @@ -110,14 +97,14 @@ namespace de4dot.code.deobfuscators.Babel_NET { class MethodReferenceReader { ImageReader imageReader; - BinaryReader reader; + IBinaryReader reader; BabelMethodreference bmr; - public MethodReferenceReader(ImageReader imageReader, BinaryReader reader) + public MethodReferenceReader(ImageReader imageReader, IBinaryReader reader) : this(imageReader, reader, new BabelMethodreference()) { } - public MethodReferenceReader(ImageReader imageReader, BinaryReader reader, BabelMethodreference bmr) { + public MethodReferenceReader(ImageReader imageReader, IBinaryReader reader, BabelMethodreference bmr) { this.imageReader = imageReader; this.reader = reader; this.bmr = bmr; @@ -125,23 +112,24 @@ namespace de4dot.code.deobfuscators.Babel_NET { public BabelMethodreference read() { bmr.Name = imageReader.readString(); - bmr.DeclaringType = imageReader.readTypeReference(); - bmr.ReturnType = imageReader.readTypeReference(); - bmr.Parameters = readParameters(); + bmr.DeclaringType = imageReader.readTypeSig(); + bmr.ReturnType = imageReader.readTypeSig(); + var argTypes = imageReader.readTypeSigs(); bmr.Flags = reader.ReadByte(); if (bmr.IsGenericMethod) - bmr.GenericArguments = imageReader.readTypeReferences(); + bmr.GenericArguments = imageReader.readTypeSigs(); else - bmr.GenericArguments = new TypeReference[0]; + bmr.GenericArguments = new TypeSig[0]; + bmr.Parameters = readParameters(argTypes, bmr.HasThis); return bmr; } - ParameterDefinition[] readParameters() { - var typeReferences = imageReader.readTypeReferences(); - var parameters = new ParameterDefinition[typeReferences.Length]; - for (int i = 0; i < parameters.Length; i++) - parameters[i] = new ParameterDefinition(typeReferences[i]); - return parameters; + Parameter[] readParameters(IList argTypes, bool hasThis) { + var ps = new Parameter[argTypes.Count]; + int bi = hasThis ? 1 : 0; + for (int i = 0; i < ps.Length; i++) + ps[i] = new Parameter(bi + i, i, argTypes[i]); + return ps; } } @@ -150,7 +138,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { MethodBodyReader methodBodyReader; BabelMethodDefinition bmd; - public MethodDefinitionReader(ImageReader imageReader, BinaryReader reader) { + public MethodDefinitionReader(ImageReader imageReader, IBinaryReader reader) { this.bmd = new BabelMethodDefinition(); this.methodReferenceReader = new MethodReferenceReader(imageReader, reader, bmd); this.methodBodyReader = new MethodBodyReader(imageReader, reader); diff --git a/de4dot.code/deobfuscators/Babel_NET/MethodsDecrypter.cs b/de4dot.code/deobfuscators/Babel_NET/MethodsDecrypter.cs index 131d7cdd..8506ba3b 100644 --- a/de4dot.code/deobfuscators/Babel_NET/MethodsDecrypter.cs +++ b/de4dot.code/deobfuscators/Babel_NET/MethodsDecrypter.cs @@ -20,13 +20,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.Babel_NET { class MethodsDecrypter { - ModuleDefinition module; + ModuleDefMD module; ResourceDecrypter resourceDecrypter; IDeobfuscatorContext deobfuscatorContext; Dictionary imageReaders = new Dictionary(StringComparer.Ordinal); @@ -39,7 +40,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { get { return methodsDecrypterCreator != null; } } - public MethodsDecrypter(ModuleDefinition module, ResourceDecrypter resourceDecrypter, IDeobfuscatorContext deobfuscatorContext) { + public MethodsDecrypter(ModuleDefMD module, ResourceDecrypter resourceDecrypter, IDeobfuscatorContext deobfuscatorContext) { this.module = module; this.resourceDecrypter = resourceDecrypter; this.deobfuscatorContext = deobfuscatorContext; @@ -54,7 +55,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { var fieldTypes = new FieldTypes(type); if (!fieldTypes.all(requiredFields)) continue; - if (DotNetUtils.getMethod(type, "Finalize") == null) + if (type.FindMethod("Finalize") == null) continue; var executeMethod = DotNetUtils.getMethod(type, "System.Object", "(System.String,System.Object[])"); if (executeMethod == null || !executeMethod.IsStatic || executeMethod.Body == null) @@ -84,10 +85,10 @@ namespace de4dot.code.deobfuscators.Babel_NET { TypeDef findMethodsDecrypterType(TypeDef type) { foreach (var field in type.Fields) { - var fieldType = DotNetUtils.getType(module, field.FieldType); + var fieldType = DotNetUtils.getType(module, field.FieldSig.GetFieldType()); if (fieldType == null) continue; - if (DotNetUtils.getMethod(fieldType, "Finalize") == null) + if (fieldType.FindMethod("Finalize") == null) continue; if (!new FieldTypes(fieldType).exists("System.Collections.Hashtable")) continue; @@ -106,7 +107,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { encryptedResource = BabelUtils.findEmbeddedResource(module, methodsDecrypter, simpleDeobfuscator, deob); if (encryptedResource != null) - addImageReader("", resourceDecrypter.decrypt(encryptedResource.GetResourceData())); + addImageReader("", resourceDecrypter.decrypt(encryptedResource.Data.ReadAllBytes())); } ImageReader addImageReader(string name, byte[] data) { @@ -178,7 +179,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { return null; try { - var encrypted = File.ReadAllBytes(getFile(Path.GetDirectoryName(module.FullyQualifiedName), feature)); + var encrypted = File.ReadAllBytes(getFile(Path.GetDirectoryName(module.Location), feature)); var decrypted = resourceDecrypter.decrypt(encrypted); return addImageReader(feature, decrypted); } @@ -241,7 +242,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { foreach (var instr in method.Body.Instructions) { if (instr.OpCode.Code != Code.Call && instr.OpCode.Code != Code.Callvirt) continue; - if (MemberReferenceHelper.compareMethodReferenceAndDeclaringType(decryptExecuteMethod, instr.Operand as MethodReference)) + if (MethodEqualityComparer.CompareDeclaringTypes.Equals(decryptExecuteMethod, instr.Operand as IMethod)) return true; } return false; diff --git a/de4dot.code/deobfuscators/Babel_NET/ProxyCallFixer.cs b/de4dot.code/deobfuscators/Babel_NET/ProxyCallFixer.cs index 68dc3e11..b7d98a34 100644 --- a/de4dot.code/deobfuscators/Babel_NET/ProxyCallFixer.cs +++ b/de4dot.code/deobfuscators/Babel_NET/ProxyCallFixer.cs @@ -27,7 +27,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { class ProxyCallFixer : ProxyCallFixer2 { MethodDefinitionAndDeclaringTypeDict methodToType = new MethodDefinitionAndDeclaringTypeDict(); - public ProxyCallFixer(ModuleDefinition module) + public ProxyCallFixer(ModuleDefMD module) : base(module) { } @@ -38,11 +38,11 @@ namespace de4dot.code.deobfuscators.Babel_NET { } class Context { - public TypeReference delegateType; + public ITypeDefOrRef delegateType; public int methodToken; public int declaringTypeToken; public ProxyCreatorType proxyCreatorType; - public Context(TypeReference delegateType, int methodToken, int declaringTypeToken, ProxyCreatorType proxyCreatorType) { + public Context(ITypeDefOrRef delegateType, int methodToken, int declaringTypeToken, ProxyCreatorType proxyCreatorType) { this.delegateType = delegateType; this.methodToken = methodToken; this.declaringTypeToken = declaringTypeToken; @@ -57,24 +57,24 @@ namespace de4dot.code.deobfuscators.Babel_NET { protected override object checkCctor(TypeDef type, MethodDef cctor) { var instructions = cctor.Body.Instructions; for (int i = 0; i < instructions.Count; i++) { - TypeReference delegateType; - FieldReference delegateField; - MethodReference createMethod; + ITypeDefOrRef delegateType; + IField delegateField; + IMethod createMethod; int methodToken, declaringTypeToken; var instrs = DotNetUtils.getInstructions(instructions, i, OpCodes.Ldtoken, OpCodes.Ldc_I4, OpCodes.Ldc_I4, OpCodes.Ldtoken, OpCodes.Call); if (instrs != null) { - delegateType = instrs[0].Operand as TypeReference; - methodToken = DotNetUtils.getLdcI4Value(instrs[1]); - declaringTypeToken = DotNetUtils.getLdcI4Value(instrs[2]); - delegateField = instrs[3].Operand as FieldReference; - createMethod = instrs[4].Operand as MethodReference; + delegateType = instrs[0].Operand as ITypeDefOrRef; + methodToken = instrs[1].GetLdcI4Value(); + declaringTypeToken = instrs[2].GetLdcI4Value(); + delegateField = instrs[3].Operand as IField; + createMethod = instrs[4].Operand as IMethod; } else if ((instrs = DotNetUtils.getInstructions(instructions, i, OpCodes.Ldtoken, OpCodes.Ldc_I4, OpCodes.Ldtoken, OpCodes.Call)) != null) { - delegateType = instrs[0].Operand as TypeReference; - methodToken = DotNetUtils.getLdcI4Value(instrs[1]); + delegateType = instrs[0].Operand as ITypeDefOrRef; + methodToken = instrs[1].GetLdcI4Value(); declaringTypeToken = -1; - delegateField = instrs[2].Operand as FieldReference; - createMethod = instrs[3].Operand as MethodReference; + delegateField = instrs[2].Operand as IField; + createMethod = instrs[3].Operand as IMethod; } else continue; @@ -95,7 +95,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { 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) { @@ -109,7 +109,10 @@ namespace de4dot.code.deobfuscators.Babel_NET { throw new ApplicationException(string.Format("Invalid proxy creator type: {0}", ctx.proxyCreatorType)); } - calledMethod = module.LookupToken(ctx.methodToken) as MethodReference; + var method = module.ResolveToken(ctx.methodToken) as IMethod; + if (method.MethodSig == null) + method = null; + calledMethod = method; } public void findDelegateCreator() { @@ -145,7 +148,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { foreach (var calledMethod in DotNetUtils.getCalledMethods(module, methodToCheck)) { if (!calledMethod.IsStatic || calledMethod.Body == null) continue; - if (!MemberReferenceHelper.compareTypes(methodToCheck.DeclaringType, calledMethod.DeclaringType)) + if (!new SigComparer().Equals(methodToCheck.DeclaringType, calledMethod.DeclaringType)) continue; if (DotNetUtils.isMethod(calledMethod, "System.Void", "(System.Reflection.FieldInfo,System.Type,System.Reflection.MethodInfo)")) return ProxyCreatorType.CallOrCallvirt; diff --git a/de4dot.code/deobfuscators/Babel_NET/ResourceDecrypter.cs b/de4dot.code/deobfuscators/Babel_NET/ResourceDecrypter.cs index 602ebdc5..93ff93b5 100644 --- a/de4dot.code/deobfuscators/Babel_NET/ResourceDecrypter.cs +++ b/de4dot.code/deobfuscators/Babel_NET/ResourceDecrypter.cs @@ -26,10 +26,10 @@ using de4dot.blocks; namespace de4dot.code.deobfuscators.Babel_NET { class ResourceDecrypterCreator { - ModuleDefinition module; + ModuleDefMD module; ISimpleDeobfuscator simpleDeobfuscator; - public ResourceDecrypterCreator(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator) { + public ResourceDecrypterCreator(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator) { this.module = module; this.simpleDeobfuscator = simpleDeobfuscator; } @@ -40,12 +40,12 @@ namespace de4dot.code.deobfuscators.Babel_NET { } class ResourceDecrypter { - ModuleDefinition module; + ModuleDefMD module; ISimpleDeobfuscator simpleDeobfuscator; MethodDef decryptMethod; IDecrypter decrypter; - public ResourceDecrypter(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator) { + public ResourceDecrypter(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator) { this.module = module; this.simpleDeobfuscator = simpleDeobfuscator; } @@ -56,9 +56,9 @@ namespace de4dot.code.deobfuscators.Babel_NET { // v3.0 class Decrypter1 : IDecrypter { - ModuleDefinition module; + ModuleDefMD module; - public Decrypter1(ModuleDefinition module) { + public Decrypter1(ModuleDefMD module) { this.module = module; } @@ -82,7 +82,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { key = reader.ReadBytes(reader.ReadByte()); else { key = new byte[reader.ReadByte()]; - Array.Copy(module.Assembly.Name.PublicKey, 0, key, 0, key.Length); + Array.Copy(module.Assembly.PublicKey.Data, 0, key, 0, key.Length); } reader.ReadBytes(reader.ReadInt32()); // hash @@ -92,9 +92,9 @@ namespace de4dot.code.deobfuscators.Babel_NET { // v3.5+ class Decrypter2 : IDecrypter { - ModuleDefinition module; + ModuleDefMD module; - public Decrypter2(ModuleDefinition module) { + public Decrypter2(ModuleDefMD module) { this.module = module; } @@ -143,7 +143,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { key = reader.ReadBytes(reader.ReadByte()); else { key = new byte[reader.ReadByte()]; - Array.Copy(module.Assembly.Name.PublicKey, 12, key, 0, key.Length); + Array.Copy(module.Assembly.PublicKey.Data, 12, key, 0, key.Length); key[5] |= 0x80; } return isCompressed; @@ -152,10 +152,10 @@ namespace de4dot.code.deobfuscators.Babel_NET { // v5.0+ retail class Decrypter3 : IDecrypter { - ModuleDefinition module; + ModuleDefMD module; Inflater inflater; - public Decrypter3(ModuleDefinition module, MethodDef decryptMethod) { + public Decrypter3(ModuleDefMD module, MethodDef decryptMethod) { this.module = module; this.inflater = InflaterCreator.create(decryptMethod, true); } @@ -201,7 +201,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { key = reader.ReadBytes(reader.ReadByte()); else { key = new byte[reader.ReadByte()]; - Array.Copy(module.Assembly.Name.PublicKey, 12, key, 0, key.Length); + Array.Copy(module.Assembly.PublicKey.Data, 12, key, 0, key.Length); key[5] |= 0x80; } return isCompressed; diff --git a/de4dot.code/deobfuscators/Babel_NET/ResourceResolver.cs b/de4dot.code/deobfuscators/Babel_NET/ResourceResolver.cs index 4289490d..6b35dc88 100644 --- a/de4dot.code/deobfuscators/Babel_NET/ResourceResolver.cs +++ b/de4dot.code/deobfuscators/Babel_NET/ResourceResolver.cs @@ -20,13 +20,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.Babel_NET { class ResourceResolver { - ModuleDefinition module; + ModuleDefMD module; ResourceDecrypter resourceDecrypter; ISimpleDeobfuscator simpleDeobfuscator; TypeDef resolverType; @@ -47,7 +48,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { get { return registerMethod; } } - public ResourceResolver(ModuleDefinition module, ResourceDecrypter resourceDecrypter, ISimpleDeobfuscator simpleDeobfuscator) { + public ResourceResolver(ModuleDefMD module, ResourceDecrypter resourceDecrypter, ISimpleDeobfuscator simpleDeobfuscator) { this.module = module; this.resourceDecrypter = resourceDecrypter; this.simpleDeobfuscator = simpleDeobfuscator; @@ -104,20 +105,20 @@ namespace de4dot.code.deobfuscators.Babel_NET { var callvirt = instrs[i]; if (callvirt.OpCode.Code != Code.Callvirt) continue; - var calledMethod = callvirt.Operand as MethodReference; + var calledMethod = callvirt.Operand as IMethod; if (calledMethod == null) continue; if (calledMethod.FullName != "System.Int32 System.IO.BinaryReader::ReadInt32()") continue; var ldci4 = instrs[i + 1]; - if (!DotNetUtils.isLdcI4(ldci4)) + if (!ldci4.IsLdcI4()) continue; if (instrs[i + 2].OpCode.Code != Code.Xor) continue; - ints.Add(DotNetUtils.getLdcI4Value(ldci4)); + ints.Add(ldci4.GetLdcI4Value()); } if (ints.Count == 2) { @@ -130,14 +131,14 @@ namespace de4dot.code.deobfuscators.Babel_NET { public EmbeddedResource mergeResources() { if (encryptedResource == null) return null; - DeobUtils.decryptAndAddResources(module, encryptedResource.Name, () => decryptResourceAssembly()); + DeobUtils.decryptAndAddResources(module, encryptedResource.Name.String, () => decryptResourceAssembly()); var result = encryptedResource; encryptedResource = null; return result; } byte[] decryptResourceAssembly() { - var decrypted = resourceDecrypter.decrypt(encryptedResource.GetResourceData()); + var decrypted = resourceDecrypter.decrypt(encryptedResource.Data.ReadAllBytes()); var reader = new BinaryReader(new MemoryStream(decrypted)); int numResources = reader.ReadInt32() ^ xorKey1; diff --git a/de4dot.code/deobfuscators/Babel_NET/StringDecrypter.cs b/de4dot.code/deobfuscators/Babel_NET/StringDecrypter.cs index ade3f060..bb6791b1 100644 --- a/de4dot.code/deobfuscators/Babel_NET/StringDecrypter.cs +++ b/de4dot.code/deobfuscators/Babel_NET/StringDecrypter.cs @@ -21,6 +21,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Text; +using dot10.IO; using dot10.DotNet; using dot10.DotNet.Emit; using de4dot.blocks; @@ -28,7 +29,7 @@ using de4dot.blocks.cflow; namespace de4dot.code.deobfuscators.Babel_NET { class StringDecrypter { - ModuleDefinition module; + ModuleDefMD module; ResourceDecrypter resourceDecrypter; ISimpleDeobfuscator simpleDeobfuscator; TypeDef decrypterType; @@ -38,7 +39,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { interface IDecrypterInfo { MethodDef Decrypter { get; } bool NeedsResource { get; } - void initialize(ModuleDefinition module, EmbeddedResource resource); + void initialize(ModuleDefMD module, EmbeddedResource resource); string decrypt(object[] args); } @@ -49,7 +50,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { get { return false; } } - public void initialize(ModuleDefinition module, EmbeddedResource resource) { + public void initialize(ModuleDefMD module, EmbeddedResource resource) { } public string decrypt(object[] args) { @@ -72,8 +73,8 @@ namespace de4dot.code.deobfuscators.Babel_NET { get { return true; } } - public void initialize(ModuleDefinition module, EmbeddedResource resource) { - key = resource.GetResourceData(); + public void initialize(ModuleDefMD module, EmbeddedResource resource) { + key = resource.Data.ReadAllBytes(); if (key.Length != 0x100) throw new ApplicationException(string.Format("Unknown key length: {0}", key.Length)); } @@ -106,8 +107,8 @@ namespace de4dot.code.deobfuscators.Babel_NET { this.resourceDecrypter = resourceDecrypter; } - public void initialize(ModuleDefinition module, EmbeddedResource resource) { - var decrypted = resourceDecrypter.decrypt(resource.GetResourceData()); + public void initialize(ModuleDefMD module, EmbeddedResource resource) { + var decrypted = resourceDecrypter.decrypt(resource.Data.ReadAllBytes()); var reader = new BinaryReader(new MemoryStream(decrypted)); while (reader.BaseStream.Position < reader.BaseStream.Length) offsetToString[getOffset((int)reader.BaseStream.Position)] = reader.ReadString(); @@ -118,8 +119,8 @@ namespace de4dot.code.deobfuscators.Babel_NET { if (OffsetCalcInstructions == null || OffsetCalcInstructions.Count == 0) return offset; if (dummyMethod == null) { - dummyMethod = new MethodDef("", 0, new TypeReference("", "", null, null)); - dummyMethod.Body = new MethodBody(dummyMethod); + dummyMethod = new MethodDefUser(); + dummyMethod.Body = new CilBody(); } emulator.init(dummyMethod); emulator.push(new Int32Value(offset)); @@ -153,7 +154,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { get { return encryptedResource; } } - public StringDecrypter(ModuleDefinition module, ResourceDecrypter resourceDecrypter) { + public StringDecrypter(ModuleDefMD module, ResourceDecrypter resourceDecrypter) { this.module = module; this.resourceDecrypter = resourceDecrypter; } @@ -212,7 +213,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { int stringLength = 0, stringToCharArray = 0, stringCtor = 0; foreach (var instr in method.Body.Instructions) { - var calledMethod = instr.Operand as MethodReference; + var calledMethod = instr.Operand as IMethod; if (calledMethod == null) continue; @@ -246,7 +247,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { if (nested.HasProperties || nested.HasEvents) return null; - if (DotNetUtils.getMethod(nested, ".ctor") == null) + if (nested.FindMethod(".ctor") == null) return null; if (nested.Fields.Count == 1 || nested.Fields.Count == 3) { @@ -259,7 +260,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { if (decrypterBuilderMethod == null) return null; - resourceDecrypter.DecryptMethod = ResourceDecrypter.findDecrypterMethod(DotNetUtils.getMethod(nested, ".ctor")); + resourceDecrypter.DecryptMethod = ResourceDecrypter.findDecrypterMethod(nested.FindMethod(".ctor")); var nestedDecrypter = DotNetUtils.getMethod(nested, "System.String", "(System.Int32)"); if (nestedDecrypter == null || nestedDecrypter.IsStatic) @@ -286,7 +287,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { if (decrypter == null || !decrypter.IsStatic) return null; - resourceDecrypter.DecryptMethod = ResourceDecrypter.findDecrypterMethod(DotNetUtils.getMethod(nested, ".ctor")); + resourceDecrypter.DecryptMethod = ResourceDecrypter.findDecrypterMethod(nested.FindMethod(".ctor")); return new DecrypterInfoV3(resourceDecrypter) { Decrypter = decrypter }; } @@ -346,7 +347,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { return true; case Code.Newarr: - var arrayType = (TypeReference)instr.Operand; + var arrayType = (ITypeDefOrRef)instr.Operand; int arrayCount = ((Int32Value)emulator.pop()).value; if (arrayType.FullName == "System.Char") emulator.push(new UserValue(new char[arrayCount])); @@ -396,7 +397,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { break; case Code.Ldsfld: - emulator.push(new UserValue((FieldReference)instr.Operand)); + emulator.push(new UserValue((IField)instr.Operand)); break; default: @@ -409,30 +410,32 @@ namespace de4dot.code.deobfuscators.Babel_NET { } bool doCall(Instruction instr) { - var calledMethod = (MethodReference)instr.Operand; - if (calledMethod.FullName == "System.Byte[] System.Convert::FromBase64String(System.String)") { + var calledMethod = (IMethod)instr.Operand; + var sig = calledMethod.MethodSig; + var fn = calledMethod.FullName; + if (fn == "System.Byte[] System.Convert::FromBase64String(System.String)") { emulator.push(new UserValue(Convert.FromBase64String(((StringValue)emulator.pop()).value))); return true; } - else if (calledMethod.FullName == "System.String System.Text.Encoding::GetString(System.Byte[])") { + else if (fn == "System.String System.Text.Encoding::GetString(System.Byte[])") { emulator.push(new StringValue(Encoding.UTF8.GetString((byte[])((UserValue)emulator.pop()).obj))); return true; } - else if (calledMethod.FullName == "System.Int32 System.Int32::Parse(System.String)") { + else if (fn == "System.Int32 System.Int32::Parse(System.String)") { emulator.push(new Int32Value(int.Parse(((StringValue)emulator.pop()).value))); return true; } - else if (calledMethod.FullName == "System.String[] System.String::Split(System.Char[])") { + else if (fn == "System.String[] System.String::Split(System.Char[])") { var ary = (char[])((UserValue)emulator.pop()).obj; var s = ((StringValue)emulator.pop()).value; emulator.push(new UserValue(s.Split(ary))); return true; } - else if (calledMethod.HasThis && calledMethod.DeclaringType.FullName == "System.Reflection.Emit.ILGenerator" && calledMethod.Name == "Emit") { + else if (sig != null && sig.HasThis && calledMethod.DeclaringType.FullName == "System.Reflection.Emit.ILGenerator" && calledMethod.Name == "Emit") { Value operand = null; - if (calledMethod.Parameters.Count == 2) + if (calledMethod.MethodSig.GetParamCount() == 2) operand = emulator.pop(); - var opcode = reflectionToCecilOpCode((FieldReference)((UserValue)emulator.pop()).obj); + var opcode = reflectionToOpCode((IField)((UserValue)emulator.pop()).obj); emulator.pop(); // the this ptr addInstruction(new Instruction { OpCode = opcode, @@ -458,8 +461,8 @@ namespace de4dot.code.deobfuscators.Babel_NET { instructions.Add(instr); } - static OpCode reflectionToCecilOpCode(FieldReference reflectionField) { - var field = typeof(OpCodes).GetField(reflectionField.Name); + static OpCode reflectionToOpCode(IField reflectionField) { + var field = typeof(OpCodes).GetField(reflectionField.Name.String); if (field == null || field.FieldType != typeof(OpCode)) return null; return (OpCode)field.GetValue(null); @@ -499,9 +502,9 @@ namespace de4dot.code.deobfuscators.Babel_NET { return -1; } - static bool hasFieldType(IEnumerable fields, TypeReference fieldType) { + static bool hasFieldType(IEnumerable fields, TypeDef fieldType) { foreach (var field in fields) { - if (MemberReferenceHelper.compareTypes(field.FieldType, fieldType)) + if (new SigComparer().Equals(field.FieldSig.GetFieldType(), fieldType)) return true; } return false; @@ -517,32 +520,32 @@ namespace de4dot.code.deobfuscators.Babel_NET { continue; var ldci4 = instrs[index++]; - if (!DotNetUtils.isLdcI4(ldci4)) + if (!ldci4.IsLdcI4()) continue; var callvirt = instrs[index++]; if (callvirt.OpCode.Code != Code.Callvirt) continue; - var calledMethod = callvirt.Operand as MethodReference; + var calledMethod = callvirt.Operand as IMethod; if (calledMethod == null) continue; if (calledMethod.FullName != "System.Void System.Reflection.Emit.ILGenerator::Emit(System.Reflection.Emit.OpCode,System.Int32)") continue; - if (!DotNetUtils.isLdloc(instrs[index++])) + if (!instrs[index++].IsLdloc()) continue; var ldsfld2 = instrs[index++]; if (ldsfld2.OpCode.Code != Code.Ldsfld) continue; - var field = ldsfld2.Operand as FieldReference; + var field = ldsfld2.Operand as IField; if (field == null) continue; if (field.FullName != "System.Reflection.Emit.OpCode System.Reflection.Emit.OpCodes::Xor") continue; // Here if Babel.NET 5.5 - return DotNetUtils.getLdcI4Value(ldci4); + return ldci4.GetLdcI4Value(); } // Here if Babel.NET <= 5.0 @@ -552,11 +555,11 @@ namespace de4dot.code.deobfuscators.Babel_NET { bool checkFields(TypeDef type, string fieldType1, TypeDef fieldType2) { if (type.Fields.Count != 2) return false; - if (type.Fields[0].FieldType.FullName != fieldType1 && - type.Fields[1].FieldType.FullName != fieldType1) + if (type.Fields[0].FieldSig.GetFieldType().GetFullName() != fieldType1 && + type.Fields[1].FieldSig.GetFieldType().GetFullName() != fieldType1) return false; - if (!MemberReferenceHelper.compareTypes(type.Fields[0].FieldType, fieldType2) && - !MemberReferenceHelper.compareTypes(type.Fields[1].FieldType, fieldType2)) + if (!new SigComparer().Equals(type.Fields[0].FieldSig.GetFieldType(), fieldType2) && + !new SigComparer().Equals(type.Fields[1].FieldSig.GetFieldType(), fieldType2)) return false; return true; } diff --git a/de4dot.cui/Program.cs b/de4dot.cui/Program.cs index a487156a..47e0bb26 100644 --- a/de4dot.cui/Program.cs +++ b/de4dot.cui/Program.cs @@ -38,8 +38,8 @@ namespace de4dot.cui { return new List { new de4dot.code.deobfuscators.Unknown.DeobfuscatorInfo(), new de4dot.code.deobfuscators.Agile_NET.DeobfuscatorInfo(), -#if PORT new de4dot.code.deobfuscators.Babel_NET.DeobfuscatorInfo(), +#if PORT new de4dot.code.deobfuscators.CodeFort.DeobfuscatorInfo(), new de4dot.code.deobfuscators.CodeVeil.DeobfuscatorInfo(), new de4dot.code.deobfuscators.CodeWall.DeobfuscatorInfo(), diff --git a/dot10 b/dot10 index cdf5619a..5844915b 160000 --- a/dot10 +++ b/dot10 @@ -1 +1 @@ -Subproject commit cdf5619a39c2caf03b35569ef42383ca31971166 +Subproject commit 5844915b880f422af17a3bcd234829ba32dcb6e5