private bool IterateStatements(RootStatement root, SSAUConstructorSparseEx ssa) { FlattenStatementsHelper flatthelper = new FlattenStatementsHelper(); DirectGraph dgraph = flatthelper.BuildDirectGraph(root); bool res = false; HashSet <DirectNode> setVisited = new HashSet <DirectNode>(); LinkedList <DirectNode> stack = new LinkedList <DirectNode>(); LinkedList <Dictionary <VarVersionPair, Exprent> > stackMaps = new LinkedList <Dictionary <VarVersionPair, Exprent> >(); stack.AddLast(dgraph.first); stackMaps.AddLast(new Dictionary <VarVersionPair, Exprent>()); while (!(stack.Count == 0)) { DirectNode nd = Sharpen.Collections.RemoveFirst(stack); Dictionary <VarVersionPair, Exprent> mapVarValues = Sharpen.Collections.RemoveFirst (stackMaps); if (setVisited.Contains(nd)) { continue; } setVisited.Add(nd); List <List <Exprent> > lstLists = new List <List <Exprent> >(); if (!(nd.exprents.Count == 0)) { lstLists.Add(nd.exprents); } if (nd.succs.Count == 1) { DirectNode ndsucc = nd.succs[0]; if (ndsucc.type == DirectNode.Node_Tail && !(ndsucc.exprents.Count == 0)) { lstLists.Add(nd.succs[0].exprents); nd = ndsucc; } } for (int i = 0; i < lstLists.Count; i++) { List <Exprent> lst = lstLists[i]; int index = 0; while (index < lst.Count) { Exprent next = null; if (index == lst.Count - 1) { if (i < lstLists.Count - 1) { next = lstLists[i + 1][0]; } } else { next = lst[index + 1]; } int[] ret = IterateExprent(lst, index, next, mapVarValues, ssa); if (ret[0] >= 0) { index = ret[0]; } else { index++; } res |= (ret[1] == 1); } } foreach (DirectNode ndx in nd.succs) { stack.AddLast(ndx); stackMaps.AddLast(new Dictionary <VarVersionPair, Exprent>(mapVarValues)); } // make sure the 3 special exprent lists in a loop (init, condition, increment) are not empty // change loop type if necessary if ((nd.exprents.Count == 0) && (nd.type == DirectNode.Node_Init || nd.type == DirectNode .Node_Condition || nd.type == DirectNode.Node_Increment)) { nd.exprents.Add(null); if (nd.statement.type == Statement.Type_Do) { DoStatement loop = (DoStatement)nd.statement; if (loop.GetLooptype() == DoStatement.Loop_For && loop.GetInitExprent() == null && loop.GetIncExprent() == null) { // "downgrade" loop to 'while' loop.SetLooptype(DoStatement.Loop_While); } } } } return(res); }
private static void MatchFor(DoStatement stat) { Exprent lastDoExprent; Exprent initDoExprent; Statement lastData; Statement preData = null; // get last exprent lastData = GetLastDirectData(stat.GetFirst()); if (lastData == null || (lastData.GetExprents().Count == 0)) { return; } List <Exprent> lstExpr = lastData.GetExprents(); lastDoExprent = lstExpr[lstExpr.Count - 1]; bool issingle = false; if (lstExpr.Count == 1) { // single exprent if (lastData.GetAllPredecessorEdges().Count > 1) { // break edges issingle = true; } } bool haslast = issingle || lastDoExprent.type == Exprent.Exprent_Assignment || lastDoExprent .type == Exprent.Exprent_Function; if (!haslast) { return; } bool hasinit = false; // search for an initializing exprent Statement current = stat; while (true) { Statement parent = current.GetParent(); if (parent == null) { break; } if (parent.type == Statement.Type_Sequence) { if (current == parent.GetFirst()) { current = parent; } else { preData = current.GetNeighbours(StatEdge.Type_Regular, Statement.Direction_Backward )[0]; preData = GetLastDirectData(preData); if (preData != null && !(preData.GetExprents().Count == 0)) { initDoExprent = preData.GetExprents()[preData.GetExprents().Count - 1]; if (initDoExprent.type == Exprent.Exprent_Assignment) { hasinit = true; } } break; } } else { break; } } if (hasinit || issingle) { // FIXME: issingle sufficient? HashSet <Statement> set = stat.GetNeighboursSet(StatEdge.Type_Continue, Statement. Direction_Backward); set.Remove(lastData); if (!(set.Count == 0)) { return; } stat.SetLooptype(DoStatement.Loop_For); if (hasinit) { stat.SetInitExprent(preData.GetExprents().RemoveAtReturningValue(preData.GetExprents ().Count - 1)); } stat.SetIncExprent(lastData.GetExprents().RemoveAtReturningValue(lastData.GetExprents ().Count - 1)); } if ((lastData.GetExprents().Count == 0)) { List <StatEdge> lst = lastData.GetAllSuccessorEdges(); if (!(lst.Count == 0)) { lastData.RemoveSuccessor(lst[0]); } RemoveLastEmptyStatement(stat, lastData); } }
private static void MatchDoWhile(DoStatement stat) { // search for an if condition at the end of the loop Statement last = stat.GetFirst(); while (last.type == Statement.Type_Sequence) { last = last.GetStats().GetLast(); } if (last.type == Statement.Type_If) { IfStatement lastif = (IfStatement)last; if (lastif.iftype == IfStatement.Iftype_If && lastif.GetIfstat() == null) { StatEdge ifedge = lastif.GetIfEdge(); StatEdge elseedge = lastif.GetAllSuccessorEdges()[0]; if ((ifedge.GetType() == StatEdge.Type_Break && elseedge.GetType() == StatEdge.Type_Continue && elseedge.closure == stat && IsDirectPath(stat, ifedge.GetDestination())) || (ifedge.GetType() == StatEdge.Type_Continue && elseedge.GetType() == StatEdge.Type_Break && ifedge.closure == stat && IsDirectPath(stat, elseedge.GetDestination()))) { HashSet <Statement> set = stat.GetNeighboursSet(StatEdge.Type_Continue, Statement. Direction_Backward); set.Remove(last); if (!(set.Count == 0)) { return; } stat.SetLooptype(DoStatement.Loop_Dowhile); IfExprent ifexpr = (IfExprent)lastif.GetHeadexprent().Copy(); if (ifedge.GetType() == StatEdge.Type_Break) { ifexpr.NegateIf(); } stat.SetConditionExprent(ifexpr.GetCondition()); lastif.GetFirst().RemoveSuccessor(ifedge); lastif.RemoveSuccessor(elseedge); // remove empty if if ((lastif.GetFirst().GetExprents().Count == 0)) { RemoveLastEmptyStatement(stat, lastif); } else { lastif.SetExprents(lastif.GetFirst().GetExprents()); StatEdge newedge = new StatEdge(StatEdge.Type_Continue, lastif, stat); lastif.AddSuccessor(newedge); stat.AddLabeledEdge(newedge); } if ((stat.GetAllSuccessorEdges().Count == 0)) { StatEdge edge = elseedge.GetType() == StatEdge.Type_Continue ? ifedge : elseedge; edge.SetSource(stat); if (edge.closure == stat) { edge.closure = stat.GetParent(); } stat.AddSuccessor(edge); } } } } }
private static bool MatchWhile(DoStatement stat) { // search for an if condition at the entrance of the loop Statement first = stat.GetFirst(); while (first.type == Statement.Type_Sequence) { first = first.GetFirst(); } // found an if statement if (first.type == Statement.Type_If) { IfStatement firstif = (IfStatement)first; if ((firstif.GetFirst().GetExprents().Count == 0)) { if (firstif.iftype == IfStatement.Iftype_If) { if (firstif.GetIfstat() == null) { StatEdge ifedge = firstif.GetIfEdge(); if (IsDirectPath(stat, ifedge.GetDestination())) { // exit condition identified stat.SetLooptype(DoStatement.Loop_While); // negate condition (while header) IfExprent ifexpr = (IfExprent)firstif.GetHeadexprent().Copy(); ifexpr.NegateIf(); stat.SetConditionExprent(ifexpr.GetCondition()); // remove edges firstif.GetFirst().RemoveSuccessor(ifedge); firstif.RemoveSuccessor(firstif.GetAllSuccessorEdges()[0]); if ((stat.GetAllSuccessorEdges().Count == 0)) { ifedge.SetSource(stat); if (ifedge.closure == stat) { ifedge.closure = stat.GetParent(); } stat.AddSuccessor(ifedge); } // remove empty if statement as it is now part of the loop if (firstif == stat.GetFirst()) { BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock(DecompilerContext .GetCounterContainer().GetCounterAndIncrement(CounterContainer.Statement_Counter ))); bstat.SetExprents(new List <Exprent>()); stat.ReplaceStatement(firstif, bstat); } else { // precondition: sequence must contain more than one statement! Statement sequence = firstif.GetParent(); sequence.GetStats().RemoveWithKey(firstif.id); sequence.SetFirst(sequence.GetStats()[0]); } return(true); } } else { StatEdge elseedge = firstif.GetAllSuccessorEdges()[0]; if (IsDirectPath(stat, elseedge.GetDestination())) { // exit condition identified stat.SetLooptype(DoStatement.Loop_While); // no need to negate the while condition stat.SetConditionExprent(((IfExprent)firstif.GetHeadexprent().Copy()).GetCondition ()); // remove edges StatEdge ifedge = firstif.GetIfEdge(); firstif.GetFirst().RemoveSuccessor(ifedge); firstif.RemoveSuccessor(elseedge); if ((stat.GetAllSuccessorEdges().Count == 0)) { elseedge.SetSource(stat); if (elseedge.closure == stat) { elseedge.closure = stat.GetParent(); } stat.AddSuccessor(elseedge); } if (firstif.GetIfstat() == null) { BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock(DecompilerContext .GetCounterContainer().GetCounterAndIncrement(CounterContainer.Statement_Counter ))); bstat.SetExprents(new List <Exprent>()); ifedge.SetSource(bstat); bstat.AddSuccessor(ifedge); stat.ReplaceStatement(firstif, bstat); } else { // replace the if statement with its content first.GetParent().ReplaceStatement(first, firstif.GetIfstat()); // lift closures foreach (StatEdge prededge in elseedge.GetDestination().GetPredecessorEdges(StatEdge .Type_Break)) { if (stat.ContainsStatementStrict(prededge.closure)) { stat.AddLabeledEdge(prededge); } } LabelHelper.LowClosures(stat); } return(true); } } } } } return(false); }