Browse Source

Make ValidateConstructor safe

pull/2005/head
Siegfried Pammer 5 years ago
parent
commit
d457ef38f4
  1. 69
      ICSharpCode.Decompiler/IL/Transforms/TransformDisplayClassUsage.cs

69
ICSharpCode.Decompiler/IL/Transforms/TransformDisplayClassUsage.cs

@ -151,6 +151,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
var result = AnalyzeVariable(v); var result = AnalyzeVariable(v);
if (result == null) if (result == null)
continue; continue;
context.Step($"Detected display-class {v}", result.Initializer ?? f.Body);
displayClasses.Add(v, result); displayClasses.Add(v, result);
} }
} }
@ -266,38 +267,42 @@ namespace ICSharpCode.Decompiler.IL.Transforms
private bool ValidateConstructor(IMethod method) private bool ValidateConstructor(IMethod method)
{ {
if (method.Parameters.Count != 0) try {
return false; if (method.Parameters.Count != 0)
var handle = (MethodDefinitionHandle)method.MetadataToken; return false;
var module = (MetadataModule)method.ParentModule; var handle = (MethodDefinitionHandle)method.MetadataToken;
var file = module.PEFile; var module = (MetadataModule)method.ParentModule;
if (handle.IsNil || file == null) var file = module.PEFile;
return false; if (handle.IsNil || file != context.PEFile)
var def = file.Metadata.GetMethodDefinition(handle); return false;
if (def.RelativeVirtualAddress == 0) var def = file.Metadata.GetMethodDefinition(handle);
return false; if (def.RelativeVirtualAddress == 0)
var body = file.Reader.GetMethodBody(def.RelativeVirtualAddress); return false;
if (!body.LocalSignature.IsNil) var body = file.Reader.GetMethodBody(def.RelativeVirtualAddress);
return false; if (!body.LocalSignature.IsNil || body.ExceptionRegions.Length != 0)
var reader = body.GetILReader(); return false;
if (reader.Length != 7) var reader = body.GetILReader();
return false; if (reader.Length != 7)
// IL_0000: ldarg.0 return false;
// IL_0001: call instance void [mscorlib]System.Object::.ctor() // IL_0000: ldarg.0
// IL_0006: ret // IL_0001: call instance void [mscorlib]System.Object::.ctor()
if (reader.DecodeOpCode() != ILOpCode.Ldarg_0) // IL_0006: ret
return false; if (reader.DecodeOpCode() != ILOpCode.Ldarg_0)
if (reader.DecodeOpCode() != ILOpCode.Call) return false;
return false; if (reader.DecodeOpCode() != ILOpCode.Call)
var baseCtorHandle = MetadataTokenHelpers.EntityHandleOrNil(reader.ReadInt32()); return false;
if (baseCtorHandle.IsNil) var baseCtorHandle = MetadataTokenHelpers.EntityHandleOrNil(reader.ReadInt32());
return false; if (baseCtorHandle.IsNil)
var objectCtor = module.ResolveMethod(baseCtorHandle, new TypeSystem.GenericContext()); return false;
if (!objectCtor.DeclaringType.IsKnownType(KnownTypeCode.Object)) var objectCtor = module.ResolveMethod(baseCtorHandle, new TypeSystem.GenericContext());
return false; if (!objectCtor.DeclaringType.IsKnownType(KnownTypeCode.Object))
if (objectCtor.Parameters.Count != 0) return false;
if (!objectCtor.IsConstructor || objectCtor.Parameters.Count != 0)
return false;
return reader.DecodeOpCode() == ILOpCode.Ret;
} catch (BadImageFormatException) {
return false; return false;
return reader.DecodeOpCode() == ILOpCode.Ret; }
} }
VariableToDeclare AddVariable(DisplayClass result, ILInstruction init, out IField field) VariableToDeclare AddVariable(DisplayClass result, ILInstruction init, out IField field)
@ -333,6 +338,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return declaredVar.CanPropagate; return declaredVar.CanPropagate;
} }
return true; return true;
case StLoc stloc:
return true;
default: default:
return false; return false;
} }

Loading…
Cancel
Save