public void TrfPropagateStackValuesToSuccessor() { m.Label("Start"); Identifier ecx = m.Register(1); trf = CreateTrashedRegisterFinder(prog); CreateBlockFlow(m.Block, m.Frame); trf.StartProcessingBlock(m.Block); trf.StackSymbolicValues[-4] = ecx; trf.StackSymbolicValues[-8] = ecx; trf.StackSymbolicValues[-12] = ecx; trf.StackSymbolicValues[-16] = m.Word32(0x1234); trf.StackSymbolicValues[-20] = m.Word32(0x5678); trf.StackSymbolicValues[-24] = m.Word32(0x9ABC); var succ = new Block(m.Procedure, "succ"); var sf = CreateBlockFlow(succ, m.Frame); flow[succ] = sf; sf.SymbolicIn.StackState[-8] = ecx; sf.SymbolicIn.StackState[-12] = Constant.Word32(1231); sf.SymbolicIn.StackState[-20] = Constant.Word32(0x5678); sf.SymbolicIn.StackState[-24] = Constant.Word32(0xCCCC); trf.PropagateToSuccessorBlock(succ); Assert.AreEqual("ecx", sf.SymbolicIn.StackState[-4].ToString(), "Didn't have a value before"); Assert.AreEqual("ecx", sf.SymbolicIn.StackState[-8].ToString(), "Same value as before"); Assert.AreEqual("<invalid>", sf.SymbolicIn.StackState[-12].ToString()); Assert.AreEqual("0x00001234", sf.SymbolicIn.StackState[-16].ToString()); Assert.AreEqual("0x00005678", sf.SymbolicIn.StackState[-20].ToString()); Assert.AreEqual("<invalid>", sf.SymbolicIn.StackState[-24].ToString()); }
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(); } }
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 TrfPropagateToProcedureSummary() { Procedure proc = new Procedure("proc", prog.Architecture.CreateFrame()); prog.CallGraph.AddProcedure(proc); Identifier eax = proc.Frame.EnsureRegister(Registers.eax); Identifier ebx = proc.Frame.EnsureRegister(Registers.ebx); Identifier ecx = proc.Frame.EnsureRegister(Registers.ecx); Identifier esi = proc.Frame.EnsureRegister(Registers.esi); flow[proc] = new ProcedureFlow(proc, prog.Architecture); trf = CreateTrashedRegisterFinder(); CreateBlockFlow(proc.ExitBlock, proc.Frame); trf.StartProcessingBlock(proc.ExitBlock); trf.RegisterSymbolicValues[(RegisterStorage)eax.Storage] = eax; // preserved trf.RegisterSymbolicValues[(RegisterStorage)ebx.Storage] = ecx; // trashed trf.RegisterSymbolicValues[(RegisterStorage)esi.Storage] = Constant.Invalid; // trashed trf.PropagateToProcedureSummary(proc); ProcedureFlow pf = flow[proc]; Assert.AreEqual(" ebx esi", pf.EmitRegisters(prog.Architecture, "", pf.TrashedRegisters)); Assert.AreEqual(" eax", pf.EmitRegisters(prog.Architecture, "", pf.PreservedRegisters)); }
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) { 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); }
public void TrashFlag() { var scz = m.Frame.EnsureFlagGroup(0x7, arch.GrfToString(0x7), PrimitiveType.Byte); var stm = m.Assign(scz, m.Int32(3)); trf = CreateTrashedRegisterFinder(); CreateBlockFlow(m.Block, m.Frame); trf.StartProcessingBlock(m.Block); stm.Accept(trf); Assert.AreEqual(0x7, trf.TrashedFlags); }
public void TrfOutParameters() { var r2 = m.Register(2); var stm = m.SideEffect(m.Fn("Hello", m.AddrOf(r2))); trf = CreateTrashedRegisterFinder(); trf.EnsureEvaluationContext(CreateBlockFlow(m.Block, m.Frame)); stm.Instruction.Accept(trf); Assert.AreEqual("<invalid>", trf.RegisterSymbolicValues[(RegisterStorage)r2.Storage].ToString()); }
public void TrashCompoundRegister() { Identifier ax = m.Frame.EnsureRegister(Registers.ax); var stm = m.Assign(ax, 1); trf = CreateTrashedRegisterFinder(); CreateBlockFlow(m.Block, m.Frame); trf.StartProcessingBlock(m.Block); stm.Accept(trf); Assert.AreEqual("(ax:0x0001)", DumpValues()); }
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); }
public void TrashRegister() { var r1 = m.Register(1); var stm = m.Assign(r1, m.Int32(0)); trf = CreateTrashedRegisterFinder(); CreateBlockFlow(m.Block, m.Frame); trf.StartProcessingBlock(m.Block); stm.Accept(trf); Debug.WriteLine(trf.RegisterSymbolicValues[(RegisterStorage)r1.Storage].ToString()); Assert.IsTrue(trf.IsTrashed(r1.Storage), "r1 should have been marked as trashed."); }
public void TrfCopy() { Identifier r1 = m.Register(1); Identifier r2 = m.Register(2); var ass = m.Assign(r2, r1); trf = CreateTrashedRegisterFinder(); CreateBlockFlow(m.Block, m.Frame); trf.StartProcessingBlock(m.Block); ass.Accept(trf); Assert.AreEqual(r1, trf.RegisterSymbolicValues[(RegisterStorage)r2.Storage], "r2 should now be equal to r1"); }
public void TrfTerminatingProcedure() { var eax = m.Procedure.Frame.EnsureRegister(Registers.eax); m.Assign(eax, m.Word32(0x40)); m.Call(exit, 4); flow[m.Block] = CreateBlockFlow(m.Block, m.Frame); flow[exit] = new ProcedureFlow(exit, prog.Architecture); flow[exit].TerminatesProcess = true; trf = CreateTrashedRegisterFinder(prog); trf.ProcessBlock(m.Block); Assert.AreEqual("", DumpValues()); }
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(); } }
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(); } }
public void TrfProcessBlock() { Identifier eax = m.Procedure.Frame.EnsureRegister(Registers.eax); Identifier esp = m.Procedure.Frame.EnsureRegister(Registers.esp); m.Store(m.ISub(esp, 4), eax); m.Assign(eax, m.Int32(3)); m.Assign(eax, m.LoadDw(m.ISub(esp, 4))); flow[m.Block] = CreateBlockFlow(m.Block, m.Frame); flow[m.Block].SymbolicIn.SetValue(esp, m.Frame.FramePointer); trf = CreateTrashedRegisterFinder(prog); trf.ProcessBlock(m.Block); Assert.AreEqual("(eax:eax), (esp:fp), (Stack -4:eax)", DumpValues()); }
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(); } }
public void TrfCallInstruction() { var callee = new Procedure("Callee", prog.Architecture.CreateFrame()); var stm = m.Call(callee, 4); var pf = new ProcedureFlow(callee, prog.Architecture); pf.TrashedRegisters[Registers.ebx.Number] = true; flow[callee] = pf; trf = CreateTrashedRegisterFinder(); CreateBlockFlow(m.Block, m.Frame); trf.StartProcessingBlock(m.Block); stm.Instruction.Accept(trf); Assert.AreEqual("(ebx:<invalid>)", DumpValues()); }
public void TrfPropagateFlagsToProcedureSummary() { var proc = new Procedure("proc", prog.Architecture.CreateFrame()); prog.CallGraph.AddProcedure(proc); var flags = prog.Architecture.GetFlagGroup("SZ"); var sz = m.Frame.EnsureFlagGroup(flags.FlagGroupBits, flags.Name, flags.DataType); var stm = m.Assign(sz, m.Int32(3)); flow[proc] = new ProcedureFlow(proc, prog.Architecture); trf = CreateTrashedRegisterFinder(prog); CreateBlockFlow(m.Block, m.Frame); trf.StartProcessingBlock(m.Block); stm.Accept(trf); trf.PropagateToProcedureSummary(proc); Assert.AreEqual(" SZ", flow[proc].EmitFlagGroup(prog.Architecture, "", flow[proc].grfTrashed)); }
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 TrfCopyBack() { var esp = m.Frame.EnsureRegister(Registers.esp); var r2 = m.Register(2); var stm1 = m.Store(m.ISub(esp, 0x10), r2); var stm2 = m.Assign(r2, m.Int32(0)); var stm3 = m.Assign(r2, m.Mem32(m.ISub(esp, 0x10))); trf = CreateTrashedRegisterFinder(); var flow = CreateBlockFlow(m.Block, m.Frame); flow.SymbolicIn.SetValue((Identifier)esp, (Expression)this.m.Frame.FramePointer); trf.StartProcessingBlock(m.Block); stm1.Instruction.Accept(trf); stm2.Accept(trf); stm3.Accept(trf); Assert.AreEqual(r2, trf.RegisterSymbolicValues[(RegisterStorage)r2.Storage]); }
public void TrfPropagateToSuccessorBlocks() { Procedure proc = new Procedure("test", prog.Architecture.CreateFrame()); var frame = proc.Frame; Identifier ecx = m.Register(1); Identifier edx = m.Register(2); Identifier ebx = m.Register(3); Block b = proc.AddBlock("b"); Block t = proc.AddBlock("t"); Block e = proc.AddBlock("e"); proc.ControlGraph.AddEdge(b, e); proc.ControlGraph.AddEdge(b, t); flow[t] = new BlockFlow(t, null, new SymbolicEvaluationContext(prog.Architecture, frame)); flow[e] = new BlockFlow(e, null, new SymbolicEvaluationContext(prog.Architecture, frame)); trf = CreateTrashedRegisterFinder(prog); CreateBlockFlow(b, frame); trf.StartProcessingBlock(b); trf.RegisterSymbolicValues[(RegisterStorage)ecx.Storage] = Constant.Invalid; trf.RegisterSymbolicValues[(RegisterStorage)edx.Storage] = ebx; flow[e].SymbolicIn.RegisterState[(RegisterStorage)ecx.Storage] = edx; flow[e].SymbolicIn.RegisterState[(RegisterStorage)edx.Storage] = ebx; flow[t].SymbolicIn.RegisterState[(RegisterStorage)ecx.Storage] = Constant.Invalid; flow[t].SymbolicIn.RegisterState[(RegisterStorage)edx.Storage] = edx; trf.PropagateToSuccessorBlock(e); trf.PropagateToSuccessorBlock(t); Assert.AreEqual(2, proc.ControlGraph.Successors(b).Count); Assert.AreEqual("<invalid>", flow[e].SymbolicIn.RegisterState[(RegisterStorage)ecx.Storage].ToString(), "trash & r2 => trash"); Assert.AreEqual("ebx", flow[e].SymbolicIn.RegisterState[(RegisterStorage)edx.Storage].ToString(), "ebx & ebx => ebx"); Assert.AreEqual("<invalid>", flow[e].SymbolicIn.RegisterState[(RegisterStorage)ecx.Storage].ToString(), "trash & r2 => trash"); Assert.AreEqual("ebx", flow[e].SymbolicIn.RegisterState[(RegisterStorage)edx.Storage].ToString(), "ebx & ebx => ebx"); Assert.AreEqual("<invalid>", flow[t].SymbolicIn.RegisterState[(RegisterStorage)ecx.Storage].ToString(), "trash & trash => trash"); Assert.AreEqual("<invalid>", flow[t].SymbolicIn.RegisterState[(RegisterStorage)edx.Storage].ToString(), "r3 & r2 => trash"); }
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 TrfPropagateToProcedureSummary() { Procedure proc = new Procedure("proc", program.Architecture.CreateFrame()); program.CallGraph.AddProcedure(proc); Identifier eax = proc.Frame.EnsureRegister(Registers.eax); Identifier ebx = proc.Frame.EnsureRegister(Registers.ebx); Identifier ecx = proc.Frame.EnsureRegister(Registers.ecx); Identifier esi = proc.Frame.EnsureRegister(Registers.esi); flow[proc] = new ProcedureFlow(proc, program.Architecture); trf = CreateTrashedRegisterFinder(); CreateBlockFlow(proc.ExitBlock, proc.Frame); trf.StartProcessingBlock(proc.ExitBlock); trf.RegisterSymbolicValues[(RegisterStorage) eax.Storage] = eax; // preserved trf.RegisterSymbolicValues[(RegisterStorage) ebx.Storage] = ecx; // trashed trf.RegisterSymbolicValues[(RegisterStorage) esi.Storage] = Constant.Invalid; // trashed trf.PropagateToProcedureSummary(proc); ProcedureFlow pf = flow[proc]; Assert.AreEqual(" ebx esi", pf.EmitRegisters(program.Architecture, "", pf.TrashedRegisters)); Assert.AreEqual(" eax", pf.EmitRegisters(program.Architecture, "", pf.PreservedRegisters)); }
public void TrfPropagateStackValuesToSuccessor() { m.Label("Start"); Identifier ecx = m.Register(1); trf = CreateTrashedRegisterFinder(program); CreateBlockFlow(m.Block, m.Frame); trf.StartProcessingBlock(m.Block); trf.StackSymbolicValues[-4] = ecx; trf.StackSymbolicValues[-8] = ecx; trf.StackSymbolicValues[-12] = ecx; trf.StackSymbolicValues[-16] = m.Word32(0x1234); trf.StackSymbolicValues[-20] = m.Word32(0x5678); trf.StackSymbolicValues[-24] = m.Word32(0x9ABC); var succ = new Block(m.Procedure, "succ"); var sf = CreateBlockFlow(succ, m.Frame); flow[succ] = sf; sf.SymbolicIn.StackState[-8] = ecx; sf.SymbolicIn.StackState[-12] = Constant.Word32(1231); sf.SymbolicIn.StackState[-20] = Constant.Word32(0x5678); sf.SymbolicIn.StackState[-24] = Constant.Word32(0xCCCC); trf.PropagateToSuccessorBlock(succ); Assert.AreEqual("ecx", sf.SymbolicIn.StackState[-4].ToString(), "Didn't have a value before"); Assert.AreEqual("ecx", sf.SymbolicIn.StackState[-8].ToString(), "Same value as before"); Assert.AreEqual("<invalid>", sf.SymbolicIn.StackState[-12].ToString()); Assert.AreEqual("0x00001234", sf.SymbolicIn.StackState[-16].ToString()); Assert.AreEqual("0x00005678", sf.SymbolicIn.StackState[-20].ToString()); Assert.AreEqual("<invalid>", sf.SymbolicIn.StackState[-24].ToString()); }
public void TrfPropagateToSuccessorBlocks() { Procedure proc = new Procedure("test", program.Architecture.CreateFrame()); var frame = proc.Frame; Identifier ecx = m.Register(1); Identifier edx = m.Register(2); Identifier ebx = m.Register(3); Block b = proc.AddBlock("b"); Block t = proc.AddBlock("t"); Block e = proc.AddBlock("e"); proc.ControlGraph.AddEdge(b, e); proc.ControlGraph.AddEdge(b, t); flow[t] = new BlockFlow(t, null, new SymbolicEvaluationContext(program.Architecture, frame)); flow[e] = new BlockFlow(e, null, new SymbolicEvaluationContext(program.Architecture, frame)); trf = CreateTrashedRegisterFinder(program); CreateBlockFlow(b, frame); trf.StartProcessingBlock(b); trf.RegisterSymbolicValues[(RegisterStorage) ecx.Storage] = Constant.Invalid; trf.RegisterSymbolicValues[(RegisterStorage) edx.Storage] = ebx; flow[e].SymbolicIn.RegisterState[(RegisterStorage) ecx.Storage] = edx; flow[e].SymbolicIn.RegisterState[(RegisterStorage) edx.Storage] = ebx; flow[t].SymbolicIn.RegisterState[(RegisterStorage) ecx.Storage] = Constant.Invalid; flow[t].SymbolicIn.RegisterState[(RegisterStorage) edx.Storage] = edx; trf.PropagateToSuccessorBlock(e); trf.PropagateToSuccessorBlock(t); Assert.AreEqual(2, proc.ControlGraph.Successors(b).Count); Assert.AreEqual("<invalid>", flow[e].SymbolicIn.RegisterState[(RegisterStorage) ecx.Storage].ToString(), "trash & r2 => trash"); Assert.AreEqual("ebx", flow[e].SymbolicIn.RegisterState[(RegisterStorage) edx.Storage].ToString(), "ebx & ebx => ebx"); Assert.AreEqual("<invalid>", flow[e].SymbolicIn.RegisterState[(RegisterStorage) ecx.Storage].ToString(), "trash & r2 => trash"); Assert.AreEqual("ebx", flow[e].SymbolicIn.RegisterState[(RegisterStorage) edx.Storage].ToString(), "ebx & ebx => ebx"); Assert.AreEqual("<invalid>", flow[t].SymbolicIn.RegisterState[(RegisterStorage) ecx.Storage].ToString(), "trash & trash => trash"); Assert.AreEqual("<invalid>", flow[t].SymbolicIn.RegisterState[(RegisterStorage) edx.Storage].ToString(), "r3 & r2 => trash"); }
public void TrfCallInstruction() { var callee = new Procedure("Callee", program.Architecture.CreateFrame()); var stm = m.Call(callee, 4); var pf = new ProcedureFlow(callee, program.Architecture); pf.TrashedRegisters.Add(Registers.ebx); flow[callee] = pf; trf = CreateTrashedRegisterFinder(); CreateBlockFlow(m.Block, m.Frame); trf.StartProcessingBlock(m.Block); stm.Instruction.Accept(trf); Assert.AreEqual("(ebx:<invalid>)", DumpValues()); }
public void TrfOutParameters() { var r2 = m.Register(2); var stm = m.SideEffect(m.Fn("Hello", m.AddrOf(r2))); trf = CreateTrashedRegisterFinder(); trf.EnsureEvaluationContext(CreateBlockFlow(m.Block, m.Frame)); stm.Instruction.Accept(trf); Assert.AreEqual("<invalid>", trf.RegisterSymbolicValues[(RegisterStorage) r2.Storage].ToString()); }
public void TrfProcessBlock() { Identifier eax = m.Procedure.Frame.EnsureRegister(Registers.eax); Identifier esp = m.Procedure.Frame.EnsureRegister(Registers.esp); m.Store(m.ISub(esp, 4), eax); m.Assign(eax, m.Int32(3)); m.Assign(eax, m.LoadDw(m.ISub(esp, 4))); flow[m.Block] = CreateBlockFlow(m.Block, m.Frame); flow[m.Block].SymbolicIn.SetValue(esp, m.Frame.FramePointer); trf = CreateTrashedRegisterFinder(program); trf.ProcessBlock(m.Block); Assert.AreEqual("(eax:eax), (esp:fp), (Stack -4:eax)", DumpValues()); }
public void TrashCompoundRegister() { Identifier ax = m.Frame.EnsureRegister(Registers.ax); var stm = m.Assign(ax, 1); trf = CreateTrashedRegisterFinder(); CreateBlockFlow(m.Block, m.Frame); trf.StartProcessingBlock(m.Block); stm.Accept(trf); Assert.AreEqual("(ax:0x0001)", DumpValues()); }
public void TrashFlag() { var flags = arch.GetFlagGroup(0x7).FlagRegister; var scz = m.Frame.EnsureFlagGroup(flags, 0x7, arch.GrfToString(0x7), PrimitiveType.Byte); var stm = m.Assign(scz, m.Int32(3)); trf = CreateTrashedRegisterFinder(); CreateBlockFlow(m.Block, m.Frame); trf.StartProcessingBlock(m.Block); stm.Accept(trf); Assert.AreEqual(0x7, trf.TrashedFlags); }
public void TrashRegister() { var r1 = m.Register(1); var stm = m.Assign(r1, m.Int32(0)); trf = CreateTrashedRegisterFinder(); CreateBlockFlow(m.Block, m.Frame); trf.StartProcessingBlock(m.Block); stm.Accept(trf); Debug.WriteLine(trf.RegisterSymbolicValues[(RegisterStorage) r1.Storage].ToString()); Assert.IsTrue(trf.IsTrashed(r1.Storage), "r1 should have been marked as trashed."); }
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; } }
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(); } }
public void TrfPropagateFlagsToProcedureSummary() { var proc = new Procedure("proc", program.Architecture.CreateFrame()); program.CallGraph.AddProcedure(proc); var flags = program.Architecture.GetFlagGroup("SZ"); var sz = m.Frame.EnsureFlagGroup(flags.FlagRegister, flags.FlagGroupBits, flags.Name, flags.DataType); var stm = m.Assign(sz, m.Int32(3)); flow[proc] = new ProcedureFlow(proc, program.Architecture); trf = CreateTrashedRegisterFinder(program); CreateBlockFlow(m.Block, m.Frame); trf.StartProcessingBlock(m.Block); stm.Accept(trf); trf.PropagateToProcedureSummary(proc); Assert.AreEqual(" SZ", flow[proc].EmitFlagGroup(program.Architecture, "", flow[proc].grfTrashed)); }
public void TrfCopy() { Identifier r1 = m.Register(1); Identifier r2 = m.Register(2); var ass = m.Assign(r2, r1); trf = CreateTrashedRegisterFinder(); CreateBlockFlow(m.Block, m.Frame); trf.StartProcessingBlock(m.Block); ass.Accept(trf); Assert.AreEqual(r1, trf.RegisterSymbolicValues[(RegisterStorage) r2.Storage], "r2 should now be equal to r1"); }
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"); }
public void TrfCopyBack() { var esp = m.Frame.EnsureRegister(Registers.esp); var r2 = m.Register(2); var stm1 = m.Store(m.ISub(esp, 0x10), r2); var stm2 = m.Assign(r2, m.Int32(0)); var stm3 = m.Assign(r2, m.LoadDw(m.ISub(esp, 0x10))); trf = CreateTrashedRegisterFinder(); var flow = CreateBlockFlow(m.Block, m.Frame); flow.SymbolicIn.SetValue(esp, m.Frame.FramePointer); trf.StartProcessingBlock(m.Block); stm1.Instruction.Accept(trf); stm2.Accept(trf); stm3.Accept(trf); Assert.AreEqual(r2, trf.RegisterSymbolicValues[(RegisterStorage) r2.Storage]); }
public void TrfTerminatingProcedure() { var eax = m.Procedure.Frame.EnsureRegister(Registers.eax); m.Assign(eax, m.Word32(0x40)); m.Call(exit, 4); flow[m.Block] = CreateBlockFlow(m.Block, m.Frame); flow[exit] = new ProcedureFlow(exit, program.Architecture); flow[exit].TerminatesProcess = true; trf = CreateTrashedRegisterFinder(program); trf.ProcessBlock(m.Block); Assert.AreEqual("", DumpValues()); }
/// <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); }