Example #1
0
        /// <summary>
        /// Collects weakly connected components from the ICFG and gathers
        /// them into Clusters.
        /// </summary>
        public List <Cluster> FindClusters()
        {
            var nodesLeft  = new HashSet <RtlBlock>(sr.ICFG.Nodes);
            var clusters   = new List <Cluster>();
            int totalCount = nodesLeft.Count;

            if (totalCount > 0)
            {
                listener.ShowProgress("Finding procedure candidates", 0, totalCount);
                var wl = WorkList.Create(nodesLeft);
                while (wl.TryGetWorkItem(out var node))
                {
                    if (listener.IsCanceled())
                    {
                        break;
                    }
                    var cluster = new Cluster();
                    clusters.Add(cluster);

                    BuildWCC(node, cluster, wl);
                    sr.BreakOnWatchedAddress(cluster.Blocks.Select(b => b.Address));
                    listener.ShowProgress("Finding procedure candidates", totalCount - nodesLeft.Count, totalCount);
                }
            }
            return(clusters);
        }
Example #2
0
        /// <summary>
        /// As far as possible, try fusing consecutive linear blocks in the
        /// cluster.
        /// </summary>
        /// <param name="cluster"></param>
        public void FuseLinearBlocks(Cluster cluster)
        {
            var wl = WorkList.Create(cluster.Blocks);

            while (wl.TryGetWorkItem(out var block))
            {
                if (sr.ICFG.Successors(block).Count != 1)
                {
                    continue;
                }
                var succ = sr.ICFG.Successors(block).First();
                if (sr.ICFG.Predecessors(succ).Count != 1)
                {
                    continue;
                }
                Debug.Assert(sr.ICFG.Predecessors(succ).First() == block, "Inconsistent graph");
                if (!(block.Instructions.Last().Instructions.Last() is RtlAssignment))
                {
                    continue;
                }

                // Move all instructions into predecessor.
                block.Instructions.AddRange(succ.Instructions);
                sr.ICFG.RemoveEdge(block, succ);
                var succSuccs = sr.ICFG.Successors(succ).ToList();
                foreach (var ss in succSuccs)
                {
                    sr.ICFG.RemoveEdge(succ, ss);
                    sr.ICFG.AddEdge(block, ss);
                }
                cluster.Blocks.Remove(succ);
                // May be more blocks.
                wl.Add(block);
            }
        }
Example #3
0
        public override Dictionary <string, IDictionary <Address, IAddressable> > GetObjectPlacements(string fileExtension, DecompilerEventListener listener)
        {
            this.defaultFile     = Path.ChangeExtension(program.Name, fileExtension);
            this.defaultDataFile = Path.ChangeExtension(program.Name, "globals" + fileExtension);

            // Find the segment for each procedure
            var result = new Dictionary <string, IDictionary <Address, IAddressable> >();

            foreach (var proc in program.Procedures.Values)
            {
                PlaceObject(proc, defaultFile, result);
            }

            // Place all global objects.
            var wl = WorkList.Create(
                MakeGlobalWorkItems()
                .Concat(MakeSegmentWorkitems()));
            var objectTracer = new GlobalObjectTracer(program, wl, listener);

            while (wl.TryGetWorkItem(out var item))
            {
                var(field, addr) = item;
                var globalVar = new GlobalVariable(addr, field.DataType, program.NamingPolicy.GlobalName(field));
                PlaceObject(globalVar, defaultDataFile, result);
                objectTracer.TraceObject(field.DataType, addr);
            }
            return(result);
        }
Example #4
0
        public void Transform()
        {
            var wl = WorkList.Create(ssa.Procedure.Statements);

            while (wl.TryGetWorkItem(out var stm))
            {
                var prjf  = new ProjectionFilter(ssa, stm, sac);
                var instr = stm.Instruction.Accept(prjf);
                stm.Instruction = instr;
                wl.AddRange(prjf.NewStatements);
            }
        }
Example #5
0
        /// <summary>
        /// For each procedure/SSA state, compute the variables that are live-out
        /// (and which bit ranges are live-out) and store them in the procedure flow.
        /// </summary>
        private void CollectLiveOutStorages()
        {
            var wl = WorkList.Create(ssaStates);

            while (wl.TryGetWorkItem(out SsaState ssa))
            {
                var liveOut = CollectLiveOutStorages(ssa.Procedure);
                var flow    = dataFlow.ProcedureFlows[ssa.Procedure];
                var changed = MergeLiveOut(flow, liveOut);
                if (changed)
                {
                    wl.AddRange(program.CallGraph.Callees(ssa.Procedure).Select(p => procToSsa[p]));
                }
            }
        }
        public DataType BuildOverlappedStructure(List <StructureField> fields)
        {
            List <StructureType> types = new List <StructureType>();
            int commonOffset           = CommonOffset(fields);
            var worklist = WorkList.Create(fields);

            while (worklist.TryGetWorkItem(out StructureField field))
            {
                StructureType?s = FindStructureToFitIn(field, commonOffset, types);
                if (s == null)
                {
                    s = new StructureType();
                    types.Add(s);
                }
                s.Fields.Add(new StructureField(field.Offset - commonOffset, field.DataType));
            }
            return(Normalize(types));
        }
        public void Transform()
        {
            var wl = WorkList.Create(proc.ControlGraph.Blocks);

            while (wl.TryGetWorkItem(out Block block))
            {
                if (listener.IsCanceled())
                {
                    return;
                }
                var c = DetermineCandidate(block);
                if (c == null)
                {
                    continue;
                }
                FuseIntoPredecessor(c);

                // We may need to mutate the predecessor again.
                wl.Add(c.Predecessor !);
            }
        }
Example #8
0
        static void MergeChildNodes(XElement dst, XElement src)
        {
            var dstNodes = WorkList.Create(dst);
            var srcNodes = WorkList.Create(src);

            // First skip all _identical_ nodes
            // (doesn't actually merge anything, just removes identical nodes from work list)
            MergeNodesBothDirections(
                dstNodes,
                srcNodes,
                DeepEquals);

            // First merge all where name matches
            MergeNodesBothDirections(
                dstNodes,
                srcNodes,
                (dstNode, srcNode) =>
            {
                if (dstNode.NodeType != srcNode.NodeType)
                {
                    return(false);
                }
                if (dstNode.NodeType == XmlNodeType.Element)
                {
                    if (((XElement)dstNode).Name != ((XElement)srcNode).Name)
                    {
                        return(false);
                    }
                }
                Merge(dstNode, srcNode);
                return(true);
            });

            // Then merge all where only node type matches
            MergeNodesBothDirections(
                dstNodes,
                srcNodes,
                (dstNode, srcNode) =>
            {
                if (dstNode.NodeType != srcNode.NodeType)
                {
                    return(false);
                }
                Merge(dstNode, srcNode);
                return(true);
            });

            while (!dstNodes.IsEmpty)
            {
                var node = dstNodes.Pop(Position.Tail);
                node.Remove();
            }

            XNode dstInsertPoint = null;

            while (!srcNodes.IsEmpty)
            {
                // We need to know where to insert this.
                var srcNode = srcNodes.Pop(Position.Head);
                var dstNode = CloneNode(srcNode);
                if (dstInsertPoint == null)
                {
                    var srcIndex = srcNode.NodeIndex();
                    if (srcIndex == 0)
                    {
                        dst.AddFirst(dstNode);
                    }
                    else
                    {
                        dstInsertPoint = dst.FirstNode;
                        // Insert point will be element before srcNode index
                        for (int dstIndex = 0; dstIndex < (srcIndex - 1); dstIndex++)
                        {
                            dstInsertPoint = dstInsertPoint.NextNode;
                        }
                        dstInsertPoint.AddAfterSelf(dstNode);
                    }
                }
                else
                {
                    dstInsertPoint.AddAfterSelf(dstNode);
                }

                dstInsertPoint = dstNode;
            }
        }
        static void MergeChildNodes(IUxContainerInternals dst, IUxContainerInternals src)
        {
            var dstNodes = WorkList.Create(dst);
            var srcNodes = WorkList.Create(src);

            // First skip all _identical_ nodes
            // (doesn't actually merge anything, just removes identical nodes from work list)
            MergeNodesBothDirections(
                dstNodes,
                srcNodes,
                DeepEquals);

            // First merge all where name matches
            MergeNodesBothDirections(
                dstNodes,
                srcNodes,
                (dstNode, srcNode) =>
            {
                if (dstNode.NodeType != srcNode.NodeType)
                {
                    return(false);
                }
                if (dstNode.NodeType == XmlNodeType.Element)
                {
                    if (((UxElement)dstNode).Name != ((UxElement)srcNode).Name)
                    {
                        return(false);
                    }
                }
                Merge(dstNode, srcNode);
                return(true);
            });

            // Then merge all where only node type matches
            MergeNodesBothDirections(
                dstNodes,
                srcNodes,
                (dstNode, srcNode) =>
            {
                if (dstNode.NodeType != srcNode.NodeType)
                {
                    return(false);
                }
                Merge(dstNode, srcNode);
                return(true);
            });

            while (!dstNodes.IsEmpty)
            {
                var node = dstNodes.Pop(Position.Tail);
                node.Remove();
            }

            while (!srcNodes.IsEmpty)
            {
                // We need to know where to insert this.
                var srcNode = srcNodes.Pop(Position.Head);
                var dstNode = CloneNode(srcNode);
                dst.Nodes.Insert(srcNode.NodeIndex, dstNode);
            }
        }