public override Statement CloneStatementOnly() { BlockStatement result = new BlockStatement(); CopyParentAndLabel(result); foreach (Statement s in statements) { result.AddStatement(s.CloneStatementOnly()); } return result; }
public override Statement CloneStatementOnly() { BlockStatement result = new BlockStatement(); CopyParentAndLabel(result); foreach (Statement s in statements) { result.AddStatement(s.CloneStatementOnly()); } return(result); }
public BlockStatement Process(DecompilationContext context, BlockStatement body) { MethodDefinition method = context.MethodContext.Method; if (!method.IsUnsafe && method.HasBody && IsUnsafe(method.Body.Instructions)) { UnsafeBlockStatement unsafeStatement = new UnsafeBlockStatement(body.Statements); body.Statements = new StatementCollection(); body.AddStatement(unsafeStatement); } return body; }
public override Statement Clone() { V_0 = new BlockStatement(); this.CopyParentAndLabel(V_0); V_1 = this.statements.GetEnumerator(); try { while (V_1.MoveNext()) { V_2 = V_1.get_Current(); V_0.AddStatement(V_2.Clone()); } } finally { if (V_1 != null) { V_1.Dispose(); } } return(V_0); }
private ICodeNode ConvertLambda(MethodInvocationExpression invocation) { if (invocation.Arguments.Count != 2) { return null; } ArrayCreationExpression arguments = Visit(invocation.Arguments[1]) as ArrayCreationExpression; if (arguments == null || arguments.Initializer == null || arguments.Initializer.Expressions == null || arguments.Initializer.Expressions.Any(element => element.CodeNodeType != CodeNodeType.ArgumentReferenceExpression)) { return null; } List<ArgumentReferenceExpression> parameters = arguments.Initializer.Expressions.Cast<ArgumentReferenceExpression>().ToList(); bool hasAnonymousParameter = parameters.Any(param => param.Parameter.ParameterType.Resolve().IsAnonymous()); BlockStatement body = new BlockStatement(); body.AddStatement(new ExpressionStatement(new ShortFormReturnExpression((Expression)Visit(invocation.Arguments[0]), null))); return new LambdaExpression(new ExpressionCollection(parameters.Select(param => new LambdaParameterExpression(param.Parameter, !hasAnonymousParameter, null))), body, false, false, parameters.Select(argRef => argRef.Parameter), true, null); }
private CachedDecompiledMember DecompileMethod(ILanguage language, MethodDefinition method, TypeSpecificContext typeContext) { CachedDecompiledMember decompiledMember; Statement statement; try { DecompilationContext innerContext = null; statement = method.Body.Decompile(language, out innerContext, typeContext); decompiledMember = new CachedDecompiledMember(new DecompiledMember(Utilities.GetMemberUniqueName(method), statement, innerContext.MethodContext), innerContext.TypeContext); } catch (Exception ex) { this.ExceptionsWhileDecompiling.Add(method); BlockStatement blockStatement = new BlockStatement(); statement = new ExceptionStatement(ex, method); blockStatement.AddStatement(statement); decompiledMember = new CachedDecompiledMember(new DecompiledMember(Utilities.GetMemberUniqueName(method), blockStatement, new MethodSpecificContext(method.Body))); } return decompiledMember; }
/// <summary> /// Performs a move out operation on the goto statement. For more information see /// Chapter 2.2.1 "Outward-movement Transformations" /// </summary> /// <param name="gotoStatement"></param> /// <param name="label"></param> private void MoveOut(IfStatement gotoStatement, string label) { /// Preprocessing. BlockStatement containingBlock = gotoStatement.Parent as BlockStatement; BlockStatement outerBlock = GetOuterBlock(containingBlock); VariableReferenceExpression conditionVar = new VariableReferenceExpression(GetLabelVariable(label), null); ExtractConditionIntoVariable(conditionVar.CloneExpressionOnly() as VariableReferenceExpression, gotoStatement, containingBlock); Statement oldEnclosingStatement = containingBlock.Parent; if (oldEnclosingStatement is SwitchCase) { oldEnclosingStatement = oldEnclosingStatement.Parent; } if (containingBlock.Parent is SwitchCase || containingBlock.Parent is WhileStatement || containingBlock.Parent is DoWhileStatement || containingBlock.Parent is ForStatement || containingBlock.Parent is ForEachStatement) { /// Then we can exit using break. /// Create the if - break. BlockStatement thenBlock = new BlockStatement(); thenBlock.AddStatement(new BreakStatement(null)); //might have to keep track of brakes IfStatement breakIf = new IfStatement(conditionVar.CloneExpressionOnly(), thenBlock, null); /// Replace the original goto int gotoIndex = containingBlock.Statements.IndexOf(gotoStatement); containingBlock.Statements.Remove(gotoStatement); containingBlock.AddStatementAt(gotoIndex, breakIf); } else if (containingBlock.Parent is IfStatement || containingBlock.Parent is TryStatement || containingBlock.Parent is IfElseIfStatement) { /// Then we can exit via introducing another condition. int gotoIndex = containingBlock.Statements.IndexOf(gotoStatement); int index = gotoIndex + 1; BlockStatement thenBlock = new BlockStatement(); while (index < containingBlock.Statements.Count) { thenBlock.AddStatement(containingBlock.Statements[index]); containingBlock.Statements.RemoveAt(index); } UnaryExpression condition = new UnaryExpression(UnaryOperator.LogicalNot, conditionVar.CloneExpressionOnly(), null); IfStatement innerIf = new IfStatement(condition, thenBlock, null); /// At this point the goto statement should be the last one in the block. /// Simply replace it with the new if. containingBlock.Statements.Remove(gotoStatement); /// If the then block is empty, the if should not be added. if (innerIf.Then.Statements.Count != 0) { containingBlock.AddStatement(innerIf); } } else { throw new ArgumentOutOfRangeException("Goto statement can not leave this parent construct."); } /// Add the goto statement after the construct. /// The goto statement shoud be detached from the AST at this point. outerBlock.AddStatementAt(outerBlock.Statements.IndexOf(oldEnclosingStatement) + 1, gotoStatement); }
/// <summary> /// Contains the logic for moving a goto inside the case of switch statement. For more information /// see Chapter "2.2.2 Inward-movement Transformations : Moving a goto into a switch statement" from /// <see cref="Taming Control Flow A Structured Approach to Eliminating Goto Statements.pdf"/>. /// </summary> /// <param name="gotoStatement">The goto statement to be moved in.</param> /// <param name="switchCase">The switch case that contains the target of the goto statement.</param> /// <param name="label">The label of the target.</param> private void MoveInCase(IfStatement gotoStatement, SwitchCase switchCase, string label) { VariableReferenceExpression conditionVariable = new VariableReferenceExpression(GetLabelVariable(label), null); BlockStatement containingBlock = GetOuterBlock(gotoStatement); SwitchStatement switchStatement = switchCase.Parent as SwitchStatement; int gotoIndex = containingBlock.Statements.IndexOf(gotoStatement); int switchIndex = containingBlock.Statements.IndexOf(switchStatement); /// Generate variable and extract the switch condition string switchVariableName = "switch" + switchStatement.ConditionBlock.First.Offset; TypeReference switchVariableType = GetSwitchType(switchStatement); VariableDefinition switchVariable = new VariableDefinition(switchVariableName, switchVariableType); switchVariables.Add(switchVariable); VariableReferenceExpression switchVarEx = new VariableReferenceExpression(switchVariable, null); ExtractConditionIntoVariable(switchVarEx, switchStatement, containingBlock); BlockStatement thenBlock = CollectStatements(gotoIndex + 1, switchIndex + 1, containingBlock); BlockStatement elseBlock = new BlockStatement(); /// Adds swCond = caseCond; in the last part of else. BinaryExpression assignSwitchVariable = new BinaryExpression(BinaryOperator.Assign, switchVarEx.CloneExpressionOnly(), GetCaseConditionExpression(switchCase), typeSystem, null); elseBlock.AddStatement(new ExpressionStatement(assignSwitchVariable)); IfStatement precedingIf = new IfStatement(new UnaryExpression(UnaryOperator.LogicalNot, conditionVariable, null), thenBlock, elseBlock); /// Attach new if and move the goto conditional. /// Attach it only if the then block is not empty. if (precedingIf.Then.Statements.Count != 0) { containingBlock.AddStatementAt(gotoIndex, precedingIf); } containingBlock.Statements.Remove(gotoStatement); switchCase.Body.AddStatementAt(0, gotoStatement); }
/// <summary> /// Embeds unconditional goto into <code> if(true){} </code> statement /// </summary> /// <param name="jump">The unconditional goto.</param> private void EmbedIntoDefaultIf(GotoStatement jump) { BlockStatement parentBlock = jump.Parent as BlockStatement; BlockStatement thenBlock = new BlockStatement(); thenBlock.AddStatement(jump); Expression condition = GetLiteralExpression(true); IfStatement embeddingStatement = new IfStatement(condition, thenBlock, null); ///Should be initialized by the statements themselves, but just in case. thenBlock.Parent = embeddingStatement; ///Replace the old goto statement with the new embedding If int jumpIndex = parentBlock.Statements.IndexOf(jump); parentBlock.Statements.RemoveAt(jumpIndex); parentBlock.AddStatementAt(jumpIndex, embeddingStatement); if (parentBlock.Parent is ConditionCase) { ///If the goto was the last statement in case add break after the embedding if. int embeddingStatementIndex = parentBlock.Statements.IndexOf(embeddingStatement); if (embeddingStatementIndex == parentBlock.Statements.Count) { parentBlock.AddStatement(new BreakStatement(null)); } } }
/// <summary> /// Inserts the selected statements into new BlockStatement and returns it. In the process the collected statements are detached from their previous containing block. /// </summary> /// <param name="startingIndex">The index of the first statement to be selected.</param> /// <param name="endingIndex">The index of the last statement. This is the first one that doesn't get selected.</param> /// <param name="containingBlock">The block from which statements are retrieved.</param> /// <returns>The new block containining the selected statements.</returns> private BlockStatement CollectStatements(int startingIndex, int endingIndex, BlockStatement containingBlock) { BlockStatement newThenBlock = new BlockStatement(); for (int i = startingIndex; i < endingIndex; endingIndex--) { newThenBlock.AddStatement(containingBlock.Statements[i]); containingBlock.Statements.RemoveAt(i); } return newThenBlock; }
/// <summary> /// Adds /// <code> /// If(<paramref name="conditionVariable"/>) /// { /// <paramref name="statement"/> /// } /// </code> /// statement at <paramref name="index"/> in <paramref name="containingBlock"/> /// </summary> /// <param name="index">The index at which the generated statement must be inserted.</param> /// <param name="containingBlock">The block, in which the new statement is inserted.</param> /// <param name="statement">The only statement in the then clause.</param> /// <param name="conditionVariable">The condition of the if.</param> private void AddBreakContinueConditional(int index, BlockStatement containingBlock, Statement statement, VariableReference conditionVariable) { BlockStatement thenBlock = new BlockStatement(); thenBlock.AddStatement(statement); VariableReferenceExpression ifCondition = new VariableReferenceExpression(conditionVariable, null); IfStatement enclosingIfStatement = new IfStatement(ifCondition, thenBlock, null); containingBlock.AddStatementAt(index, enclosingIfStatement); }
private BlockStatement FinishDecompilationOfMethod(BlockStatement block, DecompilationContext context, out MethodSpecificContext methodContext) { methodContext = null; BlockStatement fullyDecompiledBlock; try { BlockDecompilationPipeline pipeline = this.language.CreatePropertyPipeline(context); methodContext = pipeline.Run(context.MethodContext.Method.Body, block, this.language).MethodContext; fullyDecompiledBlock = pipeline.Body; } catch (Exception ex) { this.ExceptionsWhileDecompiling.Add(context.MethodContext.Method); methodContext = new MethodSpecificContext(context.MethodContext.Method.Body); fullyDecompiledBlock = new BlockStatement(); fullyDecompiledBlock.AddStatement(new ExceptionStatement(ex, context.MethodContext.Method)); OnExceptionThrown(ex); } return fullyDecompiledBlock; }
private BlockStatement DecompileMethodPartially(MethodBody body, out DecompilationContext context, bool needDecompiledMember = false) { context = null; if (this.IsCachingEnabled && this.cacheService.IsDecompiledMemberInCache(body.Method, this.language, this.renameInvalidMembers)) { CachedDecompiledMember cachedDecompiledMember = this.cacheService.GetDecompiledMemberFromCache(body.Method, this.language, this.renameInvalidMembers); return cachedDecompiledMember.Member.Statement as BlockStatement; } //Performance improvement ControlFlowGraph cfg = new ControlFlowGraphBuilder(body.Method).CreateGraph(); if (cfg.Blocks.Length > 2) { return null; } BlockStatement block; try { DecompilationPipeline pipeline; DecompilationContext decompilationContext = new DecompilationContext(new MethodSpecificContext(body), this.typeContext ?? new TypeSpecificContext(body.Method.DeclaringType), this.language); if (!needDecompiledMember) { decompilationContext.MethodContext.EnableEventAnalysis = false; } pipeline = new DecompilationPipeline(BaseLanguage.IntermediateRepresenationPipeline.Steps, decompilationContext); context = pipeline.Run(body, this.language); block = pipeline.Body; } catch (Exception ex) { this.ExceptionsWhileDecompiling.Add(body.Method); block = new BlockStatement(); block.AddStatement(new ExceptionStatement(ex, body.Method)); OnExceptionThrown(ex); } return block; }
private BlockStatement DecompileMethod(MethodBody body, out MethodSpecificContext methodContext) { methodContext = null; BlockStatement block; try { DecompilationContext decompilationContext = new DecompilationContext(new MethodSpecificContext(body), this.typeContext ?? new TypeSpecificContext(body.Method.DeclaringType), this.language); DecompilationPipeline pipeline = this.language.CreatePipeline(decompilationContext); methodContext = pipeline.Run(body, this.language).MethodContext; block = pipeline.Body; } catch (Exception ex) { this.ExceptionsWhileDecompiling.Add(body.Method); methodContext = new MethodSpecificContext(body); block = new BlockStatement(); block.AddStatement(new ExceptionStatement(ex, body.Method)); OnExceptionThrown(ex); } return block; }
private void CopyWhileBodyStatements(WhileStatement whileStatement) { statementBody = new BlockStatement(); for (int i = 1; i < whileStatement.Body.Statements.Count - 1; i++) { statementBody.AddStatement(whileStatement.Body.Statements[i]); } }