Browse Source

Add Visual Basic symbolic execution option which ignores overflow checks

pull/2874/head
ElektroKill 2 years ago
parent
commit
0cbd9a4faa
No known key found for this signature in database
GPG Key ID: 7E3C5C084E40E3EC
  1. 10
      ICSharpCode.Decompiler/IL/ControlFlow/StateRangeAnalysis.cs
  2. 6
      ICSharpCode.Decompiler/IL/ControlFlow/SymbolicExecution.cs
  3. 2
      ICSharpCode.Decompiler/IL/ControlFlow/YieldReturnDecompiler.cs

10
ICSharpCode.Decompiler/IL/ControlFlow/StateRangeAnalysis.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
// Copyright (c) 2012 AlphaSierraPapa for the SharpDevelop Team
// Copyright (c) 2012 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
@ -58,6 +58,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -58,6 +58,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
public CancellationToken CancellationToken;
readonly StateRangeAnalysisMode mode;
readonly IField? stateField;
readonly bool legacyVisualBasic;
readonly SymbolicEvaluationContext evalContext;
readonly Dictionary<Block, LongSet> ranges = new Dictionary<Block, LongSet>();
@ -67,10 +68,11 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -67,10 +68,11 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
internal ILVariable? doFinallyBodies;
internal ILVariable? skipFinallyBodies;
public StateRangeAnalysis(StateRangeAnalysisMode mode, IField? stateField, ILVariable? cachedStateVar = null)
public StateRangeAnalysis(StateRangeAnalysisMode mode, IField? stateField, ILVariable? cachedStateVar = null, bool legacyVisualBasic = false)
{
this.mode = mode;
this.stateField = stateField;
this.legacyVisualBasic = legacyVisualBasic;
if (mode == StateRangeAnalysisMode.IteratorDispose)
{
finallyMethodToStateRange = new Dictionary<IMethod, LongSet>();
@ -80,7 +82,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -80,7 +82,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
rangesForLeave = new Dictionary<BlockContainer, LongSet>();
}
evalContext = new SymbolicEvaluationContext(stateField);
evalContext = new SymbolicEvaluationContext(stateField, legacyVisualBasic);
if (cachedStateVar != null)
evalContext.AddStateVariable(cachedStateVar);
}
@ -94,7 +96,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -94,7 +96,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
/// </summary>
internal StateRangeAnalysis CreateNestedAnalysis()
{
var sra = new StateRangeAnalysis(mode, stateField);
var sra = new StateRangeAnalysis(mode, stateField, legacyVisualBasic: legacyVisualBasic);
sra.doFinallyBodies = this.doFinallyBodies;
sra.skipFinallyBodies = this.skipFinallyBodies;
foreach (var v in this.evalContext.StateVariables)

6
ICSharpCode.Decompiler/IL/ControlFlow/SymbolicExecution.cs

@ -99,10 +99,12 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -99,10 +99,12 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
class SymbolicEvaluationContext
{
readonly IField stateField;
readonly bool legacyVisualBasic;
readonly List<ILVariable> stateVariables = new List<ILVariable>();
public SymbolicEvaluationContext(IField stateField)
public SymbolicEvaluationContext(IField stateField, bool legacyVisualBasic = false)
{
this.legacyVisualBasic = legacyVisualBasic;
this.stateField = stateField;
}
@ -118,7 +120,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -118,7 +120,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
public SymbolicValue Eval(ILInstruction inst)
{
if (inst is BinaryNumericInstruction bni && bni.Operator == BinaryNumericOperator.Sub)
if (inst is BinaryNumericInstruction bni && bni.Operator == BinaryNumericOperator.Sub && (legacyVisualBasic || !bni.CheckForOverflow))
{
var left = Eval(bni.Left);
var right = Eval(bni.Right);

2
ICSharpCode.Decompiler/IL/ControlFlow/YieldReturnDecompiler.cs

@ -776,7 +776,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -776,7 +776,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
// but those cannot contain any yield statements.
// So for reconstructing the control flow, we only consider the blocks directly within body.
var rangeAnalysis = new StateRangeAnalysis(StateRangeAnalysisMode.IteratorMoveNext, stateField);
var rangeAnalysis = new StateRangeAnalysis(StateRangeAnalysisMode.IteratorMoveNext, stateField, legacyVisualBasic: isCompiledWithLegacyVisualBasic);
rangeAnalysis.skipFinallyBodies = skipFinallyBodies;
rangeAnalysis.doFinallyBodies = doFinallyBodies;
rangeAnalysis.CancellationToken = context.CancellationToken;

Loading…
Cancel
Save