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); }
private void Given_Program() { this.arch = new FakeArchitecture(); var platform = new FakePlatform(null, arch); this.program = new Program { SegmentMap = new SegmentMap( Address.Ptr32(0x1000), new ImageSegment( ".text", new MemoryArea(Address.Ptr32(0x1000), new byte[1000]), AccessMode.ReadExecute)), Platform = platform, Architecture = arch, }; }
public void EP_ConditionOf() { var p = new ProgramBuilder(); var proc = p.Add("main", (m) => { var szo = m.Frame.EnsureFlagGroup(Registers.eflags, 0x7, "SZO", PrimitiveType.Byte); var ebx = m.Frame.EnsureRegister(new RegisterStorage("ebx", 3, 0, PrimitiveType.Word32)); var v4 = m.Frame.CreateTemporary(PrimitiveType.Word16); m.Assign(v4, m.IAdd(m.LoadW(ebx), 1)); m.Store(ebx, v4); m.Assign(szo, m.Cond(v4)); m.Return(); }); var arch = new X86ArchitectureFlat32(); var platform = new FakePlatform(null, arch); var ctx = new SymbolicEvaluationContext(arch, proc.Frame); var simplifier = new ExpressionSimplifier(ctx); var ep = new ExpressionPropagator(platform, simplifier, ctx, new ProgramDataFlow()); var newInstr = proc.EntryBlock.Succ[0].Statements[2].Instruction.Accept(ep); Assert.AreEqual("SZO = cond(v4)", newInstr.ToString()); }
public void Dfa2_UserDefinedStackArgs() { var arch = new X86ArchitectureFlat32(); var pb = new ProgramBuilder(arch); var test = pb.Add( new Procedure_v1 { CSignature = "void test(int a, int b)" }, m => { var sp = m.Register(m.Architecture.StackRegister); var r1 = m.Reg32("r1", 1); var r2 = m.Reg32("r2", 2); var fp = m.Frame.FramePointer; m.Assign(r1, m.LoadDw(m.IAdd(fp, 4))); m.Assign(r2, m.LoadDw(m.IAdd(fp, 8))); m.Assign(r1, m.IAdd(r1, r2)); m.Store(m.Word32(0x010008), r1); m.Return(); }); var program = pb.BuildProgram(); var platform = new FakePlatform(null, arch); platform.Test_CreateProcedureSerializer = (t, d) => { var typeLoader = new TypeLibraryDeserializer(platform, false, new TypeLibrary()); return new X86ProcedureSerializer((IntelArchitecture)program.Architecture, typeLoader, ""); }; program.Platform = platform; var dfa = new DataFlowAnalysis(program, new FakeDecompilerEventListener()); dfa.AnalyzeProgram2(); var sExp = @"// test // Return size: 4 void test(int32 a, int32 b) test_entry: // succ: l1 l1: word32 r1_4 = a + b Mem5[0x00010008:word32] = r1_4 return // succ: test_exit test_exit: "; AssertProgram(sExp, pb.Program); }
public void EP_LValue() { var arch = new FakeArchitecture(); var platform = new FakePlatform(null, arch); var p = new ProgramBuilder(arch); Identifier r2 = null; Identifier sp = null; var proc = p.Add("main", (m) => { r2 = m.Register("r2"); sp = m.Frame.EnsureRegister(arch.StackRegister); m.Store(m.ISub(sp, 12), m.ISub(sp, 16)); m.Store(m.ISub(sp, 12), 2); }); var ctx = new SymbolicEvaluationContext (arch, proc.Frame); var simplifier = new ExpressionSimplifier(ctx); var ep = new ExpressionPropagator(platform, simplifier,ctx, new ProgramDataFlow()); ctx.RegisterState[arch.StackRegister]= proc.Frame.FramePointer; var stms = proc.EntryBlock.Succ[0].Statements; var instr1 = stms[0].Instruction.Accept(ep); Assert.AreEqual("dwLoc0C = fp - 0x00000010", instr1.ToString()); var instr2 = stms[1].Instruction.Accept(ep); Assert.AreEqual("dwLoc0C = 0x00000002", instr2.ToString()); }
public void EP_AddrOf() { var arch = new FakeArchitecture(); var platform = new FakePlatform(null, arch); var p = new ProgramBuilder(arch); Identifier r2 = null, r3 = null; var proc = p.Add("main", (m) => { r2 = m.Register("r2"); r3 = m.Register("r3"); m.Assign(r2, 0x1234); // after which R2 has a definite value m.SideEffect(m.Fn("Foo", m.Out(PrimitiveType.Pointer32, r2))); // Can't promise R2 is preserved after call, so should be invalid. m.Assign(r3, r2); }); var ctx = new SymbolicEvaluationContext(arch, proc.Frame); var simplifier = new ExpressionSimplifier(ctx); var ep = new ExpressionPropagator(platform, simplifier, ctx, new ProgramDataFlow()); ctx.RegisterState[arch.StackRegister] = proc.Frame.FramePointer; var stms = proc.EntryBlock.Succ[0].Statements; stms[0].Instruction.Accept(ep); Assert.AreEqual("0x00001234", ctx.GetValue(r2).ToString()); var instr2 = stms[1].Instruction.Accept(ep); Assert.AreEqual("Foo(out r2)", instr2.ToString()); Assert.AreEqual("<invalid>", ctx.GetValue(r2).ToString()); var instr3 = stms[2].Instruction.Accept(ep); Assert.AreEqual("r3 = r2", instr3.ToString()); Assert.AreEqual("<invalid>", ctx.GetValue(r2).ToString()); Assert.AreEqual("<invalid>", ctx.GetValue(r3).ToString()); }
public void EP_StackReference() { var arch = new FakeArchitecture(); var platform = new FakePlatform(null, arch); var p = new ProgramBuilder(arch); var proc = p.Add("main", (m) => { var sp = m.Frame.EnsureRegister(m.Architecture.StackRegister); var r1 = m.Register(1); m.Assign(sp, m.ISub(sp, 4)); m.Assign(r1, m.LoadDw(m.IAdd(sp, 8))); m.Return(); }); var ctx = new SymbolicEvaluationContext(arch, proc.Frame); var simplifier = new ExpressionSimplifier(ctx); var ep = new ExpressionPropagator(platform, simplifier, ctx, new ProgramDataFlow()); ctx.RegisterState[arch.StackRegister] = proc.Frame.FramePointer; var stms = proc.EntryBlock.Succ[0].Statements; var newInstr = stms[0].Instruction.Accept(ep); Assert.AreEqual("r63 = fp - 0x00000004", newInstr.ToString()); newInstr = stms[1].Instruction.Accept(ep); Assert.AreEqual("r1 = dwArg04", newInstr.ToString()); }
public void EP_IndirectCall() { var arch = new FakeArchitecture(); var p = new ProgramBuilder(arch); var proc = p.Add("main", (m) => { var r1 = m.Register("r1"); m.Assign(r1, m.Word32(0x42)); m.Emit(new CallInstruction(r1, new CallSite(4, 0))); m.Return(); }); var platform = new FakePlatform(null, arch) { Test_CreateTrashedRegisters = () => new HashSet<RegisterStorage>() }; var ctx = new SymbolicEvaluationContext(arch, proc.Frame); var simplifier = new ExpressionSimplifier(ctx); var ep = new ExpressionPropagator(platform, simplifier, ctx, new ProgramDataFlow()); ctx.RegisterState[arch.StackRegister] = proc.Frame.FramePointer; var stms = proc.EntryBlock.Succ[0].Statements; stms[0].Instruction.Accept(ep); var newInstr = stms[1].Instruction.Accept(ep); Assert.AreEqual("call 0x00000042 (retsize: 4; depth: 4)", newInstr.ToString()); }
private void Given_Program(Address address, byte[] bytes) { var mem = new MemoryArea(address, bytes); var segmentMap = new SegmentMap( mem.BaseAddress, new ImageSegment("proggie", mem, AccessMode.ReadExecute)); var arch = new X86ArchitectureFlat32(); var platform = new FakePlatform(null, arch); this.program = new Program { Architecture = arch, SegmentMap = segmentMap, Platform = platform }; platform.Test_CreateProcedureSerializer = (t, d) => { var typeLoader = new TypeLibraryDeserializer(platform, false, new TypeLibrary()); return new X86ProcedureSerializer((IntelArchitecture)program.Architecture, typeLoader, ""); }; }