Browse Source

#1189: Fix various exceptions in ILReader when reading invalid IL.

pull/1198/head
Daniel Grunwald 7 years ago
parent
commit
2b5db1d005
  1. 73
      ICSharpCode.Decompiler/IL/ILReader.cs
  2. 2
      ICSharpCode.Decompiler/TypeSystem/MetadataAssembly.cs

73
ICSharpCode.Decompiler/IL/ILReader.cs

@ -100,25 +100,37 @@ namespace ICSharpCode.Decompiler.IL @@ -100,25 +100,37 @@ namespace ICSharpCode.Decompiler.IL
EntityHandle ReadAndDecodeMetadataToken()
{
return MetadataTokens.EntityHandle(reader.ReadInt32());
int token = reader.ReadInt32();
if (token < 0) {
// SRM uses negative tokens as "virtual tokens" and can get confused
// if we manually create them.
throw new BadImageFormatException("Invalid metadata token");
}
return MetadataTokens.EntityHandle(token);
}
IType ReadAndDecodeTypeReference()
{
var typeReference = MetadataTokens.EntityHandle(reader.ReadInt32());
var typeReference = ReadAndDecodeMetadataToken();
return typeSystem.ResolveAsType(typeReference);
}
IMethod ReadAndDecodeMethodReference()
{
var methodReference = MetadataTokens.EntityHandle(reader.ReadInt32());
return typeSystem.ResolveAsMethod(methodReference);
var methodReference = ReadAndDecodeMetadataToken();
IMethod m = typeSystem.ResolveAsMethod(methodReference);
if (m == null)
throw new BadImageFormatException("Invalid method token");
return m;
}
IField ReadAndDecodeFieldReference()
{
var fieldReference = MetadataTokens.EntityHandle(reader.ReadInt32());
return typeSystem.ResolveAsField(fieldReference);
var fieldReference = ReadAndDecodeMetadataToken();
IField f = typeSystem.ResolveAsField(fieldReference);
if (f == null)
throw new BadImageFormatException("Invalid field token");
return f;
}
ILVariable[] InitLocalVariables()
@ -337,7 +349,12 @@ namespace ICSharpCode.Decompiler.IL @@ -337,7 +349,12 @@ namespace ICSharpCode.Decompiler.IL
cancellationToken.ThrowIfCancellationRequested();
int start = reader.Offset;
StoreStackForOffset(start, ref currentStack);
ILInstruction decodedInstruction = DecodeInstruction();
ILInstruction decodedInstruction;
try {
decodedInstruction = DecodeInstruction();
} catch (BadImageFormatException ex) {
decodedInstruction = new InvalidBranch(ex.Message);
}
if (decodedInstruction.ResultType == StackType.Unknown)
Warn("Unknown result type (might be due to invalid IL or missing references)");
decodedInstruction.CheckInvariant(ILPhase.InILReader);
@ -1131,34 +1148,60 @@ namespace ICSharpCode.Decompiler.IL @@ -1131,34 +1148,60 @@ namespace ICSharpCode.Decompiler.IL
private ILInstruction Ldarg(int v)
{
return new LdLoc(parameterVariables[v]);
if (v >= 0 && v < parameterVariables.Length) {
return new LdLoc(parameterVariables[v]);
} else {
return new InvalidExpression($"ldarg {v} (out-of-bounds)");
}
}
private ILInstruction Ldarga(int v)
{
return new LdLoca(parameterVariables[v]);
if (v >= 0 && v < parameterVariables.Length) {
return new LdLoca(parameterVariables[v]);
} else {
return new InvalidExpression($"ldarga {v} (out-of-bounds)");
}
}
private ILInstruction Starg(int v)
{
return new StLoc(parameterVariables[v], Pop(parameterVariables[v].StackType));
if (v >= 0 && v < parameterVariables.Length) {
return new StLoc(parameterVariables[v], Pop(parameterVariables[v].StackType));
} else {
Pop();
return new InvalidExpression($"starg {v} (out-of-bounds)");
}
}
private ILInstruction Ldloc(int v)
{
return new LdLoc(localVariables[v]);
if (v >= 0 && v < localVariables.Length) {
return new LdLoc(localVariables[v]);
} else {
return new InvalidExpression($"ldloc {v} (out-of-bounds)");
}
}
private ILInstruction Ldloca(int v)
{
return new LdLoca(localVariables[v]);
if (v >= 0 && v < localVariables.Length) {
return new LdLoca(localVariables[v]);
} else {
return new InvalidExpression($"ldloca {v} (out-of-bounds)");
}
}
private ILInstruction Stloc(int v)
{
return new StLoc(localVariables[v], Pop(localVariables[v].StackType)) {
ILStackWasEmpty = currentStack.IsEmpty
};
if (v >= 0 && v < localVariables.Length) {
return new StLoc(localVariables[v], Pop(localVariables[v].StackType)) {
ILStackWasEmpty = currentStack.IsEmpty
};
} else {
Pop();
return new InvalidExpression($"stloc {v} (out-of-bounds)");
}
}
private ILInstruction LdElem(IType type)

2
ICSharpCode.Decompiler/TypeSystem/MetadataAssembly.cs

@ -264,7 +264,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -264,7 +264,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
case HandleKind.MethodSpecification:
return ResolveMethodSpecification((MethodSpecificationHandle)methodReference, context, expandVarArgs: true);
default:
throw new ArgumentException("HandleKind must be either a MethodDefinition, MemberReference or MethodSpecification", nameof(methodReference));
throw new BadImageFormatException("Metadata token must be either a methoddef, memberref or methodspec");
}
}

Loading…
Cancel
Save