// *****************************************************************************
        // public methods
        // *****************************************************************************
        public static Statement IsHead2Block(Statement head)
        {
            if (head.GetLastBasicType() != Statement.Lastbasictype_General)
            {
                return(null);
            }
            // at most one outgoing edge
            StatEdge        edge     = null;
            List <StatEdge> lstSuccs = head.GetSuccessorEdges(Statedge_Direct_All);

            if (!(lstSuccs.Count == 0))
            {
                edge = lstSuccs[0];
            }
            if (edge != null && edge.GetType() == StatEdge.Type_Regular)
            {
                Statement stat = edge.GetDestination();
                if (stat != head && stat.GetPredecessorEdges(StatEdge.Type_Regular).Count == 1 &&
                    !stat.IsMonitorEnter())
                {
                    if (stat.GetLastBasicType() == Statement.Lastbasictype_General)
                    {
                        if (DecHelper.CheckStatementExceptions(Sharpen.Arrays.AsList(head, stat)))
                        {
                            return(new SequenceStatement(head, stat));
                        }
                    }
                }
            }
            return(null);
        }
        // *****************************************************************************
        // private methods
        // *****************************************************************************
        public virtual void SortEdgesAndNodes()
        {
            Dictionary <StatEdge, int> mapEdgeIndex  = new Dictionary <StatEdge, int>();
            List <StatEdge>            lstFirstSuccs = first.GetSuccessorEdges(Statedge_Direct_All);

            for (int i = 0; i < lstFirstSuccs.Count; i++)
            {
                Sharpen.Collections.Put(mapEdgeIndex, lstFirstSuccs[i], i == 0 ? lstFirstSuccs.Count
                                         : i);
            }
            // case values
            BasicBlockStatement bbstat = (BasicBlockStatement)first;

            int[] values = ((SwitchInstruction)bbstat.GetBlock().GetLastInstruction()).GetValues
                               ();
            List <Statement>    nodes = new List <Statement>(stats.Count - 1);
            List <List <int?> > edges = new List <List <int?> >(stats.Count - 1);

            // collect regular edges
            for (int i = 1; i < stats.Count; i++)
            {
                Statement   stat = stats[i];
                List <int?> lst  = new List <int?>();
                foreach (StatEdge edge in stat.GetPredecessorEdges(StatEdge.Type_Regular))
                {
                    if (edge.GetSource() == first)
                    {
                        lst.Add(mapEdgeIndex.GetOrNullable(edge));
                    }
                }
                lst.Sort();
                nodes.Add(stat);
                edges.Add(lst);
            }
            // collect exit edges
            List <StatEdge> lstExitEdges = first.GetSuccessorEdges(StatEdge.Type_Break | StatEdge
                                                                   .Type_Continue);

            while (!(lstExitEdges.Count == 0))
            {
                StatEdge    edge = lstExitEdges[0];
                List <int?> lst  = new List <int?>();
                for (int i = lstExitEdges.Count - 1; i >= 0; i--)
                {
                    StatEdge edgeTemp = lstExitEdges[i];
                    if (edgeTemp.GetDestination() == edge.GetDestination() && edgeTemp.GetType() == edge
                        .GetType())
                    {
                        lst.Add(mapEdgeIndex.GetOrNullable(edgeTemp));
                        lstExitEdges.RemoveAtReturningValue(i);
                    }
                }
                lst.Sort();
                nodes.Add(null);
                edges.Add(lst);
            }
            // sort edges (bubblesort)
            for (int i = 0; i < edges.Count - 1; i++)
            {
                for (int j = edges.Count - 1; j > i; j--)
                {
                    if (edges[j - 1][0] > edges[j][0])
                    {
                        edges[j] = edges[j - 1] = edges[j];
                        nodes[j] = nodes[j - 1] = nodes[j];
                    }
                }
            }
            // sort statement cliques
            for (int index = 0; index < nodes.Count; index++)
            {
                Statement stat = nodes[index];
                if (stat != null)
                {
                    HashSet <Statement> setPreds = new HashSet <Statement>(stat.GetNeighbours(StatEdge.
                                                                                              Type_Regular, Direction_Backward));
                    setPreds.Remove(first);
                    if (!(setPreds.Count == 0))
                    {
                        Statement pred = new Sharpen.EnumeratorAdapter <Statement>(setPreds.GetEnumerator()).Next();
                        // assumption: at most one predecessor node besides the head. May not hold true for obfuscated code.
                        for (int j = 0; j < nodes.Count; j++)
                        {
                            if (j != (index - 1) && nodes[j] == pred)
                            {
                                nodes.Add(j + 1, stat);
                                edges.Add(j + 1, edges[index]);
                                if (j > index)
                                {
                                    nodes.RemoveAtReturningValue(index);
                                    edges.RemoveAtReturningValue(index);
                                    index--;
                                }
                                else
                                {
                                    nodes.RemoveAtReturningValue(index + 1);
                                    edges.RemoveAtReturningValue(index + 1);
                                }
                                break;
                            }
                        }
                    }
                }
            }
            // translate indices back into edges
            List <List <StatEdge> > lstEdges  = new List <List <StatEdge> >(edges.Count);
            List <List <Exprent> >  lstValues = new List <List <Exprent> >(edges.Count);

            foreach (List <int?> lst in edges)
            {
                List <StatEdge> lste     = new List <StatEdge>(lst.Count);
                List <Exprent>  lstv     = new List <Exprent>(lst.Count);
                List <StatEdge> lstSuccs = first.GetSuccessorEdges(Statedge_Direct_All);
                foreach (int? @in in lst)
                {
                    int?index = @in == lstSuccs.Count ? 0 : @in;
                    if (!index.HasValue)
                    {
                        continue;
                    }
                    lste.Add(lstSuccs[index.Value]);
                    lstv.Add(index == 0 ? null : new ConstExprent(values[index.Value - 1], false, null));
                }
                lstEdges.Add(lste);
                lstValues.Add(lstv);
            }
            // replace null statements with dummy basic blocks
            for (int i = 0; i < nodes.Count; i++)
            {
                if (nodes[i] == null)
                {
                    BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock(DecompilerContext
                                                                                       .GetCounterContainer().GetCounterAndIncrement(CounterContainer.Statement_Counter
                                                                                                                                     )));
                    StatEdge sample_edge = lstEdges[i][0];
                    bstat.AddSuccessor(new StatEdge(sample_edge.GetType(), bstat, sample_edge.GetDestination
                                                        (), sample_edge.closure));
                    foreach (StatEdge edge in lstEdges[i])
                    {
                        edge.GetSource().ChangeEdgeType(Direction_Forward, edge, StatEdge.Type_Regular);
                        edge.closure.GetLabelEdges().Remove(edge);
                        edge.GetDestination().RemovePredecessor(edge);
                        edge.GetSource().ChangeEdgeNode(Direction_Forward, edge, bstat);
                        bstat.AddPredecessor(edge);
                    }
                    nodes[i] = bstat;
                    stats.AddWithKey(bstat, bstat.id);
                    bstat.SetParent(this);
                }
            }
            caseStatements = nodes;
            caseEdges      = lstEdges;
            caseValues     = lstValues;
        }
Beispiel #3
0
        private IfStatement(Statement head, int regedges, Statement postst)
            : this()
        {
            first = head;
            stats.AddWithKey(head, head.id);
            List <StatEdge> lstHeadSuccs = head.GetSuccessorEdges(Statedge_Direct_All);

            switch (regedges)
            {
            case 0:
            {
                ifstat   = null;
                elsestat = null;
                break;
            }

            case 1:
            {
                ifstat   = null;
                elsestat = null;
                StatEdge edgeif = lstHeadSuccs[1];
                if (edgeif.GetType() != StatEdge.Type_Regular)
                {
                    post = lstHeadSuccs[0].GetDestination();
                }
                else
                {
                    post    = edgeif.GetDestination();
                    negated = true;
                }
                break;
            }

            case 2:
            {
                elsestat = lstHeadSuccs[0].GetDestination();
                ifstat   = lstHeadSuccs[1].GetDestination();
                List <StatEdge> lstSucc  = ifstat.GetSuccessorEdges(StatEdge.Type_Regular);
                List <StatEdge> lstSucc1 = elsestat.GetSuccessorEdges(StatEdge.Type_Regular);
                if (ifstat.GetPredecessorEdges(StatEdge.Type_Regular).Count > 1 || lstSucc.Count
                    > 1)
                {
                    post = ifstat;
                }
                else if (elsestat.GetPredecessorEdges(StatEdge.Type_Regular).Count > 1 || lstSucc1
                         .Count > 1)
                {
                    post = elsestat;
                }
                else if (lstSucc.Count == 0)
                {
                    post = elsestat;
                }
                else if (lstSucc1.Count == 0)
                {
                    post = ifstat;
                }
                if (ifstat == post)
                {
                    if (elsestat != post)
                    {
                        ifstat  = elsestat;
                        negated = true;
                    }
                    else
                    {
                        ifstat = null;
                    }
                    elsestat = null;
                }
                else if (elsestat == post)
                {
                    elsestat = null;
                }
                else
                {
                    post = postst;
                }
                if (elsestat == null)
                {
                    regedges = 1;
                }
                break;
            }
            }
            // if without else
            ifedge   = lstHeadSuccs[negated ? 0 : 1];
            elseedge = (regedges == 2) ? lstHeadSuccs[negated ? 1 : 0] : null;
            iftype   = (regedges == 2) ? Iftype_Ifelse : Iftype_If;
            if (iftype == Iftype_If)
            {
                if (regedges == 0)
                {
                    StatEdge edge = lstHeadSuccs[0];
                    head.RemoveSuccessor(edge);
                    edge.SetSource(this);
                    this.AddSuccessor(edge);
                }
                else if (regedges == 1)
                {
                    StatEdge edge = lstHeadSuccs[negated ? 1 : 0];
                    head.RemoveSuccessor(edge);
                }
            }
            if (ifstat != null)
            {
                stats.AddWithKey(ifstat, ifstat.id);
            }
            if (elsestat != null)
            {
                stats.AddWithKey(elsestat, elsestat.id);
            }
            if (post == head)
            {
                post = this;
            }
        }