public ScanResults ScanInstructions(ScanResults sr) { var ranges = FindUnscannedRanges().ToList(); DumpRanges(ranges); var binder = new StorageBinder(); var shsc = new ShingledScanner(this.program, this.host, binder, sr, this.eventListener); bool unscanned = false; foreach (var range in ranges) { unscanned = true; try { shsc.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); } shsc.Dump("After shingle scan graph built"); return(sr); }
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); }
private void ScanProgram(Program program) { try { eventListener.ShowStatus("Rewriting reachable machine code."); scanner = CreateScanner(program); foreach (EntryPoint ep in program.EntryPoints) { scanner.EnqueueEntryPoint(ep); } foreach (Procedure_v1 up in program.User.Procedures.Values) { scanner.EnqueueUserProcedure(up); } foreach (var addr in program.FunctionHints) { scanner.EnqueueProcedure(addr); } if (false || //$DEBUG program.User.Heuristics.Contains("shingle")) { eventListener.ShowStatus("Shingle scanning"); var sh = new ShingledScanner(program, (IRewriterHost) scanner); var procs = sh.Scan(); foreach (var addr in procs) { scanner.EnqueueProcedure(addr); } } scanner.ScanImage(); if (false || //$DEBUG program.User.Heuristics.Contains("HeuristicScanning")) { eventListener.ShowStatus("Finding machine code using heuristics."); scanner.ScanImageHeuristically(); } eventListener.ShowStatus("Finished rewriting reachable machine code."); } finally { host.WriteDisassembly(program, w => DumpAssembler(program, w)); host.WriteIntermediateCode(program, w => EmitProgram(program, null, w)); } }
private void ScanProgram(Program program) { try { eventListener.ShowStatus("Rewriting reachable machine code."); scanner = CreateScanner(program); var tlDeser = program.CreateTypeLibraryDeserializer(); foreach (var global in program.User.Globals) { var addr = global.Key; var dt = global.Value.DataType.Accept(tlDeser); scanner.EnqueueUserGlobalData(addr, dt); } foreach (ImageSymbol ep in program.EntryPoints.Values) { scanner.EnqueueImageSymbol(ep, true); } foreach (Procedure_v1 up in program.User.Procedures.Values) { scanner.EnqueueUserProcedure(up); } foreach (ImageSymbol sym in program.ImageSymbols.Values.Where(s => s.Type == SymbolType.Procedure)) { if (sym.NoDecompile) program.EnsureUserProcedure(sym.Address, sym.Name, false); else scanner.EnqueueImageSymbol(sym, false); } scanner.ScanImage(); if (program.User.Heuristics.Contains("HeuristicScanning")) { //eventListener.ShowStatus("Finding machine code using heuristics."); //scanner.ScanImageHeuristically(); } if (program.User.Heuristics.Contains("Shingle heuristic")) { eventListener.ShowStatus("Shingle scanning"); var sh = new ShingledScanner(program, (IRewriterHost)scanner, eventListener); var watch = new Stopwatch(); watch.Start(); var procs = sh.Scan(); var pprocs = procs.ToList(); watch.Stop(); Debug.Print( "Elapsed time: {0} msec for {1} procs", watch.ElapsedMilliseconds, pprocs.Count); foreach (var addr in procs) { scanner.ScanProcedure(addr.Key, null, program.Architecture.CreateProcessorState()); } } eventListener.ShowStatus("Finished rewriting reachable machine code."); } finally { eventListener.ShowStatus("Writing .asm and .dis files."); host.WriteDisassembly(program, w => DumpAssembler(program, w)); host.WriteIntermediateCode(program, w => EmitProgram(program, null, w)); } }