예제 #1
0
        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);
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
        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);
                        }
                    }
                }
            }
        }
예제 #4
0
        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);
        }