示例#1
0
 private static bool CollapseIfElse(IfHelper.IfNode rtnode)
 {
     if (rtnode.edgetypes[0] == 0)
     {
         IfHelper.IfNode ifbranch = rtnode.succs[0];
         if (ifbranch.succs.Count == 2)
         {
             // if-else branch
             if (ifbranch.succs[0].value == rtnode.succs[1].value)
             {
                 IfStatement ifparent = (IfStatement)rtnode.value;
                 IfStatement ifchild  = (IfStatement)ifbranch.value;
                 if ((ifchild.GetFirst().GetExprents().Count == 0))
                 {
                     ifparent.GetFirst().RemoveSuccessor(ifparent.GetIfEdge());
                     ifchild.GetFirst().RemoveSuccessor(ifchild.GetIfEdge());
                     ifparent.GetStats().RemoveWithKey(ifchild.id);
                     if (ifbranch.edgetypes[1] == 1 && ifbranch.edgetypes[0] == 1)
                     {
                         // target null
                         ifparent.SetIfstat(null);
                         StatEdge ifedge = ifchild.GetAllSuccessorEdges()[0];
                         ifchild.RemoveSuccessor(ifedge);
                         ifedge.SetSource(ifparent.GetFirst());
                         ifparent.GetFirst().AddSuccessor(ifedge);
                         ifparent.SetIfEdge(ifedge);
                     }
                     else
                     {
                         throw new Exception("inconsistent if structure!");
                     }
                     // merge if conditions
                     IfExprent      statexpr    = ifparent.GetHeadexprent();
                     List <Exprent> lstOperands = new List <Exprent>();
                     lstOperands.Add(statexpr.GetCondition());
                     lstOperands.Add(new FunctionExprent(FunctionExprent.Function_Bool_Not, ifchild.GetHeadexprent
                                                             ().GetCondition(), null));
                     statexpr.SetCondition(new FunctionExprent(FunctionExprent.Function_Cadd, lstOperands
                                                               , null));
                     statexpr.AddBytecodeOffsets(ifchild.GetHeadexprent().bytecode);
                     return(true);
                 }
             }
         }
     }
     return(false);
 }
示例#2
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);
                        }
                    }
                }
            }
        }
示例#3
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);
        }
示例#4
0
        // FIXME: rewrite the entire method!!! keep in mind finally exits!!
        private static bool ReorderIf(IfStatement ifstat)
        {
            if (ifstat.iftype == IfStatement.Iftype_Ifelse)
            {
                return(false);
            }
            bool      ifdirect;
            bool      elsedirect;
            bool      noifstat = false;
            bool      noelsestat;
            bool      ifdirectpath   = false;
            bool      elsedirectpath = false;
            Statement parent         = ifstat.GetParent();
            Statement from           = parent.type == Statement.Type_Sequence ? parent : ifstat;
            Statement next           = GetNextStatement(from);

            if (ifstat.GetIfstat() == null)
            {
                noifstat = true;
                ifdirect = ifstat.GetIfEdge().GetType() == StatEdge.Type_Finallyexit || MergeHelper
                           .IsDirectPath(from, ifstat.GetIfEdge().GetDestination());
            }
            else
            {
                List <StatEdge> lstSuccs = ifstat.GetIfstat().GetAllSuccessorEdges();
                ifdirect = !(lstSuccs.Count == 0) && lstSuccs[0].GetType() == StatEdge.Type_Finallyexit ||
                           HasDirectEndEdge(ifstat.GetIfstat(), from);
            }
            Statement last = parent.type == Statement.Type_Sequence ? parent.GetStats().GetLast
                                 () : ifstat;

            noelsestat = (last == ifstat);
            elsedirect = !(last.GetAllSuccessorEdges().Count == 0) && last.GetAllSuccessorEdges
                             ()[0].GetType() == StatEdge.Type_Finallyexit || HasDirectEndEdge(last, from);
            if (!noelsestat && ExistsPath(ifstat, ifstat.GetAllSuccessorEdges()[0].GetDestination
                                              ()))
            {
                return(false);
            }
            if (!ifdirect && !noifstat)
            {
                ifdirectpath = ExistsPath(ifstat, next);
            }
            if (!elsedirect && !noelsestat)
            {
                SequenceStatement sequence = (SequenceStatement)parent;
                for (int i = sequence.GetStats().Count - 1; i >= 0; i--)
                {
                    Statement sttemp = sequence.GetStats()[i];
                    if (sttemp == ifstat)
                    {
                        break;
                    }
                    else if (elsedirectpath = ExistsPath(sttemp, next))
                    {
                        break;
                    }
                }
            }
            if ((ifdirect || ifdirectpath) && (elsedirect || elsedirectpath) && !noifstat &&
                !noelsestat)
            {
                // if - then - else
                SequenceStatement sequence = (SequenceStatement)parent;
                // build and cut the new else statement
                List <Statement> lst = new List <Statement>();
                for (int i = sequence.GetStats().Count - 1; i >= 0; i--)
                {
                    Statement sttemp = sequence.GetStats()[i];
                    if (sttemp == ifstat)
                    {
                        break;
                    }
                    else
                    {
                        lst.Add(0, sttemp);
                    }
                }
                Statement stelse;
                if (lst.Count == 1)
                {
                    stelse = lst[0];
                }
                else
                {
                    stelse = new SequenceStatement(lst);
                    stelse.SetAllParent();
                }
                ifstat.RemoveSuccessor(ifstat.GetAllSuccessorEdges()[0]);
                foreach (Statement st in lst)
                {
                    sequence.GetStats().RemoveWithKey(st.id);
                }
                StatEdge elseedge = new StatEdge(StatEdge.Type_Regular, ifstat.GetFirst(), stelse
                                                 );
                ifstat.GetFirst().AddSuccessor(elseedge);
                ifstat.SetElsestat(stelse);
                ifstat.SetElseEdge(elseedge);
                ifstat.GetStats().AddWithKey(stelse, stelse.id);
                stelse.SetParent(ifstat);
                //			if(next.type != Statement.TYPE_DUMMYEXIT && (ifdirect || elsedirect)) {
                //	            StatEdge breakedge = new StatEdge(StatEdge.TYPE_BREAK, ifstat, next);
                //				sequence.addLabeledEdge(breakedge);
                //				ifstat.addSuccessor(breakedge);
                //			}
                ifstat.iftype = IfStatement.Iftype_Ifelse;
            }
            else if (ifdirect && (!elsedirect || (noifstat && !noelsestat)))
            {
                // if - then
                // negate the if condition
                IfExprent statexpr = ifstat.GetHeadexprent();
                statexpr.SetCondition(new FunctionExprent(FunctionExprent.Function_Bool_Not, statexpr
                                                          .GetCondition(), null));
                if (noelsestat)
                {
                    StatEdge ifedge   = ifstat.GetIfEdge();
                    StatEdge elseedge = ifstat.GetAllSuccessorEdges()[0];
                    if (noifstat)
                    {
                        ifstat.GetFirst().RemoveSuccessor(ifedge);
                        ifstat.RemoveSuccessor(elseedge);
                        ifedge.SetSource(ifstat);
                        elseedge.SetSource(ifstat.GetFirst());
                        ifstat.AddSuccessor(ifedge);
                        ifstat.GetFirst().AddSuccessor(elseedge);
                        ifstat.SetIfEdge(elseedge);
                    }
                    else
                    {
                        Statement         ifbranch = ifstat.GetIfstat();
                        SequenceStatement newseq   = new SequenceStatement(Sharpen.Arrays.AsList(ifstat, ifbranch
                                                                                                 ));
                        ifstat.GetFirst().RemoveSuccessor(ifedge);
                        ifstat.GetStats().RemoveWithKey(ifbranch.id);
                        ifstat.SetIfstat(null);
                        ifstat.RemoveSuccessor(elseedge);
                        elseedge.SetSource(ifstat.GetFirst());
                        ifstat.GetFirst().AddSuccessor(elseedge);
                        ifstat.SetIfEdge(elseedge);
                        ifstat.GetParent().ReplaceStatement(ifstat, newseq);
                        newseq.SetAllParent();
                        ifstat.AddSuccessor(new StatEdge(StatEdge.Type_Regular, ifstat, ifbranch));
                    }
                }
                else
                {
                    SequenceStatement sequence = (SequenceStatement)parent;
                    // build and cut the new else statement
                    List <Statement> lst = new List <Statement>();
                    for (int i = sequence.GetStats().Count - 1; i >= 0; i--)
                    {
                        Statement sttemp = sequence.GetStats()[i];
                        if (sttemp == ifstat)
                        {
                            break;
                        }
                        else
                        {
                            lst.Add(0, sttemp);
                        }
                    }
                    Statement stelse;
                    if (lst.Count == 1)
                    {
                        stelse = lst[0];
                    }
                    else
                    {
                        stelse = new SequenceStatement(lst);
                        stelse.SetAllParent();
                    }
                    ifstat.RemoveSuccessor(ifstat.GetAllSuccessorEdges()[0]);
                    foreach (Statement st in lst)
                    {
                        sequence.GetStats().RemoveWithKey(st.id);
                    }
                    if (noifstat)
                    {
                        StatEdge ifedge = ifstat.GetIfEdge();
                        ifstat.GetFirst().RemoveSuccessor(ifedge);
                        ifedge.SetSource(ifstat);
                        ifstat.AddSuccessor(ifedge);
                    }
                    else
                    {
                        Statement ifbranch = ifstat.GetIfstat();
                        ifstat.GetFirst().RemoveSuccessor(ifstat.GetIfEdge());
                        ifstat.GetStats().RemoveWithKey(ifbranch.id);
                        ifstat.AddSuccessor(new StatEdge(StatEdge.Type_Regular, ifstat, ifbranch));
                        sequence.GetStats().AddWithKey(ifbranch, ifbranch.id);
                        ifbranch.SetParent(sequence);
                    }
                    StatEdge newifedge = new StatEdge(StatEdge.Type_Regular, ifstat.GetFirst(), stelse
                                                      );
                    ifstat.GetFirst().AddSuccessor(newifedge);
                    ifstat.SetIfstat(stelse);
                    ifstat.SetIfEdge(newifedge);
                    ifstat.GetStats().AddWithKey(stelse, stelse.id);
                    stelse.SetParent(ifstat);
                }
            }
            else
            {
                return(false);
            }
            return(true);
        }
示例#5
0
 private static bool CollapseElse(IfHelper.IfNode rtnode)
 {
     if (rtnode.edgetypes[1] == 0)
     {
         IfHelper.IfNode elsebranch = rtnode.succs[1];
         if (elsebranch.succs.Count == 2)
         {
             // else-if or else-else branch
             int path = elsebranch.succs[1].value == rtnode.succs[0].value ? 2 : (elsebranch.succs
                                                                                  [0].value == rtnode.succs[0].value ? 1 : 0);
             if (path > 0)
             {
                 IfStatement firstif  = (IfStatement)rtnode.value;
                 IfStatement secondif = (IfStatement)elsebranch.value;
                 Statement   parent   = firstif.GetParent();
                 if ((secondif.GetFirst().GetExprents().Count == 0))
                 {
                     firstif.GetFirst().RemoveSuccessor(firstif.GetIfEdge());
                     // remove first if
                     firstif.RemoveAllSuccessors(secondif);
                     foreach (StatEdge edge in firstif.GetAllPredecessorEdges())
                     {
                         if (!firstif.ContainsStatementStrict(edge.GetSource()))
                         {
                             firstif.RemovePredecessor(edge);
                             edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, secondif);
                             secondif.AddPredecessor(edge);
                         }
                     }
                     parent.GetStats().RemoveWithKey(firstif.id);
                     if (parent.GetFirst() == firstif)
                     {
                         parent.SetFirst(secondif);
                     }
                     // merge if conditions
                     IfExprent      statexpr    = secondif.GetHeadexprent();
                     List <Exprent> lstOperands = new List <Exprent>();
                     lstOperands.Add(firstif.GetHeadexprent().GetCondition());
                     if (path == 2)
                     {
                         lstOperands[0] = new FunctionExprent(FunctionExprent.Function_Bool_Not, lstOperands
                                                              [0], null);
                     }
                     lstOperands.Add(statexpr.GetCondition());
                     statexpr.SetCondition(new FunctionExprent(path == 1 ? FunctionExprent.Function_Cor
                                                          : FunctionExprent.Function_Cadd, lstOperands, null));
                     if ((secondif.GetFirst().GetExprents().Count == 0) && !(firstif.GetFirst().GetExprents
                                                                                 ().Count == 0))
                     {
                         secondif.ReplaceStatement(secondif.GetFirst(), firstif.GetFirst());
                     }
                     return(true);
                 }
             }
         }
         else if (elsebranch.succs.Count == 1)
         {
             if (elsebranch.succs[0].value == rtnode.succs[0].value)
             {
                 IfStatement firstif = (IfStatement)rtnode.value;
                 Statement   second  = elsebranch.value;
                 firstif.RemoveAllSuccessors(second);
                 foreach (StatEdge edge in second.GetAllSuccessorEdges())
                 {
                     second.RemoveSuccessor(edge);
                     edge.SetSource(firstif);
                     firstif.AddSuccessor(edge);
                 }
                 StatEdge ifedge = firstif.GetIfEdge();
                 firstif.GetFirst().RemoveSuccessor(ifedge);
                 second.AddSuccessor(new StatEdge(ifedge.GetType(), second, ifedge.GetDestination(
                                                      ), ifedge.closure));
                 StatEdge newifedge = new StatEdge(StatEdge.Type_Regular, firstif.GetFirst(), second
                                                   );
                 firstif.GetFirst().AddSuccessor(newifedge);
                 firstif.SetIfstat(second);
                 firstif.GetStats().AddWithKey(second, second.id);
                 second.SetParent(firstif);
                 firstif.GetParent().GetStats().RemoveWithKey(second.id);
                 // negate the if condition
                 IfExprent statexpr = firstif.GetHeadexprent();
                 statexpr.SetCondition(new FunctionExprent(FunctionExprent.Function_Bool_Not, statexpr
                                                           .GetCondition(), null));
                 return(true);
             }
         }
     }
     return(false);
 }
示例#6
0
 private static bool CollapseIfIf(IfHelper.IfNode rtnode)
 {
     if (rtnode.edgetypes[0] == 0)
     {
         IfHelper.IfNode ifbranch = rtnode.succs[0];
         if (ifbranch.succs.Count == 2)
         {
             // if-if branch
             if (ifbranch.succs[1].value == rtnode.succs[1].value)
             {
                 IfStatement ifparent = (IfStatement)rtnode.value;
                 IfStatement ifchild  = (IfStatement)ifbranch.value;
                 Statement   ifinner  = ifbranch.succs[0].value;
                 if ((ifchild.GetFirst().GetExprents().Count == 0))
                 {
                     ifparent.GetFirst().RemoveSuccessor(ifparent.GetIfEdge());
                     ifchild.RemoveSuccessor(ifchild.GetAllSuccessorEdges()[0]);
                     ifparent.GetStats().RemoveWithKey(ifchild.id);
                     if (ifbranch.edgetypes[0] == 1)
                     {
                         // target null
                         ifparent.SetIfstat(null);
                         StatEdge ifedge = ifchild.GetIfEdge();
                         ifchild.GetFirst().RemoveSuccessor(ifedge);
                         ifedge.SetSource(ifparent.GetFirst());
                         if (ifedge.closure == ifchild)
                         {
                             ifedge.closure = null;
                         }
                         ifparent.GetFirst().AddSuccessor(ifedge);
                         ifparent.SetIfEdge(ifedge);
                     }
                     else
                     {
                         ifchild.GetFirst().RemoveSuccessor(ifchild.GetIfEdge());
                         StatEdge ifedge = new StatEdge(StatEdge.Type_Regular, ifparent.GetFirst(), ifinner
                                                        );
                         ifparent.GetFirst().AddSuccessor(ifedge);
                         ifparent.SetIfEdge(ifedge);
                         ifparent.SetIfstat(ifinner);
                         ifparent.GetStats().AddWithKey(ifinner, ifinner.id);
                         ifinner.SetParent(ifparent);
                         if (!(ifinner.GetAllSuccessorEdges().Count == 0))
                         {
                             StatEdge edge = ifinner.GetAllSuccessorEdges()[0];
                             if (edge.closure == ifchild)
                             {
                                 edge.closure = null;
                             }
                         }
                     }
                     // merge if conditions
                     IfExprent      statexpr    = ifparent.GetHeadexprent();
                     List <Exprent> lstOperands = new List <Exprent>();
                     lstOperands.Add(statexpr.GetCondition());
                     lstOperands.Add(ifchild.GetHeadexprent().GetCondition());
                     statexpr.SetCondition(new FunctionExprent(FunctionExprent.Function_Cadd, lstOperands
                                                               , null));
                     statexpr.AddBytecodeOffsets(ifchild.GetHeadexprent().bytecode);
                     return(true);
                 }
             }
         }
     }
     return(false);
 }