/// Plan of attack: /// In each unscanned "hole", look for signatures of procedure entries. /// These are procedure entry candidates. /// Scan each of the procedure entry candidates heuristically. /// /// Next scan all executable code segments for: /// - calls that reach those candidates /// - jmps to those candidates /// - pointers to those candidates. /// Each time we find a call, we increase the score of the candidate. /// At the end we have a list of scored candidates. public void ScanImageHeuristically() { var sw = new Stopwatch(); sw.Start(); var list = new List <HeuristicBlock>(); var ranges = FindUnscannedRanges(); var fnRanges = FindPossibleFunctions(ranges).ToList(); int n = 0; foreach (var range in fnRanges) { var hproc = DisassembleProcedure(range.Item1, range.Item2); var hps = new HeuristicProcedureScanner(program, hproc, host); hps.BlockConflictResolution(); DumpBlocks(hproc.Cfg.Nodes); hps.GapResolution(); // TODO: add all guessed code to image map -- clearly labelled. AddBlocks(hproc); list.AddRange(hproc.Cfg.Nodes); eventListener.ShowProgress("Estimating procedures", n, fnRanges.Count); ++n; } eventListener.Warn( new Reko.Core.Services.NullCodeLocation("Heuristics"), string.Format("Scanned image in {0} seconds, finding {1} blocks.", sw.Elapsed.TotalSeconds, list.Count)); list.ToString(); }
public ScanResults ScanImage(ScanResults sr) { this.sr = sr; // sr.WatchedAddresses.Add(Address.Ptr64(0x0000000000405EF3)); //$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(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 HeuristicProcedureScanner( program, sr, program.SegmentMap.IsValidAddress, host); Probe(sr); hsc.ResolveBlockConflicts(sr.KnownProcedures.Concat(sr.DirectlyCalledAddresses.Keys)); Probe(sr); sr.Dump("After block conflict resolution"); // Collect weakly connected components and create // procedures from them. var pd = new ProcedureDetector(program, sr, this.eventListener); var procs = pd.DetectProcedures(); sr.Procedures = procs; return(sr); }
public void ScanImageHeuristically() { var heuristicScanner = new HeuristicScanner(program, this); var ranges = heuristicScanner.FindUnscannedRanges(); foreach (var item in heuristicScanner.FindPossibleFunctions(ranges)) { var hproc = heuristicScanner.DisassembleProcedure(item.Item1, item.Item2); var hps = new HeuristicProcedureScanner(program, hproc); hps.BlockConflictResolution(); // TODO: add all guessed code to image map -- clearly labelled. } }
/// Plan of attack: /// In each unscanned "hole", look for signatures of procedure entries. /// These are procedure entry candidates. /// Scan each of the procedure entry candidates heuristically. /// /// Next scan all executable code segments for: /// - calls that reach those candidates /// - jmps to those candidates /// - pointers to those candidates. /// Each time we find a call, we increase the score of the candidate. /// At the end we have a list of scored candidates. public void ScanImageHeuristically() { var ranges = FindUnscannedRanges(); foreach (var range in FindPossibleFunctions(ranges)) { var hproc = DisassembleProcedure(range.Item1, range.Item2); var hps = new HeuristicProcedureScanner(program, hproc, host); hps.BlockConflictResolution(); DumpBlocks(hproc.Cfg.Nodes); hps.GapResolution(); // TODO: add all guessed code to image map -- clearly labelled. } }
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 dasm = new ShingledScanner(program, host, storageBinder, sr, eventListener); bool unscanned = false; foreach (var range in ranges) { unscanned = true; try { dasm.ScanRange(range.Item1, range.Item2, range.Item3, range.Item3.ToLinear() - range.Item2.ToLinear()); } 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); dasm.Dump("After shingle scan graph built"); var deadNodes = dasm.RemoveBadInstructionsFromGraph(); dasm.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 HeuristicProcedureScanner( 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); }