Browse Source

Fix #1189: Avoid crashing on invalid IL bytes.

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

58
ICSharpCode.Decompiler/CSharp/RequiredNamespaceCollector.cs

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

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

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

2
ICSharpCode.Decompiler/IL/ILReader.cs

@ -388,7 +388,7 @@ namespace ICSharpCode.Decompiler.IL @@ -388,7 +388,7 @@ namespace ICSharpCode.Decompiler.IL
} catch (BadImageFormatException ex) {
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)");
decodedInstruction.CheckInvariant(ILPhase.InILReader);
int end = reader.Offset;

4
ICSharpCode.Decompiler/TypeSystem/MetadataModule.cs

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

Loading…
Cancel
Save