예제 #1
0
        // vers.size() == 0 means uninitialized variable, which is impossible
        private void CreateOrUpdatePhiNode(VarVersionPair phivar, FastSparseSetFactory <int> .FastSparseSet <int> vers, Statement stat)
        {
            FastSparseSetFactory <int> .FastSparseSet <int> versCopy = vers.GetCopy();
            HashSet <int> phiVers = new HashSet <int>();
            // take into account the corresponding mm/pp node if existing
            int ppvers = phantomppnodes.ContainsKey(phivar) ? phantomppnodes.GetOrNull(phivar
                                                                                       ).version : -1;
            // ssu graph
            VarVersionNode        phinode  = ssuversions.nodes.GetWithKey(phivar);
            List <VarVersionEdge> lstPreds = new List <VarVersionEdge>(phinode.preds);

            if (lstPreds.Count == 1)
            {
                // not yet a phi node
                VarVersionEdge edge = lstPreds[0];
                edge.source.RemoveSuccessor(edge);
                phinode.RemovePredecessor(edge);
            }
            else
            {
                foreach (VarVersionEdge edge in lstPreds)
                {
                    int verssrc = new Sharpen.EnumeratorAdapter <VarVersionEdge>(edge.source.preds.GetEnumerator()).Next().source.version;
                    if (!vers.Contains(verssrc) && verssrc != ppvers)
                    {
                        edge.source.RemoveSuccessor(edge);
                        phinode.RemovePredecessor(edge);
                    }
                    else
                    {
                        versCopy.Remove(verssrc);
                        phiVers.Add(verssrc);
                    }
                }
            }
            List <VarVersionNode> colnodes = new List <VarVersionNode>();
            List <VarVersionPair> colpaars = new List <VarVersionPair>();

            foreach (int ver in versCopy)
            {
                VarVersionNode prenode = ssuversions.nodes.GetWithKey(new VarVersionPair(phivar.var
                                                                                         , ver));
                int            tempver  = GetNextFreeVersion(phivar.var, stat);
                VarVersionNode tempnode = new VarVersionNode(phivar.var, tempver);
                colnodes.Add(tempnode);
                colpaars.Add(new VarVersionPair(phivar.var, tempver));
                VarVersionEdge edge = new VarVersionEdge(VarVersionEdge.Edge_General, prenode, tempnode
                                                         );
                prenode.AddSuccessor(edge);
                tempnode.AddPredecessor(edge);
                edge = new VarVersionEdge(VarVersionEdge.Edge_General, tempnode, phinode);
                tempnode.AddSuccessor(edge);
                phinode.AddPredecessor(edge);
                phiVers.Add(tempver);
            }
            ssuversions.AddNodes(colnodes, colpaars);
        }
예제 #2
0
        // *****************************************************************************
        // 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;
        }
예제 #3
0
        private void ProcessExprent(Exprent expr, SFormsFastMapDirect[] varmaparr, Statement
                                    stat, bool calcLiveVars)
        {
            if (expr == null)
            {
                return;
            }
            VarExprent varassign = null;
            bool       finished  = false;

            switch (expr.type)
            {
            case Exprent.Exprent_Assignment:
            {
                AssignmentExprent assexpr = (AssignmentExprent)expr;
                if (assexpr.GetCondType() == AssignmentExprent.Condition_None)
                {
                    Exprent dest = assexpr.GetLeft();
                    if (dest.type == Exprent.Exprent_Var)
                    {
                        varassign = (VarExprent)dest;
                    }
                }
                break;
            }

            case Exprent.Exprent_Function:
            {
                FunctionExprent func = (FunctionExprent)expr;
                switch (func.GetFuncType())
                {
                case FunctionExprent.Function_Iif:
                {
                    ProcessExprent(func.GetLstOperands()[0], varmaparr, stat, calcLiveVars);
                    SFormsFastMapDirect varmapFalse;
                    if (varmaparr[1] == null)
                    {
                        varmapFalse = new SFormsFastMapDirect(varmaparr[0]);
                    }
                    else
                    {
                        varmapFalse  = varmaparr[1];
                        varmaparr[1] = null;
                    }
                    ProcessExprent(func.GetLstOperands()[1], varmaparr, stat, calcLiveVars);
                    SFormsFastMapDirect[] varmaparrNeg = new SFormsFastMapDirect[] { varmapFalse, null };
                    ProcessExprent(func.GetLstOperands()[2], varmaparrNeg, stat, calcLiveVars);
                    MergeMaps(varmaparr[0], varmaparrNeg[0]);
                    varmaparr[1] = null;
                    finished     = true;
                    break;
                }

                case FunctionExprent.Function_Cadd:
                {
                    ProcessExprent(func.GetLstOperands()[0], varmaparr, stat, calcLiveVars);
                    SFormsFastMapDirect[] varmaparrAnd = new SFormsFastMapDirect[] { new SFormsFastMapDirect
                                                                                         (varmaparr[0]), null };
                    ProcessExprent(func.GetLstOperands()[1], varmaparrAnd, stat, calcLiveVars);
                    // false map
                    varmaparr[1] = MergeMaps(varmaparr[varmaparr[1] == null ? 0 : 1], varmaparrAnd[varmaparrAnd
                                                                                                   [1] == null ? 0 : 1]);
                    // true map
                    varmaparr[0] = varmaparrAnd[0];
                    finished     = true;
                    break;
                }

                case FunctionExprent.Function_Cor:
                {
                    ProcessExprent(func.GetLstOperands()[0], varmaparr, stat, calcLiveVars);
                    SFormsFastMapDirect[] varmaparrOr = new SFormsFastMapDirect[] { new SFormsFastMapDirect
                                                                                        (varmaparr[varmaparr[1] == null ? 0 : 1]), null };
                    ProcessExprent(func.GetLstOperands()[1], varmaparrOr, stat, calcLiveVars);
                    // false map
                    varmaparr[1] = varmaparrOr[varmaparrOr[1] == null ? 0 : 1];
                    // true map
                    varmaparr[0] = MergeMaps(varmaparr[0], varmaparrOr[0]);
                    finished     = true;
                    break;
                }
                }
                break;
            }
            }
            if (!finished)
            {
                List <Exprent> lst = expr.GetAllExprents();
                lst.Remove(varassign);
                foreach (Exprent ex in lst)
                {
                    ProcessExprent(ex, varmaparr, stat, calcLiveVars);
                }
            }
            SFormsFastMapDirect varmap = varmaparr[0];

            // field access
            if (expr.type == Exprent.Exprent_Field)
            {
                int?index;
                if (mapFieldVars.ContainsKey(expr.id))
                {
                    index = mapFieldVars.GetOrNullable(expr.id);
                }
                else
                {
                    index = fieldvarcounter--;
                    Sharpen.Collections.Put(mapFieldVars, expr.id, index);
                    // ssu graph
                    ssuversions.CreateNode(new VarVersionPair(index, 1));
                }
                SetCurrentVar(varmap, index, 1);
            }
            else if (expr.type == Exprent.Exprent_Invocation || (expr.type == Exprent.Exprent_Assignment &&
                                                                 ((AssignmentExprent)expr).GetLeft().type == Exprent.Exprent_Field) || (expr.
                                                                                                                                        type == Exprent.Exprent_New && ((NewExprent)expr).GetNewType().type == ICodeConstants
                                                                                                                                        .Type_Object) || expr.type == Exprent.Exprent_Function)
            {
                bool ismmpp = true;
                if (expr.type == Exprent.Exprent_Function)
                {
                    ismmpp = false;
                    FunctionExprent fexpr = (FunctionExprent)expr;
                    if (fexpr.GetFuncType() >= FunctionExprent.Function_Imm && fexpr.GetFuncType() <=
                        FunctionExprent.Function_Ppi)
                    {
                        if (fexpr.GetLstOperands()[0].type == Exprent.Exprent_Field)
                        {
                            ismmpp = true;
                        }
                    }
                }
                if (ismmpp)
                {
                    varmap.RemoveAllFields();
                }
            }
            if (varassign != null)
            {
                int varindex = varassign.GetIndex();
                if (varassign.GetVersion() == 0)
                {
                    // get next version
                    int nextver = GetNextFreeVersion(varindex, stat);
                    // set version
                    varassign.SetVersion(nextver);
                    // ssu graph
                    ssuversions.CreateNode(new VarVersionPair(varindex, nextver));
                    SetCurrentVar(varmap, varindex, nextver);
                }
                else
                {
                    if (calcLiveVars)
                    {
                        VarMapToGraph(new VarVersionPair(varindex, varassign.GetVersion()), varmap);
                    }
                    SetCurrentVar(varmap, varindex, varassign.GetVersion());
                }
            }
            else if (expr.type == Exprent.Exprent_Function)
            {
                // MM or PP function
                FunctionExprent func_1 = (FunctionExprent)expr;
                switch (func_1.GetFuncType())
                {
                case FunctionExprent.Function_Imm:
                case FunctionExprent.Function_Mmi:
                case FunctionExprent.Function_Ipp:
                case FunctionExprent.Function_Ppi:
                {
                    if (func_1.GetLstOperands()[0].type == Exprent.Exprent_Var)
                    {
                        VarExprent     var      = (VarExprent)func_1.GetLstOperands()[0];
                        int            varindex = var.GetIndex();
                        VarVersionPair varpaar  = new VarVersionPair(varindex, var.GetVersion());
                        // ssu graph
                        VarVersionPair phantomver = phantomppnodes.GetOrNull(varpaar);
                        if (phantomver == null)
                        {
                            // get next version
                            int nextver = GetNextFreeVersion(varindex, null);
                            phantomver = new VarVersionPair(varindex, nextver);
                            //ssuversions.createOrGetNode(phantomver);
                            ssuversions.CreateNode(phantomver);
                            VarVersionNode vernode = ssuversions.nodes.GetWithKey(varpaar);
                            FastSparseSetFactory <int> .FastSparseSet <int> vers = factory.SpawnEmptySet();
                            if (vernode.preds.Count == 1)
                            {
                                vers.Add(new Sharpen.EnumeratorAdapter <VarVersionEdge>(vernode.preds.GetEnumerator()).Next().source.version);
                            }
                            else
                            {
                                foreach (VarVersionEdge edge in vernode.preds)
                                {
                                    vers.Add(new Sharpen.EnumeratorAdapter <VarVersionEdge>(edge.source.preds.GetEnumerator()).Next().source.version);
                                }
                            }
                            vers.Add(nextver);
                            CreateOrUpdatePhiNode(varpaar, vers, stat);
                            Sharpen.Collections.Put(phantomppnodes, varpaar, phantomver);
                        }
                        if (calcLiveVars)
                        {
                            VarMapToGraph(varpaar, varmap);
                        }
                        SetCurrentVar(varmap, varindex, var.GetVersion());
                    }
                    break;
                }
                }
            }
            else if (expr.type == Exprent.Exprent_Var)
            {
                VarExprent vardest      = (VarExprent)expr;
                int        varindex     = vardest.GetIndex();
                int        current_vers = vardest.GetVersion();
                FastSparseSetFactory <int> .FastSparseSet <int> vers = varmap.Get(varindex);
                int cardinality = vers.GetCardinality();
                if (cardinality == 1)
                {
                    // size == 1
                    if (current_vers != 0)
                    {
                        if (calcLiveVars)
                        {
                            VarMapToGraph(new VarVersionPair(varindex, current_vers), varmap);
                        }
                        SetCurrentVar(varmap, varindex, current_vers);
                    }
                    else
                    {
                        // split last version
                        int usever = GetNextFreeVersion(varindex, stat);
                        // set version
                        vardest.SetVersion(usever);
                        SetCurrentVar(varmap, varindex, usever);
                        // ssu graph
                        int            lastver = new Sharpen.EnumeratorAdapter <int>(vers.GetEnumerator()).Next();
                        VarVersionNode prenode = ssuversions.nodes.GetWithKey(new VarVersionPair(varindex
                                                                                                 , lastver));
                        VarVersionNode usenode = ssuversions.CreateNode(new VarVersionPair(varindex, usever
                                                                                           ));
                        VarVersionEdge edge = new VarVersionEdge(VarVersionEdge.Edge_General, prenode, usenode
                                                                 );
                        prenode.AddSuccessor(edge);
                        usenode.AddPredecessor(edge);
                    }
                }
                else if (cardinality == 2)
                {
                    // size > 1
                    if (current_vers != 0)
                    {
                        if (calcLiveVars)
                        {
                            VarMapToGraph(new VarVersionPair(varindex, current_vers), varmap);
                        }
                        SetCurrentVar(varmap, varindex, current_vers);
                    }
                    else
                    {
                        // split version
                        int usever = GetNextFreeVersion(varindex, stat);
                        // set version
                        vardest.SetVersion(usever);
                        // ssu node
                        ssuversions.CreateNode(new VarVersionPair(varindex, usever));
                        SetCurrentVar(varmap, varindex, usever);
                        current_vers = usever;
                    }
                    CreateOrUpdatePhiNode(new VarVersionPair(varindex, current_vers), vers, stat);
                }
            }
        }
예제 #4
0
        private static void ProcessEdgesWithNext(Statement stat, Dictionary <Statement, List <StatEdge> > mapEdges, Statement next)
        {
            StatEdge        statedge = null;
            List <StatEdge> lstSuccs = stat.GetAllSuccessorEdges();

            if (!(lstSuccs.Count == 0))
            {
                statedge = lstSuccs[0];
                if (statedge.GetDestination() == next)
                {
                    statedge.@explicit = false;
                    statedge           = null;
                }
                else
                {
                    next = statedge.GetDestination();
                }
            }
            // no next for a do statement
            if (stat.type == Statement.Type_Do && ((DoStatement)stat).GetLooptype() == DoStatement
                .Loop_Do)
            {
                next = null;
            }
            if (next == null)
            {
                if (mapEdges.Count == 1)
                {
                    List <StatEdge> lstEdges = new Sharpen.EnumeratorAdapter <List <StatEdge> >(mapEdges.Values.GetEnumerator()).Next();
                    if (lstEdges.Count > 1 && new Sharpen.EnumeratorAdapter <Statement>(mapEdges.Keys.GetEnumerator()).Next().type != Statement
                        .Type_Dummyexit)
                    {
                        StatEdge  edge_example = lstEdges[0];
                        Statement closure      = stat.GetParent();
                        if (!closure.ContainsStatementStrict(edge_example.closure))
                        {
                            closure = edge_example.closure;
                        }
                        StatEdge newedge = new StatEdge(edge_example.GetType(), stat, edge_example.GetDestination
                                                            (), closure);
                        stat.AddSuccessor(newedge);
                        foreach (StatEdge edge in lstEdges)
                        {
                            edge.@explicit = false;
                        }
                        Sharpen.Collections.Put(mapEdges, newedge.GetDestination(), new List <StatEdge>(System.Linq.Enumerable.ToList(new [] {
                            newedge
                        })));
                    }
                }
            }
            else
            {
                bool implfound = false;
                foreach (KeyValuePair <Statement, List <StatEdge> > entr in mapEdges)
                {
                    if (entr.Key == next)
                    {
                        foreach (StatEdge edge in entr.Value)
                        {
                            edge.@explicit = false;
                        }
                        implfound = true;
                        break;
                    }
                }
                if ((stat.GetAllSuccessorEdges().Count == 0) && !implfound)
                {
                    List <StatEdge> lstEdges = null;
                    foreach (KeyValuePair <Statement, List <StatEdge> > entr in mapEdges)
                    {
                        if (entr.Key.type != Statement.Type_Dummyexit && (lstEdges == null || entr.Value.
                                                                          Count > lstEdges.Count))
                        {
                            lstEdges = entr.Value;
                        }
                    }
                    if (lstEdges != null && lstEdges.Count > 1)
                    {
                        StatEdge  edge_example = lstEdges[0];
                        Statement closure      = stat.GetParent();
                        if (!closure.ContainsStatementStrict(edge_example.closure))
                        {
                            closure = edge_example.closure;
                        }
                        StatEdge newedge = new StatEdge(edge_example.GetType(), stat, edge_example.GetDestination
                                                            (), closure);
                        stat.AddSuccessor(newedge);
                        foreach (StatEdge edge in lstEdges)
                        {
                            edge.@explicit = false;
                        }
                    }
                }
                mapEdges.Clear();
            }
            if (statedge != null)
            {
                Sharpen.Collections.Put(mapEdges, statedge.GetDestination(), new List <StatEdge>(System.Linq.Enumerable.ToList(new [] {
                    statedge
                })));
            }
        }
        private void ProcessExprent(Exprent expr, SFormsFastMapDirect[] varmaparr)
        {
            if (expr == null)
            {
                return;
            }
            VarExprent varassign = null;
            bool       finished  = false;

            switch (expr.type)
            {
            case Exprent.Exprent_Assignment:
            {
                AssignmentExprent assexpr = (AssignmentExprent)expr;
                if (assexpr.GetCondType() == AssignmentExprent.Condition_None)
                {
                    Exprent dest = assexpr.GetLeft();
                    if (dest.type == Exprent.Exprent_Var)
                    {
                        varassign = (VarExprent)dest;
                    }
                }
                break;
            }

            case Exprent.Exprent_Function:
            {
                FunctionExprent func = (FunctionExprent)expr;
                switch (func.GetFuncType())
                {
                case FunctionExprent.Function_Iif:
                {
                    ProcessExprent(func.GetLstOperands()[0], varmaparr);
                    SFormsFastMapDirect varmapFalse;
                    if (varmaparr[1] == null)
                    {
                        varmapFalse = new SFormsFastMapDirect(varmaparr[0]);
                    }
                    else
                    {
                        varmapFalse  = varmaparr[1];
                        varmaparr[1] = null;
                    }
                    ProcessExprent(func.GetLstOperands()[1], varmaparr);
                    SFormsFastMapDirect[] varmaparrNeg = new SFormsFastMapDirect[] { varmapFalse, null };
                    ProcessExprent(func.GetLstOperands()[2], varmaparrNeg);
                    MergeMaps(varmaparr[0], varmaparrNeg[0]);
                    varmaparr[1] = null;
                    finished     = true;
                    break;
                }

                case FunctionExprent.Function_Cadd:
                {
                    ProcessExprent(func.GetLstOperands()[0], varmaparr);
                    SFormsFastMapDirect[] varmaparrAnd = new SFormsFastMapDirect[] { new SFormsFastMapDirect
                                                                                         (varmaparr[0]), null };
                    ProcessExprent(func.GetLstOperands()[1], varmaparrAnd);
                    // false map
                    varmaparr[1] = MergeMaps(varmaparr[varmaparr[1] == null ? 0 : 1], varmaparrAnd[varmaparrAnd
                                                                                                   [1] == null ? 0 : 1]);
                    // true map
                    varmaparr[0] = varmaparrAnd[0];
                    finished     = true;
                    break;
                }

                case FunctionExprent.Function_Cor:
                {
                    ProcessExprent(func.GetLstOperands()[0], varmaparr);
                    SFormsFastMapDirect[] varmaparrOr = new SFormsFastMapDirect[] { new SFormsFastMapDirect
                                                                                        (varmaparr[varmaparr[1] == null ? 0 : 1]), null };
                    ProcessExprent(func.GetLstOperands()[1], varmaparrOr);
                    // false map
                    varmaparr[1] = varmaparrOr[varmaparrOr[1] == null ? 0 : 1];
                    // true map
                    varmaparr[0] = MergeMaps(varmaparr[0], varmaparrOr[0]);
                    finished     = true;
                    break;
                }
                }
                break;
            }
            }
            if (finished)
            {
                return;
            }
            List <Exprent> lst = expr.GetAllExprents();

            lst.Remove(varassign);
            foreach (Exprent ex in lst)
            {
                ProcessExprent(ex, varmaparr);
            }
            SFormsFastMapDirect varmap = varmaparr[0];

            if (varassign != null)
            {
                int varindex = varassign.GetIndex();
                if (varassign.GetVersion() == 0)
                {
                    // get next version
                    int nextver = GetNextFreeVersion(varindex);
                    // set version
                    varassign.SetVersion(nextver);
                    SetCurrentVar(varmap, varindex, nextver);
                }
                else
                {
                    SetCurrentVar(varmap, varindex, varassign.GetVersion());
                }
            }
            else if (expr.type == Exprent.Exprent_Var)
            {
                VarExprent vardest  = (VarExprent)expr;
                int        varindex = vardest.GetIndex();
                FastSparseSetFactory <int> .FastSparseSet <int> vers = varmap.Get(varindex);
                int cardinality = vers.GetCardinality();
                if (cardinality == 1)
                {
                    // == 1
                    // set version
                    int it = new Sharpen.EnumeratorAdapter <int>(vers.GetEnumerator()).Next();
                    vardest.SetVersion(it);
                }
                else if (cardinality == 2)
                {
                    // size > 1
                    int            current_vers = vardest.GetVersion();
                    VarVersionPair currpaar     = new VarVersionPair(varindex, current_vers);
                    if (current_vers != 0 && phi.ContainsKey(currpaar))
                    {
                        SetCurrentVar(varmap, varindex, current_vers);
                        // update phi node
                        phi.GetOrNull(currpaar).Union(vers);
                    }
                    else
                    {
                        // increase version
                        int nextver = GetNextFreeVersion(varindex);
                        // set version
                        vardest.SetVersion(nextver);
                        SetCurrentVar(varmap, varindex, nextver);
                        // create new phi node
                        Sharpen.Collections.Put(phi, new VarVersionPair(varindex, nextver), vers);
                    }
                }
            }
        }
예제 #6
0
 public static void ExtendSynchronizedRangeToMonitorexit(ControlFlowGraph graph)
 {
     while (true)
     {
         bool range_extended = false;
         foreach (ExceptionRangeCFG range in graph.GetExceptions())
         {
             HashSet <BasicBlock> setPreds = new HashSet <BasicBlock>();
             foreach (BasicBlock block in range.GetProtectedRange())
             {
                 Sharpen.Collections.AddAll(setPreds, block.GetPreds());
             }
             setPreds.ExceptWith(range.GetProtectedRange());
             if (setPreds.Count != 1)
             {
                 continue;
             }
             // multiple predecessors, obfuscated range
             var                 setPredsEnumerator = new EnumeratorAdapter <BasicBlock>(setPreds.GetEnumerator());
             BasicBlock          predBlock          = setPredsEnumerator.Next();
             InstructionSequence predSeq            = predBlock.GetSeq();
             if (predSeq.IsEmpty() || predSeq.GetLastInstr().opcode != ICodeConstants.opc_monitorenter)
             {
                 continue;
             }
             // not a synchronized range
             bool monitorexit_in_range = false;
             HashSet <BasicBlock> setProtectedBlocks = new HashSet <BasicBlock>();
             Sharpen.Collections.AddAll(setProtectedBlocks, range.GetProtectedRange());
             setProtectedBlocks.Add(range.GetHandler());
             foreach (BasicBlock block in setProtectedBlocks)
             {
                 InstructionSequence blockSeq = block.GetSeq();
                 for (int i = 0; i < blockSeq.Length(); i++)
                 {
                     if (blockSeq.GetInstr(i).opcode == ICodeConstants.opc_monitorexit)
                     {
                         monitorexit_in_range = true;
                         break;
                     }
                 }
                 if (monitorexit_in_range)
                 {
                     break;
                 }
             }
             if (monitorexit_in_range)
             {
                 continue;
             }
             // protected range already contains monitorexit
             HashSet <BasicBlock> setSuccs = new HashSet <BasicBlock>();
             foreach (BasicBlock block in range.GetProtectedRange())
             {
                 Sharpen.Collections.AddAll(setSuccs, block.GetSuccs());
             }
             setSuccs.ExceptWith(range.GetProtectedRange());
             if (setSuccs.Count != 1)
             {
                 continue;
             }
             // non-unique successor
             BasicBlock          succBlock = new Sharpen.EnumeratorAdapter <BasicBlock>(setSuccs.GetEnumerator()).Next();
             InstructionSequence succSeq   = succBlock.GetSeq();
             int succ_monitorexit_index    = -1;
             for (int i = 0; i < succSeq.Length(); i++)
             {
                 if (succSeq.GetInstr(i).opcode == ICodeConstants.opc_monitorexit)
                 {
                     succ_monitorexit_index = i;
                     break;
                 }
             }
             if (succ_monitorexit_index < 0)
             {
                 continue;
             }
             // monitorexit not found in the single successor block
             BasicBlock handlerBlock = range.GetHandler();
             if (handlerBlock.GetSuccs().Count != 1)
             {
                 continue;
             }
             // non-unique handler successor
             BasicBlock          succHandler    = handlerBlock.GetSuccs()[0];
             InstructionSequence succHandlerSeq = succHandler.GetSeq();
             if (succHandlerSeq.IsEmpty() || succHandlerSeq.GetLastInstr().opcode != ICodeConstants
                 .opc_athrow)
             {
                 continue;
             }
             // not a standard synchronized range
             int handler_monitorexit_index = -1;
             for (int i = 0; i < succHandlerSeq.Length(); i++)
             {
                 if (succHandlerSeq.GetInstr(i).opcode == ICodeConstants.opc_monitorexit)
                 {
                     handler_monitorexit_index = i;
                     break;
                 }
             }
             if (handler_monitorexit_index < 0)
             {
                 continue;
             }
             // monitorexit not found in the handler successor block
             // checks successful, prerequisites satisfied, now extend the range
             if (succ_monitorexit_index < succSeq.Length() - 1)
             {
                 // split block
                 SimpleInstructionSequence seq = new SimpleInstructionSequence();
                 for (int counter = 0; counter < succ_monitorexit_index; counter++)
                 {
                     seq.AddInstruction(succSeq.GetInstr(0), -1);
                     succSeq.RemoveInstruction(0);
                 }
                 // build a separate block
                 BasicBlock newblock = new BasicBlock(++graph.last_id);
                 newblock.SetSeq(seq);
                 // insert new block
                 foreach (BasicBlock block in succBlock.GetPreds())
                 {
                     block.ReplaceSuccessor(succBlock, newblock);
                 }
                 newblock.AddSuccessor(succBlock);
                 graph.GetBlocks().AddWithKey(newblock, newblock.id);
                 succBlock = newblock;
             }
             // copy exception edges and extend protected ranges (successor block)
             BasicBlock rangeExitBlock = succBlock.GetPreds()[0];
             for (int j = 0; j < rangeExitBlock.GetSuccExceptions().Count; j++)
             {
                 BasicBlock hd = rangeExitBlock.GetSuccExceptions()[j];
                 succBlock.AddSuccessorException(hd);
                 ExceptionRangeCFG rng = graph.GetExceptionRange(hd, rangeExitBlock);
                 rng.GetProtectedRange().Add(succBlock);
             }
             // copy instructions (handler successor block)
             InstructionSequence handlerSeq = handlerBlock.GetSeq();
             for (int counter = 0; counter < handler_monitorexit_index; counter++)
             {
                 handlerSeq.AddInstruction(succHandlerSeq.GetInstr(0), -1);
                 succHandlerSeq.RemoveInstruction(0);
             }
             range_extended = true;
             break;
         }
         if (!range_extended)
         {
             break;
         }
     }
 }
예제 #7
0
        public static bool IsChoiceStatement(Statement head, List <Statement> lst)
        {
            Statement           post    = null;
            HashSet <Statement> setDest = head.GetNeighboursSet(StatEdge.Type_Regular, Statement
                                                                .Direction_Forward);

            if (setDest.Contains(head))
            {
                return(false);
            }
            while (true)
            {
                lst.Clear();
                bool repeat = false;
                setDest.Remove(post);
                foreach (Statement stat in setDest)
                {
                    if (stat.GetLastBasicType() != Statement.Lastbasictype_General)
                    {
                        if (post == null)
                        {
                            post   = stat;
                            repeat = true;
                            break;
                        }
                        else
                        {
                            return(false);
                        }
                    }
                    // preds
                    HashSet <Statement> setPred = stat.GetNeighboursSet(StatEdge.Type_Regular, Statement
                                                                        .Direction_Backward);
                    setPred.Remove(head);
                    if (setPred.Contains(stat))
                    {
                        return(false);
                    }
                    if (!setPred.All(setDest.Contains) || setPred.Count > 1)
                    {
                        if (post == null)
                        {
                            post   = stat;
                            repeat = true;
                            break;
                        }
                        else
                        {
                            return(false);
                        }
                    }
                    else if (setPred.Count == 1)
                    {
                        Statement pred = new Sharpen.EnumeratorAdapter <Statement>(setPred.GetEnumerator()).Next();
                        while (lst.Contains(pred))
                        {
                            HashSet <Statement> setPredTemp = pred.GetNeighboursSet(StatEdge.Type_Regular, Statement
                                                                                    .Direction_Backward);
                            setPredTemp.Remove(head);
                            if (!(setPredTemp.Count == 0))
                            {
                                // at most 1 predecessor
                                pred = new Sharpen.EnumeratorAdapter <Statement>(setPredTemp.GetEnumerator()).Next();
                                if (pred == stat)
                                {
                                    return(false);
                                }
                            }
                            else
                            {
                                // loop found
                                break;
                            }
                        }
                    }
                    // succs
                    List <StatEdge> lstEdges = stat.GetSuccessorEdges(Statement.Statedge_Direct_All);
                    if (lstEdges.Count > 1)
                    {
                        HashSet <Statement> setSucc = stat.GetNeighboursSet(Statement.Statedge_Direct_All,
                                                                            Statement.Direction_Forward);
                        setSucc.RetainAll(setDest);
                        if (setSucc.Count > 0)
                        {
                            return(false);
                        }
                        else if (post == null)
                        {
                            post   = stat;
                            repeat = true;
                            break;
                        }
                        else
                        {
                            return(false);
                        }
                    }
                    else if (lstEdges.Count == 1)
                    {
                        StatEdge edge = lstEdges[0];
                        if (edge.GetType() == StatEdge.Type_Regular)
                        {
                            Statement statd = edge.GetDestination();
                            if (head == statd)
                            {
                                return(false);
                            }
                            if (post != statd && !setDest.Contains(statd))
                            {
                                if (post != null)
                                {
                                    return(false);
                                }
                                else
                                {
                                    HashSet <Statement> set = statd.GetNeighboursSet(StatEdge.Type_Regular, Statement.
                                                                                     Direction_Backward);
                                    if (set.Count > 1)
                                    {
                                        post   = statd;
                                        repeat = true;
                                        break;
                                    }
                                    else
                                    {
                                        return(false);
                                    }
                                }
                            }
                        }
                    }
                    lst.Add(stat);
                }
                if (!repeat)
                {
                    break;
                }
            }
            lst.Add(head);
            lst.Remove(post);
            lst.Add(0, post);
            return(true);
        }
예제 #8
0
        public static bool IsStatementIrreducible(Statement statement)
        {
            Dictionary <int, _T989645285> mapNodes = new Dictionary <int, _T989645285>();

            // checking exceptions and creating nodes
            foreach (Statement stat in statement.GetStats())
            {
                if (!(stat.GetSuccessorEdges(StatEdge.Type_Exception).Count == 0))
                {
                    return(false);
                }
                Sharpen.Collections.Put(mapNodes, stat.id, new _T989645285(stat.id));
            }
            // connecting nodes
            foreach (Statement stat in statement.GetStats())
            {
                _T989645285 node = mapNodes.GetOrNull(stat.id);
                foreach (Statement succ in stat.GetNeighbours(StatEdge.Type_Regular, Statement.Direction_Forward
                                                              ))
                {
                    _T989645285 nodeSucc = mapNodes.GetOrNull(succ.id);
                    node.succs.Add(nodeSucc);
                    nodeSucc.preds.Add(node);
                }
            }
            // transforming and reducing the graph
            while (true)
            {
                int         ttype = 0;
                _T989645285 node  = null;
                foreach (_T989645285 nd in mapNodes.Values)
                {
                    if (nd.succs.Contains(nd))
                    {
                        // T1
                        ttype = 1;
                    }
                    else if (nd.preds.Count == 1)
                    {
                        // T2
                        ttype = 2;
                    }
                    if (ttype != 0)
                    {
                        node = nd;
                        break;
                    }
                }
                if (node != null)
                {
                    if (ttype == 1)
                    {
                        node.succs.Remove(node);
                        node.preds.Remove(node);
                    }
                    else
                    {
                        _T989645285 pred = new Sharpen.EnumeratorAdapter <_T989645285>(node.preds.GetEnumerator()).Next();
                        Sharpen.Collections.AddAll(pred.succs, node.succs);
                        pred.succs.Remove(node);
                        foreach (_T989645285 succ in node.succs)
                        {
                            succ.preds.Remove(node);
                            succ.preds.Add(pred);
                        }
                        Sharpen.Collections.Remove(mapNodes, node.id);
                    }
                }
                else
                {
                    // no transformation applicable
                    return(mapNodes.Count > 1);
                }
            }
        }