private void RunTest(string sExp, Action<ProcedureBuilder> builder) { var pb = new ProcedureBuilder(this.pb.Program.Architecture); builder(pb); var proc = pb.Procedure; var dg = new DominatorGraph<Block>(proc.ControlGraph, proc.EntryBlock); var project = new Project { Programs = { this.pb.Program } }; var importResolver = new ImportResolver( project, this.pb.Program, new FakeDecompilerEventListener()); var arch = new FakeArchitecture(); var platform = new FakePlatform(null, arch); // Register r1 is assumed to always be implicit when calling // another procedure. var implicitRegs = new HashSet<RegisterStorage> { arch.GetRegister(1) }; Debug.Print("GetRegister(1) {0}", arch.GetRegister(1)); this.pb.Program.Platform = platform; this.pb.Program.Platform = new FakePlatform(null, new FakeArchitecture()); this.pb.Program.SegmentMap = new SegmentMap( Address.Ptr32(0x0000), new ImageSegment( ".text", Address.Ptr32(0), 0x40000, AccessMode.ReadWriteExecute)); // Perform the initial transformation var ssa = new SsaTransform(programFlow, proc, importResolver, dg, implicitRegs); // Propagate values and simplify the results. // We hope the the sequence // esp = fp - 4 // mov [esp-4],eax // will become // esp_2 = fp - 4 // mov [fp - 8],eax var vp = new ValuePropagator(this.pb.Program.Architecture, ssa.SsaState); vp.Transform(); ssa.RenameFrameAccesses = true; ssa.AddUseInstructions = true; ssa.Transform(); var writer = new StringWriter(); proc.Write(false, writer); var sActual = writer.ToString(); if (sActual != sExp) Debug.Print(sActual); Assert.AreEqual(sExp, sActual); }
public static RtlTrace[] Create(FakeArchitecture arch) { var frame = arch.CreateFrame(); var r1 = frame.EnsureRegister(arch.GetRegister(1)); var sp = frame.EnsureRegister(arch.StackRegister); return new RtlTrace[] { new RtlTrace(0x1000) // main { m => {m.Assign(r1, 3); }, m => { m.Assign(sp, m.ISub(sp, 4)); m.Assign(m.LoadDw(sp), r1); }, m => { m.Call(Address.Ptr32(0x1200), 4); }, m => { m.Assign(r1, 3); }, m => { m.Assign(sp, m.ISub(sp, 4)); m.Assign(m.LoadDw(sp), r1); }, m => { m.Call(Address.Ptr32(0x1100), 4); }, m => { m.Return(4, 4); } }, new RtlTrace(0x1100) // odd { m => { m.Assign(r1, m.LoadDw(m.IAdd(sp, 4))); }, m => { m.Branch(m.Eq0(r1), Address.Ptr32(0x1120), RtlClass.ConditionalTransfer); }, m => { m.Assign(r1, m.LoadDw(m.IAdd(sp, 4))); }, m => { m.Assign(r1, m.ISub(r1, 1)); }, m => { m.Assign(m.LoadDw(m.IAdd(sp, 4)), r1); }, m => { m.Goto(Address.Ptr32(0x1200)); } }, new RtlTrace(0x1120) { m => { m.Assign(r1, Constant.Word32(0)); }, m => { m.Return(4, 4); } }, new RtlTrace(0x1200) // event { m => { m.Assign(r1, m.LoadDw(m.IAdd(sp, 4))); }, m => { m.Branch(m.Eq0(r1), Address.Ptr32(0x1220), RtlClass.ConditionalTransfer); }, m => { m.Assign(r1, m.LoadDw(m.IAdd(sp, 4))); }, m => { m.Assign(r1, m.ISub(r1, 1)); }, m => { m.Assign(m.LoadDw(m.IAdd(sp, 4)), r1); }, m => { m.Goto(Address.Ptr32(0x1100)); } }, new RtlTrace(0x1220) { m => { m.Assign(r1, Constant.Word32(1)); }, m => { m.Return(4, 4); } }, }; }