public ScanResults ScanImage(ScanResults sr) { this.sr = sr; // sr.WatchedAddresses.Add(Address.Ptr32(0x00404F5C)); //$DEBUG // At this point, we have some entries in the image map // that are data, and unscanned ranges in betweeen. We // have hopefully a bunch of procedure addresses to // break up the unscanned ranges. if (ScanInstructions(sr) == null) { return(sr); } var the_blocks = BuildBasicBlocks(sr); sr.BreakOnWatchedAddress(the_blocks.Select(q => q.Key)); the_blocks = RemoveInvalidBlocks(sr, the_blocks); // Remove blocks that fall off the end of the segment // or into data. Probe(sr); sr.ICFG = BuildIcfg(sr, program.NamingPolicy, the_blocks); Probe(sr); sr.Dump("After shingle scan"); // On processors with variable length instructions, // there may be many blocks that partially overlap the // "real" blocks that would actually have been executed // by the processor. Starting with known "roots", try to // remove as many invalid blocks as possible. var hsc = new BlockConflictResolver( program, sr, program.SegmentMap.IsValidAddress, host); Probe(sr); hsc.ResolveBlockConflicts(sr.KnownProcedures.Concat(sr.DirectlyCalledAddresses.Keys)); Probe(sr); sr.Dump("After block conflict resolution"); // If we detect padding bytes between blocks, // we remove them now. var ppf = new ProcedurePaddingFinder(sr); var pads = ppf.FindPaddingBlocks(); ppf.Remove(pads); var pd = new ProcedureDetector(program, sr, this.eventListener); var procs = pd.DetectProcedures(); sr.Procedures = procs; sr.RemovedPadding = pads; return(sr); }
/// <summary> /// Given a set of clusters, finds all the entries for each cluster /// and tries to partition each cluster into procedures with single /// entries and exits. /// </summary> /// <param name="sr"></param> /// <param name="clusters"></param> private List <RtlProcedure> BuildProcedures(IEnumerable <Cluster> clusters) { var procs = new List <RtlProcedure>(); foreach (var cluster in clusters) { if (listener.IsCanceled()) { break; } FuseLinearBlocks(cluster); // cluster.Dump(sr.ICFG); sr.BreakOnWatchedAddress(cluster.Blocks.Select(b => b.Address)); var bcr = new BlockConflictResolver(null, sr, a => true, null); bcr.ResolveBlockConflicts(new Address[0]); if (FindClusterEntries(cluster)) { procs.AddRange(PostProcessCluster(cluster)); } } return(procs); }
public ScanResults?ScanImage(ScanResults sr) { // At this point, we have some entries in the image map // that are data, and unscanned ranges in betweeen. We // have hopefully a bunch of procedure addresses to // break up the unscanned ranges. var ranges = FindUnscannedRanges(); var stopwatch = new Stopwatch(); var shsc = new ShingledScanner(program, host, storageBinder, sr, eventListener); bool unscanned = false; foreach (var range in ranges) { unscanned = true; try { shsc.ScanRange( program.Architecture, range.Item1, range.Item2, range.Item3, range.Item3); } catch (AddressCorrelatedException aex) { host.Error(aex.Address, aex.Message); } } if (!unscanned) { // No unscanned blocks were found. return(null); } // Remove blocks that fall off the end of the segment // or into data. Probe(sr); shsc.Dump("After shingle scan graph built"); var deadNodes = shsc.RemoveBadInstructionsFromGraph(); shsc.BuildIcfg(deadNodes); Probe(sr); sr.Dump("After shingle scan"); // On processors with variable length instructions, // there may be many blocks that partially overlap the // "real" blocks that would actually have been executed // by the processor. Starting with known "roots", try to // remove as many invalid blocks as possible. var hsc = new BlockConflictResolver( program, sr, program.SegmentMap.IsValidAddress, host); RemoveInvalidBlocks(sr); Probe(sr); hsc.ResolveBlockConflicts(sr.KnownProcedures.Concat(sr.DirectlyCalledAddresses.Keys)); Probe(sr); sr.Dump("After block conflict resolution"); var pd = new ProcedureDetector(program, sr, this.eventListener); var procs = pd.DetectProcedures(); sr.Procedures = procs; return(sr); }