Browse Source

Fix #1189: Avoid crashing on invalid IL bytes.

pull/1213/head
Daniel Grunwald 8 years ago
parent
commit
4e8ebbf7f4
  1. 19
      ICSharpCode.Decompiler/CSharp/OutputVisitor/InsertMissingTokensDecorator.cs
  2. 58
      ICSharpCode.Decompiler/CSharp/RequiredNamespaceCollector.cs
  3. 10
      ICSharpCode.Decompiler/CSharp/Syntax/Expressions/ErrorExpression.cs
  4. 2
      ICSharpCode.Decompiler/IL/ILReader.cs
  5. 4
      ICSharpCode.Decompiler/TypeSystem/MetadataModule.cs

19
ICSharpCode.Decompiler/CSharp/OutputVisitor/InsertMissingTokensDecorator.cs

@ -68,13 +68,18 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor
public override void WriteToken(Role role, string token) public override void WriteToken(Role role, string token)
{ {
EmptyStatement node = nodes.Peek().LastOrDefault() as EmptyStatement; switch (nodes.Peek().LastOrDefault()) {
if (node == null) { case EmptyStatement emptyStatement:
CSharpTokenNode t = new CSharpTokenNode(locationProvider.Location, (TokenRole)role); emptyStatement.Location = locationProvider.Location;
t.Role = role; break;
currentList.Add(t); case ErrorExpression errorExpression:
} else { errorExpression.Location = locationProvider.Location;
node.Location = locationProvider.Location; break;
default:
CSharpTokenNode t = new CSharpTokenNode(locationProvider.Location, (TokenRole)role);
t.Role = role;
currentList.Add(t);
break;
} }
base.WriteToken(role, token); base.WriteToken(role, token);
} }

58
ICSharpCode.Decompiler/CSharp/RequiredNamespaceCollector.cs

@ -188,12 +188,24 @@ namespace ICSharpCode.Decompiler.CSharp
} }
foreach (var region in method.ExceptionRegions) { foreach (var region in method.ExceptionRegions) {
if (region.CatchType.IsNil) continue; if (region.CatchType.IsNil)
CollectNamespacesForTypeReference(module.ResolveType(region.CatchType, genericContext), namespaces); continue;
IType ty;
try {
ty = module.ResolveType(region.CatchType, genericContext);
} catch (BadImageFormatException) {
continue;
}
CollectNamespacesForTypeReference(ty, namespaces);
} }
while (instructions.RemainingBytes > 0) { while (instructions.RemainingBytes > 0) {
var opCode = instructions.DecodeOpCode(); ILOpCode opCode;
try {
opCode = instructions.DecodeOpCode();
} catch (BadImageFormatException) {
return;
}
switch (opCode.GetOperandType()) { switch (opCode.GetOperandType()) {
case Metadata.OperandType.Field: case Metadata.OperandType.Field:
case Metadata.OperandType.Method: case Metadata.OperandType.Method:
@ -201,24 +213,46 @@ namespace ICSharpCode.Decompiler.CSharp
case Metadata.OperandType.Tok: case Metadata.OperandType.Tok:
case Metadata.OperandType.Type: case Metadata.OperandType.Type:
var handle = MetadataTokenHelpers.EntityHandleOrNil(instructions.ReadInt32()); var handle = MetadataTokenHelpers.EntityHandleOrNil(instructions.ReadInt32());
if (handle.IsNil) break; if (handle.IsNil)
break;
switch (handle.Kind) { switch (handle.Kind) {
case HandleKind.TypeDefinition: case HandleKind.TypeDefinition:
case HandleKind.TypeReference: case HandleKind.TypeReference:
case HandleKind.TypeSpecification: case HandleKind.TypeSpecification:
CollectNamespacesForTypeReference(module.ResolveType(handle, genericContext), namespaces); IType type;
try {
type = module.ResolveType(handle, genericContext);
} catch (BadImageFormatException) {
break;
}
CollectNamespacesForTypeReference(type, namespaces);
break; break;
case HandleKind.FieldDefinition: case HandleKind.FieldDefinition:
case HandleKind.MethodDefinition: case HandleKind.MethodDefinition:
case HandleKind.MethodSpecification: case HandleKind.MethodSpecification:
case HandleKind.MemberReference: case HandleKind.MemberReference:
CollectNamespacesForMemberReference(module.ResolveEntity(handle, genericContext) as IMember, IMember member;
module, namespaces); try {
member = module.ResolveEntity(handle, genericContext) as IMember;
} catch (BadImageFormatException) {
break;
}
CollectNamespacesForMemberReference(member, module, namespaces);
break; break;
case HandleKind.StandaloneSignature: case HandleKind.StandaloneSignature:
var sig = metadata.GetStandaloneSignature((StandaloneSignatureHandle)handle); StandaloneSignature sig;
try {
sig = metadata.GetStandaloneSignature((StandaloneSignatureHandle)handle);
} catch (BadImageFormatException) {
break;
}
if (sig.GetKind() == StandaloneSignatureKind.Method) { if (sig.GetKind() == StandaloneSignatureKind.Method) {
var methodSig = module.DecodeMethodSignature((StandaloneSignatureHandle)handle, genericContext); MethodSignature<IType> methodSig;
try {
methodSig = module.DecodeMethodSignature((StandaloneSignatureHandle)handle, genericContext);
} catch (BadImageFormatException) {
break;
}
CollectNamespacesForTypeReference(methodSig.ReturnType, namespaces); CollectNamespacesForTypeReference(methodSig.ReturnType, namespaces);
foreach (var paramType in methodSig.ParameterTypes) { foreach (var paramType in methodSig.ParameterTypes) {
CollectNamespacesForTypeReference(paramType, namespaces); CollectNamespacesForTypeReference(paramType, namespaces);
@ -228,7 +262,11 @@ namespace ICSharpCode.Decompiler.CSharp
} }
break; break;
default: default:
instructions.SkipOperand(opCode); try {
instructions.SkipOperand(opCode);
} catch (BadImageFormatException) {
return;
}
break; break;
} }
} }

10
ICSharpCode.Decompiler/CSharp/Syntax/Expressions/ErrorExpression.cs

@ -29,17 +29,17 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
{ {
public class ErrorExpression : Expression public class ErrorExpression : Expression
{ {
TextLocation location; public TextLocation Location { get; set; }
public override TextLocation StartLocation { public override TextLocation StartLocation {
get { get {
return location; return Location;
} }
} }
public override TextLocation EndLocation { public override TextLocation EndLocation {
get { get {
return location; return Location;
} }
} }
@ -54,7 +54,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
public ErrorExpression (TextLocation location) public ErrorExpression (TextLocation location)
{ {
this.location = location; this.Location = location;
} }
public ErrorExpression (string error) public ErrorExpression (string error)
@ -64,7 +64,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
public ErrorExpression (string error, TextLocation location) public ErrorExpression (string error, TextLocation location)
{ {
this.location = location; this.Location = location;
this.Error = error; this.Error = error;
} }

2
ICSharpCode.Decompiler/IL/ILReader.cs

@ -388,7 +388,7 @@ namespace ICSharpCode.Decompiler.IL
} catch (BadImageFormatException ex) { } catch (BadImageFormatException ex) {
decodedInstruction = new InvalidBranch(ex.Message); decodedInstruction = new InvalidBranch(ex.Message);
} }
if (decodedInstruction.ResultType == StackType.Unknown) if (decodedInstruction.ResultType == StackType.Unknown && decodedInstruction.OpCode != OpCode.InvalidBranch && UnpackPush(decodedInstruction).OpCode != OpCode.InvalidExpression)
Warn("Unknown result type (might be due to invalid IL or missing references)"); Warn("Unknown result type (might be due to invalid IL or missing references)");
decodedInstruction.CheckInvariant(ILPhase.InILReader); decodedInstruction.CheckInvariant(ILPhase.InILReader);
int end = reader.Offset; int end = reader.Offset;

4
ICSharpCode.Decompiler/TypeSystem/MetadataModule.cs

@ -278,9 +278,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
case HandleKind.ExportedType: case HandleKind.ExportedType:
return ResolveForwardedType(metadata.GetExportedType((ExportedTypeHandle)typeRefDefSpec)); return ResolveForwardedType(metadata.GetExportedType((ExportedTypeHandle)typeRefDefSpec));
default: default:
Debug.Fail("Not a type handle"); throw new BadImageFormatException("Not a type handle");
ty = SpecialType.UnknownType;
break;
} }
ty = ApplyAttributeTypeVisitor.ApplyAttributesToType(ty, Compilation, typeAttributes, metadata, customOptions); ty = ApplyAttributeTypeVisitor.ApplyAttributesToType(ty, Compilation, typeAttributes, metadata, customOptions);
return ty; return ty;

Loading…
Cancel
Save