// ***************************************************************************** // 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; }
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; } }