public void EP_AddrOf() { var arch = new FakeArchitecture(); 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(arch, 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("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()); }
protected override void RunTest(Action<ProcedureBuilder> doBuild, string outputFile) { var pb = new ProgramBuilder(); pb.Add("proc1", doBuild); var program = pb.BuildProgram(); RunTest(program, outputFile); }
public void Dfa2_StackArgs() { var pb = new ProgramBuilder(new FakeArchitecture()); pb.Add("test", m => { var sp = m.Register(m.Architecture.StackRegister); var r1 = m.Reg32("r1"); var r2 = m.Reg32("r2"); m.Assign(sp, m.Frame.FramePointer); m.Assign(r1, m.LoadDw(m.IAdd(sp, 4))); m.Assign(r2, m.LoadDw(m.IAdd(sp, 8))); m.Assign(r1, m.IAdd(r1, r2)); m.Store(m.Word32(0x010008), r1); m.Return(); }); var dfa = new DataFlowAnalysis(pb.BuildProgram(), new FakeDecompilerEventListener()); dfa.UntangleProcedures2(); var sExp = @"// test // Return size: 0 void test() test_entry: // succ: l1 l1: Mem9[0x00010008:word32] = Mem0[fp + 0x00000004:word32] + Mem0[fp + 0x00000008:word32] return // succ: test_exit test_exit: "; AssertProgram(sExp, pb); }
/// <summary> /// Mutually recursive functions that jump into each other's bodies. /// </summary> /// <returns></returns> public static Program BuildProgram() { var prog = new ProgramBuilder(); var m = new ProcedureBuilder("even"); var r1 = m.Register(1); m.BranchIf(m.Eq0(r1), "done"); m.Assign(r1, m.ISub(r1, 1)); m.Call("odd", 4); m.Assign(r1, m.Not(r1)); m.Return(); m.Label("done"); m.Assign(r1, true); m.Return(); prog.Add(m); m = new ProcedureBuilder("odd"); r1 = m.Register(1); m.BranchIf(m.Eq(r1, 1), "done"); m.Assign(r1, m.ISub(r1, 1)); m.Call("event", 4); m.Assign(r1, m.Not(r1)); m.Return(); m.Label("done"); m.Assign(r1, true); m.Return(); prog.Add(m); return prog.BuildProgram(); }
/// <summary> /// This program has a cross procedural jump /// that should result in a new procedure, at Real_entry,since the jumped-to code /// is not a simple linear block but a branch. /// </summary> /// <returns></returns> public static Program CrossJump() { var b = new ProgramBuilder(); b.Add("bob", m => { var r1 = m.Reg32("r1", 1); var r2 = m.Reg32("r2", 2); m.Label("bob_1"); m.Assign(r1, 0); // Fall through should be promoted to call/return pair. m.Label("Real_entry"); // Cross jump target: should become a new function entry point. m.Store(r2, r1); m.BranchIf(r2, "Real_entry"); m.Return(); }); b.Add("ext", m => { var r1 = m.Reg32("r1", 1); m.Label("ext_1"); m.Assign(r1, 4); m.Goto("Real_entry"); }); return b.BuildProgram(); }
public void Dfa2_CallProc() { pb = new ProgramBuilder(); pb.Add("test", m => { var sp = m.Register(m.Architecture.StackRegister); var fooProc = GivenFunction("foo", m.Architecture.GetRegister(1), 4, 8); m.Assign(sp, m.ISub(sp, 4)); m.Store(sp, 2); m.Assign(sp, m.ISub(sp, 4)); m.Store(sp, 1); m.Call(fooProc, 4); m.Assign(sp, m.IAdd(sp, 8)); m.Return(); }); var dfa = new DataFlowAnalysis(pb.BuildProgram(), new FakeDecompilerEventListener()); dfa.UntangleProcedures2(); var sExp = @"// test // Return size: 0 void test() test_entry: // succ: l1 l1: Mem9[0x00010008:word32] = Mem0[fp + 0x00000004:word32] + Mem0[fp + 0x00000008:word32] return // succ: test_exit test_exit: "; AssertProgram(sExp, pb); }
public void Dfa2_Simple() { var pb = new ProgramBuilder(new FakeArchitecture()); pb.Add("test", m=> { var r1 = m.Reg32("r1", 1); var r2 = m.Reg32("r2", 2); m.Assign(r1, m.LoadDw(m.Word32(0x010000))); m.Assign(r2, m.LoadDw(m.Word32(0x010004))); m.Store(m.Word32(0x010008), m.IAdd(r1, r2)); m.Return(); }); var dfa = new DataFlowAnalysis(pb.BuildProgram(), new FakeDecompilerEventListener()); dfa.AnalyzeProgram2(); var sExp = @"// test // Return size: 0 void test() test_entry: // succ: l1 l1: Mem3[0x00010008:word32] = Mem0[0x00010000:word32] + Mem0[0x00010004:word32] return // succ: test_exit test_exit: "; AssertProgram(sExp, pb.Program); }
protected Program CompileTest(Action<ProcedureBuilder> m) { var mock = new ProcedureBuilder(); m(mock); var pmock = new ProgramBuilder(); pmock.Add(mock); return pmock.BuildProgram(); }
private void AssertProgram(string sExp, ProgramBuilder pb) { var sw = new StringWriter(); pb.Program.Procedures.Values.First().Write(false, sw); var sActual = sw.ToString(); if (sExp != sActual) Debug.WriteLine(sActual); Assert.AreEqual(sExp, sw.ToString()); }
public void PprMemberPointers() { ProgramBuilder mock = new ProgramBuilder(); ProcedureBuilder m = new ProcedureBuilder(); Identifier ds = m.Local(PrimitiveType.SegmentSelector, "ds"); m.SegStore(ds, m.Word32(7000), m.SegMemW(ds, m.SegMemW(ds, m.Word32(0x5321)))); mock.Add(m); RunTest(mock.BuildProgram(), "Typing/PprMemberPointers.txt"); }
public void PprMemberVars() { ProgramBuilder mock = new ProgramBuilder(); ProcedureBuilder p = new ProcedureBuilder(); Identifier cs = p.Frame.EnsureRegister(Registers.cs); p.Store(p.SegMemW(cs, p.Word32(0x0001)), Constant.Create(PrimitiveType.SegmentSelector, 0x0800)); mock.Add(p); RunTest(mock.BuildProgram(), "Typing/PprMemberVars.txt"); }
public void CpaSimple() { var program = new ProgramBuilder(); program.Add("test", m=> { var r1 = m.Register(1); m.Assign(r1, m.Load(PrimitiveType.Real32, m.Word32(0x10000000))); }); RunTest(program.BuildProgram(), "Typing/CpaSimple.txt"); }
public void Setup() { exit = new ExternalProcedure("exit", new ProcedureSignature(null, new Identifier("retCode", PrimitiveType.Int32, new StackArgumentStorage(0, PrimitiveType.Int32)))); exit.Characteristics = new ProcedureCharacteristics(); exit.Characteristics.Terminates = true; progMock = new ProgramBuilder(); flow = new ProgramDataFlow(); }
//$TODO: translate to RtlTraces /// <summary> /// Simple program consisting of a single procedure. /// </summary> /// <returns></returns> public Program Simple() { var b = new ProgramBuilder(); b.Add("bob", m => { m.Label("Zlon"); m.Return(); }); return b.BuildProgram(); }
public void Setup() { arch = new IntelArchitecture(ProcessorMode.Protected32); m = new ProcedureBuilder(arch); prog = new Program(); prog.Architecture = arch; exit = new Procedure("exit", new Frame(PrimitiveType.Word32)); flow = new ProgramDataFlow(); p = new ProgramBuilder(); }
public void Setup() { arch = new X86ArchitectureFlat32(); m = new ProcedureBuilder(arch); program = new Program(); program.Architecture = arch; exit = new Procedure("exit", new Frame(PrimitiveType.Word32)); flow = new ProgramDataFlow(); p = new ProgramBuilder(); }
public void DpaConstantPointer() { ProgramBuilder prog = new ProgramBuilder(); ProcedureBuilder m = new ProcedureBuilder(); Identifier r1 = m.Register(1); m.Assign(r1, 0x123130); m.Store(r1, m.Int32(0x42)); prog.Add(m); RunTest(prog.BuildProgram(), "Typing/DpaConstantPointer.txt"); }
public void DtbArrayConstantPointers() { ProgramBuilder pp = new ProgramBuilder(); pp.Add("Fn", m => { Identifier a = m.Local32("a"); Identifier i = m.Local32("i"); m.Assign(a, 0x00123456); // array pointer m.Store(m.IAdd(a, m.IMul(i, 8)), m.Int32(42)); }); RunTest(pp.BuildProgram(), "Typing/DtbArrayConstantPointers.txt"); }
private void CreateIntraProceduralJumps() { var regS = new RegisterStorage("reg", 1, 0, PrimitiveType.Word32); prog = new ProgramBuilder(); prog.Add("main", (m) => { var reg = m.Frame.EnsureRegister(regS); m.Assign(reg, 0); m.Store(m.Word32(0x1234), reg); m.Return(); }); }
public void DpaConstantMemberPointer() { ProgramBuilder prog = new ProgramBuilder(); ProcedureBuilder m = new ProcedureBuilder(); Identifier ds = m.Local16("ds"); ds.DataType = PrimitiveType.SegmentSelector; Identifier bx = m.Local16("bx"); m.Assign(bx, 0x1234); m.Store(m.SegMemW(ds, bx), m.Int16(0x0042)); prog.Add(m); RunTest(prog.BuildProgram(), "Typing/DpaConstantMemberPointer.txt"); }
public void EP_TestCondition() { var p = new ProgramBuilder(); p.Add("main", (m) => { m.Label("foo"); m.BranchCc(ConditionCode.EQ, "foo"); m.Return(); }); var proc = p.BuildProgram().Procedures.Values.First(); var ctx = new SymbolicEvaluationContext(new IntelArchitecture(ProcessorMode.Protected32), proc.Frame); var simplifier = new ExpressionSimplifier(ctx); var ep = new ExpressionPropagator(null, simplifier, ctx, new ProgramDataFlow()); var newInstr = proc.EntryBlock.Succ[0].Statements[0].Instruction.Accept(ep); Assert.AreEqual("branch Test(EQ,Z) foo", newInstr.ToString()); }
public void CceAddAdcPattern() { var p = new ProgramBuilder(new FakeArchitecture()); p.Add("main", (m) => { var r1 = MockReg(m, 1); var r2 = MockReg(m, 2); var r3 = MockReg(m, 3); var r4 = MockReg(m, 4); var SCZ = m.Frame.EnsureFlagGroup(0x7, "SZC", PrimitiveType.Byte); var C = m.Frame.EnsureFlagGroup(0x4, "C", PrimitiveType.Byte); m.Assign(r1, m.IAdd(r1, r2)); m.Assign(SCZ, m.Cond(r1)); m.Assign(r3, m.IAdd(m.IAdd(r3, r4), C)); m.Store(m.Word32(0x0444400), r1); m.Store(m.Word32(0x0444404), r3); m.Return(); }); RunTest(p, "Analysis/CceAddAdcPattern.txt"); }
public void EP_ConditionOf() { var p = new ProgramBuilder(); var proc = p.Add("main", (m) => { var szo = m.Frame.EnsureFlagGroup(0x7, "SZO", PrimitiveType.Byte); var ebx = m.Frame.EnsureRegister(new RegisterStorage("ebx", 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 ctx = new SymbolicEvaluationContext(new IntelArchitecture(ProcessorMode.Protected32), proc.Frame); var simplifier = new ExpressionSimplifier(ctx); var ep = new ExpressionPropagator(null, simplifier, ctx, new ProgramDataFlow()); var newInstr = proc.EntryBlock.Succ[0].Statements[2].Instruction.Accept(ep); Assert.AreEqual("SZO = cond(v4)", newInstr.ToString()); }
public void EP_Application() { var p = new ProgramBuilder(); var proc = p.Add("main", (m) => { var r1 = m.Frame.EnsureRegister(new RegisterStorage("r1", 1, PrimitiveType.Word32)); m.Assign(r1, m.Word32(0x42)); m.SideEffect(m.Fn("foo", r1)); m.Return(); }); var arch = new FakeArchitecture(); var ctx = new SymbolicEvaluationContext(arch, proc.Frame); var simplifier = new ExpressionSimplifier(ctx); var ep = new ExpressionPropagator(null, simplifier, ctx, new ProgramDataFlow()); var stms = proc.EntryBlock.Succ[0].Statements; stms[0].Instruction.Accept(ep); var newInstr = stms[1].Instruction.Accept(ep); Assert.AreEqual("foo(0x00000042)", newInstr.ToString()); }
public static Program BuildSample() { var pb = new ProgramBuilder(); pb.Add("fact", m => { var sp = m.Register(m.Architecture.StackRegister); var r1 = m.Register(1); var r2 = m.Register(2); var r3 = m.Register(3); var cc = m.Flags("cc"); m.Assign(sp, m.Frame.FramePointer); m.Assign(r2, r1); m.Assign(r1, 1); m.Assign(cc, m.Cond(m.ISub(r2, r1))); m.BranchIf(m.Test(ConditionCode.LE, cc), "m_done"); m.Assign(sp, m.ISub(sp, 4)); m.Store(sp, r2); m.Assign(r1, m.ISub(r2, r1)); m.Call("fact", 0); m.Assign(r2, m.LoadDw(sp)); m.Assign(sp, m.IAdd(sp, 4)); m.Assign(r1, m.IMul(r1, r2)); m.Label("m_done"); m.Return(); }); pb.Add("main", m => { var r1 = m.Register(1); m.Assign(r1, 10); m.Call("fact", 0); m.Store(m.Word32(0x400000), r1); }); return pb.BuildProgram(); }
public void Dfa2_StackArgs() { var pb = new ProgramBuilder(new FakeArchitecture()); pb.Add("test", m => { var sp = m.Register(m.Architecture.StackRegister); var r1 = m.Reg32("r1", 1); var r2 = m.Reg32("r2", 2); m.Assign(sp, m.Frame.FramePointer); m.Assign(r1, m.LoadDw(m.IAdd(sp, 4))); m.Assign(r2, m.LoadDw(m.IAdd(sp, 8))); m.Assign(r1, m.IAdd(r1, r2)); m.Store(m.Word32(0x010008), r1); m.Return(); }); var dfa = new DataFlowAnalysis(pb.BuildProgram(), new FakeDecompilerEventListener()); dfa.AnalyzeProgram2(); var sExp = @"// test // Return size: 0 void test() test_entry: // succ: l1 l1: Mem6[0x00010008:word32] = dwArg04 + dwArg08 word32 r63_1 = fp word32 r2_4 = dwArg08 return // succ: test_exit test_exit: "; AssertProgram(sExp, pb.Program); }
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; } }
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); }
private void GivenProgram(ProgramBuilder pb) { }
public void Setup() { this.pf = new ProgramDataFlow(); this.progBuilder = new ProgramBuilder(); }