From c8039d249ef2d154aa2e9148f7f0315bf153ad4d Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 6 Nov 2012 00:17:58 +0100 Subject: [PATCH] Add more checks when input has lots of invalid metadata --- blocks/cflow/InstructionEmulator.cs | 34 +++++++++++++++------ de4dot.code/ObfuscatedFile.cs | 4 ++- de4dot.code/deobfuscators/MethodStack.cs | 6 ++-- de4dot.code/deobfuscators/StringCounts.cs | 7 +++-- de4dot.code/deobfuscators/TypesRestorer.cs | 6 ++-- de4dot.code/renamer/Renamer.cs | 8 +++-- de4dot.code/renamer/VariableNameState.cs | 4 +-- de4dot.code/renamer/asmmodules/MethodDef.cs | 2 +- de4dot.code/renamer/asmmodules/Module.cs | 6 ++-- de4dot.code/renamer/asmmodules/Modules.cs | 2 ++ de4dot.code/renamer/asmmodules/TypeDef.cs | 10 +++--- dot10 | 2 +- 12 files changed, 60 insertions(+), 31 deletions(-) diff --git a/blocks/cflow/InstructionEmulator.cs b/blocks/cflow/InstructionEmulator.cs index 5324a400..e2ed4bc6 100644 --- a/blocks/cflow/InstructionEmulator.cs +++ b/blocks/cflow/InstructionEmulator.cs @@ -163,6 +163,8 @@ namespace de4dot.blocks.cflow { } public Value getArg(Parameter arg) { + if (arg == null) + return new UnknownValue(); return getArg(arg.Index); } @@ -173,11 +175,13 @@ namespace de4dot.blocks.cflow { } public void setArg(Parameter arg, Value value) { - setArg(arg.Index, value); + if (arg != null) + setArg(arg.Index, value); } public void makeArgUnknown(Parameter arg) { - setArg(arg, getUnknownArg(arg.Index)); + if (arg != null) + setArg(arg, getUnknownArg(arg.Index)); } void setArg(int index, Value value) { @@ -194,15 +198,19 @@ namespace de4dot.blocks.cflow { } public Value getLocal(Local local) { + if (local == null) + return new UnknownValue(); return getLocal(local.Index); } public void setLocal(Local local, Value value) { - setLocal(local.Index, value); + if (local != null) + setLocal(local.Index, value); } public void makeLocalUnknown(Local local) { - setLocal(local.Index, getUnknownLocal(local.Index)); + if (local != null) + setLocal(local.Index, getUnknownLocal(local.Index)); } void setLocal(int index, Value value) { @@ -247,7 +255,7 @@ namespace de4dot.blocks.cflow { case Code.Starg: case Code.Starg_S: emulate_Starg((Parameter)instr.Operand); break; case Code.Stloc: - case Code.Stloc_S: emulate_Stloc(((Local)instr.Operand).Index); break; + case Code.Stloc_S: emulate_Stloc((Local)instr.Operand); break; case Code.Stloc_0: emulate_Stloc(0); break; case Code.Stloc_1: emulate_Stloc(1); break; case Code.Stloc_2: emulate_Stloc(2); break; @@ -269,7 +277,7 @@ namespace de4dot.blocks.cflow { case Code.Ldarga: case Code.Ldarga_S: emulate_Ldarga((Parameter)instr.Operand); break; case Code.Ldloca: - case Code.Ldloca_S: emulate_Ldloca(((Local)instr.Operand).Index); break; + case Code.Ldloca_S: emulate_Ldloca((Local)instr.Operand); break; case Code.Dup: valueStack.copyTop(); break; @@ -837,7 +845,11 @@ namespace de4dot.blocks.cflow { } void emulate_Starg(Parameter arg) { - setArg(arg.Index, valueStack.pop()); + setArg(arg == null ? -1 : arg.Index, valueStack.pop()); + } + + void emulate_Stloc(Local local) { + emulate_Stloc(local == null ? -1 : local.Index); } void emulate_Stloc(int index) { @@ -849,6 +861,10 @@ namespace de4dot.blocks.cflow { makeArgUnknown(arg); } + void emulate_Ldloca(Local local) { + emulate_Ldloca(local == null ? -1 : local.Index); + } + void emulate_Ldloca(int index) { valueStack.pushUnknown(); setLocal(index, getUnknownLocal(index)); @@ -867,7 +883,7 @@ namespace de4dot.blocks.cflow { instr.CalculateStackUsage(out pushes, out pops); valueStack.pop(pops); if (pushes == 1) - valueStack.push(getUnknownValue(method.MethodSig.RetType)); + valueStack.push(getUnknownValue(method.MethodSig.GetRetType())); else valueStack.push(pushes); } @@ -901,7 +917,7 @@ namespace de4dot.blocks.cflow { void emulateLoadField(IField field) { if (field != null) - valueStack.push(getUnknownValue(field.FieldSig.Type)); + valueStack.push(getUnknownValue(field.FieldSig.GetFieldType())); else valueStack.pushUnknown(); } diff --git a/de4dot.code/ObfuscatedFile.cs b/de4dot.code/ObfuscatedFile.cs index 1b611995..9debb82b 100644 --- a/de4dot.code/ObfuscatedFile.cs +++ b/de4dot.code/ObfuscatedFile.cs @@ -435,7 +435,7 @@ namespace de4dot.code { foreach (var method in type.Methods) { if (!method.IsStatic) continue; - if (method.MethodSig.RetType.ElementType != ElementType.String && method.MethodSig.RetType.ElementType != ElementType.Object) + if (method.MethodSig.GetRetType().GetElementType() != ElementType.String && method.MethodSig.GetRetType().GetElementType() != ElementType.Object) continue; if (methodName != null && methodName != method.Name) continue; @@ -664,6 +664,8 @@ namespace de4dot.code { } static bool getMethodImplOptions(CustomAttribute cattr, ref int value) { + if (cattr.IsRawBlob) + return false; if (cattr.Arguments.Count != 1) return false; if (cattr.Arguments[0].Type.ElementType != ElementType.I2 && diff --git a/de4dot.code/deobfuscators/MethodStack.cs b/de4dot.code/deobfuscators/MethodStack.cs index 3979c93a..525b19f0 100644 --- a/de4dot.code/deobfuscators/MethodStack.cs +++ b/de4dot.code/deobfuscators/MethodStack.cs @@ -204,7 +204,7 @@ namespace de4dot.code.deobfuscators { var calledMethod = pushInstr.Operand as IMethod; if (calledMethod == null) return null; - type = calledMethod.MethodSig.RetType; + type = calledMethod.MethodSig.GetRetType(); break; case Code.Newarr: @@ -270,7 +270,7 @@ namespace de4dot.code.deobfuscators { var field = pushInstr.Operand as IField; if (field == null || field.FieldSig == null) return null; - type = field.FieldSig.Type; + type = field.FieldSig.GetFieldType(); break; case Code.Ldflda: @@ -278,7 +278,7 @@ namespace de4dot.code.deobfuscators { var field2 = pushInstr.Operand as IField; if (field2 == null || field2.FieldSig == null) return null; - type = createByReferenceType(field2.FieldSig.Type); + type = createByReferenceType(field2.FieldSig.GetFieldType()); break; case Code.Ldelema: diff --git a/de4dot.code/deobfuscators/StringCounts.cs b/de4dot.code/deobfuscators/StringCounts.cs index 96580e5b..7e2e251e 100644 --- a/de4dot.code/deobfuscators/StringCounts.cs +++ b/de4dot.code/deobfuscators/StringCounts.cs @@ -77,8 +77,11 @@ namespace de4dot.code.deobfuscators { void init(IEnumerable fields) { if (fields == null) return; - foreach (var field in fields) - add(field.FieldSig.Type.FullName); + foreach (var field in fields) { + var type = field.FieldSig.GetFieldType(); + if (type != null) + add(type.FullName); + } } } diff --git a/de4dot.code/deobfuscators/TypesRestorer.cs b/de4dot.code/deobfuscators/TypesRestorer.cs index f7e065fb..311eb0e0 100644 --- a/de4dot.code/deobfuscators/TypesRestorer.cs +++ b/de4dot.code/deobfuscators/TypesRestorer.cs @@ -256,7 +256,7 @@ namespace de4dot.code.deobfuscators { if (!method.IsStatic || method.CilBody == null) return; - bool fixReturnType = isUnknownType(method.MethodSig.RetType); + bool fixReturnType = isUnknownType(method.MethodSig.GetRetType()); argInfos.Clear(); foreach (var arg in method.Parameters) { @@ -433,7 +433,7 @@ namespace de4dot.code.deobfuscators { bool addMethodArgType(IGenericParameterProvider gpp, Parameter methodParam, IField field) { if (field == null || field.FieldSig == null) return false; - return addMethodArgType(gpp, methodParam, field.FieldSig.Type); + return addMethodArgType(gpp, methodParam, field.FieldSig.GetFieldType()); } bool addMethodArgType(IGenericParameterProvider gpp, Parameter methodParam, Local otherLocal) { @@ -631,7 +631,7 @@ namespace de4dot.code.deobfuscators { var field = o as FieldDef; if (field != null) - return field.FieldSig != null && field.FieldSig.Type != null && field.FieldSig.Type.ElementType == ElementType.Object; + return field.FieldSig.GetFieldType().GetElementType() == ElementType.Object; throw new ApplicationException(string.Format("Unknown type: {0}", o.GetType())); } diff --git a/de4dot.code/renamer/Renamer.cs b/de4dot.code/renamer/Renamer.cs index 8190b30b..95d4d967 100644 --- a/de4dot.code/renamer/Renamer.cs +++ b/de4dot.code/renamer/Renamer.cs @@ -312,7 +312,7 @@ namespace de4dot.code.renamer { if (param.IsReturnParameter) Log.v("RetParam: {0} => {1}", Utils.removeNewlines(paramInfo.oldName), Utils.removeNewlines(paramInfo.newName)); else - Log.v("Param ({0}/{1}): {2} => {3}", param.ParameterDefinition.MethodSigIndex + 1, methodDef.MethodDef.MethodSig.Params.Count, Utils.removeNewlines(paramInfo.oldName), Utils.removeNewlines(paramInfo.newName)); + Log.v("Param ({0}/{1}): {2} => {3}", param.ParameterDefinition.MethodSigIndex + 1, methodDef.MethodDef.MethodSig.GetParamCount(), Utils.removeNewlines(paramInfo.oldName), Utils.removeNewlines(paramInfo.newName)); } } @@ -574,6 +574,8 @@ namespace de4dot.code.renamer { return null; var sig = propMethod.MethodDef.MethodSig; + if (sig == null) + return null; var propType = sig.RetType; var propDef = createProperty(ownerType, name, propType, propMethod.MethodDef, null); if (propDef == null) @@ -601,7 +603,7 @@ namespace de4dot.code.renamer { return null; var sig = propMethod.MethodDef.MethodSig; - if (sig.Params.Count == 0) + if (sig == null || sig.Params.Count == 0) return null; var propType = sig.Params[sig.Params.Count - 1]; var propDef = createProperty(ownerType, name, propType, null, propMethod.MethodDef); @@ -1390,7 +1392,7 @@ namespace de4dot.code.renamer { if (methodType == PropertyMethodType.Setter) propType = propMethod.ParamDefs[propMethod.ParamDefs.Count - 1].ParameterDefinition.Type; else - propType = propMethod.MethodDef.MethodSig.RetType; + propType = propMethod.MethodDef.MethodSig.GetRetType(); if (type == null) type = propType; else if (!new SigComparer().Equals(type, propType)) diff --git a/de4dot.code/renamer/VariableNameState.cs b/de4dot.code/renamer/VariableNameState.cs index 432c547a..c8bd88f1 100644 --- a/de4dot.code/renamer/VariableNameState.cs +++ b/de4dot.code/renamer/VariableNameState.cs @@ -87,7 +87,7 @@ namespace de4dot.code.renamer { } public string getNewPropertyName(PropertyDef propertyDefinition) { - var propType = propertyDefinition.PropertySig.RetType; + var propType = propertyDefinition.PropertySig.GetRetType(); string newName; if (isGeneric(propType)) newName = existingPropertyNames.getName(propertyDefinition.Name, genericPropertyNameCreator); @@ -145,7 +145,7 @@ namespace de4dot.code.renamer { } public string getNewFieldName(FieldDef field) { - return existingVariableNames.getName(field.Name, () => variableNameCreator.create(field.FieldSig.Type)); + return existingVariableNames.getName(field.Name, () => variableNameCreator.create(field.FieldSig.GetFieldType())); } public string getNewFieldName(string oldName, INameCreator nameCreator) { diff --git a/de4dot.code/renamer/asmmodules/MethodDef.cs b/de4dot.code/renamer/asmmodules/MethodDef.cs index 53c88fe1..e0fd51c1 100644 --- a/de4dot.code/renamer/asmmodules/MethodDef.cs +++ b/de4dot.code/renamer/asmmodules/MethodDef.cs @@ -66,7 +66,7 @@ namespace de4dot.code.renamer.asmmodules { public MMethodDef(MethodDef methodDefinition, MTypeDef owner, int index) : base(methodDefinition, owner, index) { genericParams = MGenericParamDef.createGenericParamDefList(MethodDef.GenericParams); - visibleBaseIndex = methodDefinition.MethodSig.HasThis ? 1 : 0; + visibleBaseIndex = methodDefinition.MethodSig != null && methodDefinition.MethodSig.HasThis ? 1 : 0; for (int i = 0; i < methodDefinition.Parameters.Count; i++) { var param = methodDefinition.Parameters[i]; if (param.IsNormalMethodParameter) diff --git a/de4dot.code/renamer/asmmodules/Module.cs b/de4dot.code/renamer/asmmodules/Module.cs index 9f6d9850..d4f6e1c9 100644 --- a/de4dot.code/renamer/asmmodules/Module.cs +++ b/de4dot.code/renamer/asmmodules/Module.cs @@ -155,6 +155,8 @@ namespace de4dot.code.renamer.asmmodules { var typeDef = resolver.resolveType(cattr.AttributeType); if (typeDef == null) continue; + if (cattr.NamedArguments == null) + continue; for (int i = 0; i < cattr.NamedArguments.Count; i++) { var namedArg = cattr.NamedArguments[i]; @@ -191,7 +193,7 @@ namespace de4dot.code.renamer.asmmodules { foreach (var fieldDef in typeDef.AllFields) { if (fieldDef.FieldDef.Name != name) continue; - if (new SigComparer().Equals(fieldDef.FieldDef.FieldSig.Type, fieldType)) + if (new SigComparer().Equals(fieldDef.FieldDef.FieldSig.GetFieldType(), fieldType)) return fieldDef; } @@ -207,7 +209,7 @@ namespace de4dot.code.renamer.asmmodules { foreach (var propDef in typeDef.AllProperties) { if (propDef.PropertyDef.Name != name) continue; - if (new SigComparer().Equals(propDef.PropertyDef.PropertySig.RetType, propType)) + if (new SigComparer().Equals(propDef.PropertyDef.PropertySig.GetRetType(), propType)) return propDef; } diff --git a/de4dot.code/renamer/asmmodules/Modules.cs b/de4dot.code/renamer/asmmodules/Modules.cs index 4b9629a4..b6eb76e7 100644 --- a/de4dot.code/renamer/asmmodules/Modules.cs +++ b/de4dot.code/renamer/asmmodules/Modules.cs @@ -373,6 +373,8 @@ namespace de4dot.code.renamer.asmmodules { // Returns null if it's a non-loaded module/assembly IEnumerable findModules(ITypeDefOrRef type) { + if (type == null) + return null; var scope = type.Scope; if (scope == null) return null; diff --git a/de4dot.code/renamer/asmmodules/TypeDef.cs b/de4dot.code/renamer/asmmodules/TypeDef.cs index 1f525956..54a61f60 100644 --- a/de4dot.code/renamer/asmmodules/TypeDef.cs +++ b/de4dot.code/renamer/asmmodules/TypeDef.cs @@ -534,8 +534,8 @@ namespace de4dot.code.renamer.asmmodules { foreach (var ifaceInfo in interfaces) { foreach (var methodsList in ifaceInfo.typeDef.virtualMethodInstances.getMethods()) { - if (methodsList.Count != 1) // Never happens - throw new ApplicationException("Interface with more than one method in the list"); + if (methodsList.Count < 1) + continue; var methodInst = methodsList[0]; var ifaceMethod = methodInst.origMethodDef; if (!ifaceMethod.isVirtual()) @@ -569,8 +569,8 @@ namespace de4dot.code.renamer.asmmodules { } foreach (var ifaceInfo in allImplementedInterfaces.Keys) { foreach (var methodsList in ifaceInfo.typeDef.virtualMethodInstances.getMethods()) { - if (methodsList.Count != 1) // Never happens - throw new ApplicationException("Interface with more than one method in the list"); + if (methodsList.Count < 1) + continue; var ifaceMethod = methodsList[0].origMethodDef; if (!ifaceMethod.isVirtual()) continue; @@ -690,6 +690,8 @@ namespace de4dot.code.renamer.asmmodules { } MemberRef simpleClone(MethodDef methodRef, ITypeDefOrRef declaringType) { + if (module == null) + return new MemberRefUser(null, methodRef.Name, methodRef.MethodSig, declaringType); var mr = new MemberRefUser(module.ModuleDefMD, methodRef.Name, methodRef.MethodSig, declaringType); return module.ModuleDefMD.UpdateRowId(mr); } diff --git a/dot10 b/dot10 index 83714ec1..d7ccb50d 160000 --- a/dot10 +++ b/dot10 @@ -1 +1 @@ -Subproject commit 83714ec1536ec43ca5dd1ef139f767e20902cd02 +Subproject commit d7ccb50d4ea85a48c05132dff8ae1e38c4dcbba2