private void ProcessScc(IList <Procedure> scc) { var procSet = scc.ToHashSet(); var sstSet = new HashSet <SsaTransform>(); foreach (var proc in scc) { var sst = new SsaTransform( program, proc, procSet, dynamicLinker.Object, dataFlow); sst.Transform(); sst.AddUsesToExitBlock(); var vp = new ValuePropagator( program.SegmentMap, sst.SsaState, program.CallGraph, dynamicLinker.Object, NullDecompilerEventListener.Instance); vp.Transform(); sstSet.Add(sst); } var trf = new TrashedRegisterFinder( program, dataFlow, sstSet, NullDecompilerEventListener.Instance); trf.Compute(); }
public void TrfBackpropagateStackPointer() { var esp = m.Frame.EnsureRegister(Registers.esp); var ebp = m.Frame.EnsureRegister(Registers.ebp); var esi = m.Frame.EnsureRegister(Registers.esi); Given_TrashedRegisters(esp, esi, ebp); Given_Procedure(m => { m.Assign(esp, m.ISub(esp, 4)); m.MStore(esp, ebp); m.Assign(esp, m.ISub(esp, 4)); m.MStore(esp, esi); m.Call(esi, 4); m.Assign(esi, m.Mem32(esp)); m.Assign(esp, m.IAdd(esp, 4)); m.Assign(ebp, m.Mem32(esp)); m.Assign(esp, m.IAdd(esp, 4)); m.Return(); }); trf = CreateTrashedRegisterFinder(true); trf.Compute(); AssertPreservedRegisters("ebp esi esp"); }
protected override void RunTest(Program prog, TextWriter writer) { var flow = new ProgramDataFlow(prog); var eventListener = new FakeDecompilerEventListener(); var importResolver = MockRepository.GenerateStub <IImportResolver>(); importResolver.Replay(); var trf = new TrashedRegisterFinder(prog, prog.Procedures.Values, flow, eventListener); trf.Compute(); trf.RewriteBasicBlocks(); Dump(prog.CallGraph); RegisterLiveness.Compute(prog, flow, eventListener); GlobalCallRewriter.Rewrite(prog, flow, eventListener); foreach (Procedure proc in prog.Procedures.Values) { Aliases alias = new Aliases(proc, prog.Architecture); alias.Transform(); var gr = proc.CreateBlockDominatorGraph(); SsaTransform sst = new SsaTransform( flow, proc, importResolver, gr, new HashSet <RegisterStorage>()); ssa = sst.SsaState; ssa.Write(writer); proc.Write(false, true, writer); writer.WriteLine(); ssa.CheckUses(s => Assert.Fail(s)); } }
protected override void RunTest(Program prog, TextWriter writer) { var flow = new ProgramDataFlow(prog); var eventListener = new FakeDecompilerEventListener(); var trf = new TrashedRegisterFinder(prog, prog.Procedures.Values, flow, eventListener); trf.Compute(); trf.RewriteBasicBlocks(); Dump(prog.CallGraph); var rl = RegisterLiveness.Compute(prog, flow, eventListener); GlobalCallRewriter.Rewrite(prog, flow); foreach (Procedure proc in prog.Procedures.Values) { Aliases alias = new Aliases(proc, prog.Architecture); alias.Transform(); var gr = proc.CreateBlockDominatorGraph(); SsaTransform sst = new SsaTransform(flow, proc, gr); ssa = sst.SsaState; ssa.Write(writer); proc.Write(false, true, writer); writer.WriteLine(); } }
protected override void RunTest(Program prog, TextWriter writer) { this.prog = prog; flow = new ProgramDataFlow(prog); trf = CreateTrashedRegisterFinder(); trf.Compute(); DumpProcedureSummaries(writer); }
protected override void RunTest(Program prog, TextWriter writer) { var eventListener = new FakeDecompilerEventListener(); var dfa = new DataFlowAnalysis(prog, eventListener); var trf = new TrashedRegisterFinder(prog, prog.Procedures.Values, dfa.ProgramDataFlow, eventListener); trf.Compute(); trf.RewriteBasicBlocks(); var rl = RegisterLiveness.Compute(prog, dfa.ProgramDataFlow, eventListener); DumpProcedureFlows(prog, dfa, rl, writer); }
protected override void RunTest(Program prog, TextWriter writer) { var eventListener = new FakeDecompilerEventListener(); var dfa = new DataFlowAnalysis(prog, null, eventListener); var trf = new TrashedRegisterFinder(prog, prog.Procedures.Values, dfa.ProgramDataFlow, eventListener); trf.Compute(); trf.RewriteBasicBlocks(); var rl = RegisterLiveness.Compute(prog, dfa.ProgramDataFlow, eventListener); DumpProcedureFlows(prog, dfa, rl, writer); }
private void RunTest(Program prog, TextWriter writer) { flow = new ProgramDataFlow(prog); trf = new TrashedRegisterFinder(prog, prog.Procedures.Values, this.flow, new FakeDecompilerEventListener()); trf.Compute(); trf.RewriteBasicBlocks(); foreach (var proc in prog.Procedures.Values) { flow[proc].EmitRegisters(arch, "// Trashed", flow[proc].TrashedRegisters); proc.Write(false, writer); writer.WriteLine(); } }
protected override void RunTest(Program prog, TextWriter writer) { var dfa = new DataFlowAnalysis(prog, new FakeDecompilerEventListener()); var eventListener = new FakeDecompilerEventListener(); var trf = new TrashedRegisterFinder(prog, prog.Procedures.Values, dfa.ProgramDataFlow, eventListener); trf.Compute(); trf.RewriteBasicBlocks(); RegisterLiveness rl = RegisterLiveness.Compute(prog, dfa.ProgramDataFlow, eventListener); foreach (Procedure proc in prog.Procedures.Values) { LongAddRewriter larw = new LongAddRewriter(proc, prog.Architecture); larw.Transform(); proc.Write(false, writer); writer.WriteLine(); } }
private void RunTest(ProgramBuilder p, string sExp) { prog = p.BuildProgram(arch); flow = new ProgramDataFlow(prog); trf = CreateTrashedRegisterFinder(); trf.Compute(); var summary = DumpProcedureSummaries().Trim(); if (sExp == summary) { return; } Console.WriteLine(summary); Assert.AreEqual(sExp, summary); }
protected override void RunTest(Program prog, TextWriter writer) { var eventListener = new FakeDecompilerEventListener(); var dfa = new DataFlowAnalysis(prog, null, eventListener); var trf = new TrashedRegisterFinder(prog, prog.Procedures.Values, dfa.ProgramDataFlow, eventListener); trf.Compute(); trf.RewriteBasicBlocks(); RegisterLiveness rl = RegisterLiveness.Compute(prog, dfa.ProgramDataFlow, eventListener); foreach (Procedure proc in prog.Procedures.Values) { LongAddRewriter larw = new LongAddRewriter(proc, prog.Architecture); larw.Transform(); proc.Write(false, writer); writer.WriteLine(); } }
public void TrfPreserveEbp() { Identifier esp = m.Frame.EnsureRegister(Registers.esp); Identifier ebp = m.Frame.EnsureRegister(Registers.ebp); m.Store(esp, ebp); m.Assign(ebp, m.LoadDw(m.Int32(0x12345678))); m.Assign(ebp, m.LoadDw(esp)); m.Return(); Procedure proc = m.Procedure; prog.Procedures.Add(Address.Ptr32(0x10000), proc); prog.CallGraph.AddProcedure(proc); flow = new ProgramDataFlow(prog); trf = CreateTrashedRegisterFinder(prog); trf.Compute(); ProcedureFlow pf = flow[proc]; Assert.AreEqual(" esp ebp", pf.EmitRegisters(prog.Architecture, "", pf.PreservedRegisters), "ebp should have been preserved"); }
private void RunTest(ProgramBuilder p, string sExp) { program = p.BuildProgram(arch); flow = new ProgramDataFlow(program); trf = CreateTrashedRegisterFinder(); trf.Compute(); var summary = DumpProcedureSummaries().Trim(); if (sExp == summary) { return; } try { Assert.AreEqual(sExp, summary); } catch { Debug.Print("{0}", summary); throw; } }
public void TrfPreserveEbp() { Identifier esp = m.Frame.EnsureRegister(Registers.esp); Identifier ebp = m.Frame.EnsureRegister(Registers.ebp); m.Store(esp, ebp); m.Assign(ebp, m.LoadDw(m.Int32(0x12345678))); m.Assign(ebp, m.LoadDw(esp)); m.Return(); Procedure proc = m.Procedure; program.Procedures.Add(Address.Ptr32(0x10000), proc); program.CallGraph.AddProcedure(proc); flow = new ProgramDataFlow(program); trf = CreateTrashedRegisterFinder(program); trf.Compute(); ProcedureFlow pf = flow[proc]; Assert.AreEqual(" ebp esp", pf.EmitRegisters(program.Architecture, "", pf.PreservedRegisters), "ebp should have been preserved"); }
protected override void RunTest(Program prog, TextWriter writer) { this.program = prog; flow = new ProgramDataFlow(prog); trf = CreateTrashedRegisterFinder(); trf.Compute(); DumpProcedureSummaries(writer); }
private void RunTest(ProgramBuilder p, string sExp) { program = p.BuildProgram(arch); flow = new ProgramDataFlow(program); trf = CreateTrashedRegisterFinder(); trf.Compute(); var summary = DumpProcedureSummaries().Trim(); if (sExp == summary) return; try { Assert.AreEqual(sExp, summary); } catch { Console.WriteLine(summary); throw; } }
/// <summary> /// Finds all interprocedural register dependencies (in- and out-parameters) and /// abstracts them away by rewriting as calls. /// </summary> /// <returns>A RegisterLiveness object that summarizes the interprocedural register /// liveness analysis. This information can be used to generate SSA form. /// </returns> public void UntangleProcedures() { eventListener.ShowStatus("Eliminating intra-block dead registers."); var usb = new UserSignatureBuilder(program); usb.BuildSignatures(); CallRewriter.Rewrite(program); IntraBlockDeadRegisters.Apply(program); eventListener.ShowStatus("Finding terminating procedures."); var term = new TerminationAnalysis(flow); term.Analyze(program); eventListener.ShowStatus("Finding trashed registers."); var trf = new TrashedRegisterFinder(program, program.Procedures.Values, flow, eventListener); trf.Compute(); eventListener.ShowStatus("Rewriting affine expressions."); trf.RewriteBasicBlocks(); eventListener.ShowStatus("Computing register liveness."); var rl = RegisterLiveness.Compute(program, flow, eventListener); eventListener.ShowStatus("Rewriting calls."); GlobalCallRewriter.Rewrite(program, flow); }
protected override void RunTest(Program prog, TextWriter writer) { var flow = new ProgramDataFlow(prog); var eventListener = new FakeDecompilerEventListener(); var importResolver = MockRepository.GenerateStub<IImportResolver>(); importResolver.Replay(); var trf = new TrashedRegisterFinder(prog, prog.Procedures.Values, flow, eventListener); trf.Compute(); trf.RewriteBasicBlocks(); Dump(prog.CallGraph); RegisterLiveness.Compute(prog, flow, eventListener); GlobalCallRewriter.Rewrite(prog, flow, eventListener); foreach (Procedure proc in prog.Procedures.Values) { Aliases alias = new Aliases(proc, prog.Architecture); alias.Transform(); var gr = proc.CreateBlockDominatorGraph(); SsaTransform sst = new SsaTransform( flow, proc, importResolver, gr, new HashSet<RegisterStorage>()); ssa = sst.SsaState; ssa.Write(writer); proc.Write(false, true, writer); writer.WriteLine(); } }