/// <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); }
/// <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(); }
protected Program CompileTest(Action<ProcedureBuilder> m) { var mock = new ProcedureBuilder(); m(mock); var pmock = new ProgramBuilder(); pmock.Add(mock); return pmock.BuildProgram(); }
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 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"); }
//$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 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 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 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 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 TerCallTable() { var pb = new ProgramBuilder(); pb.Add(new IndirectCallFragment()); RunTest(pb.BuildProgram(), "Typing/TerCallTable.txt"); }
public void TerIntelIndexedAddressingMode() { ProgramBuilder m = new ProgramBuilder(); m.Add(new IntelIndexedAddressingMode()); RunTest(m.BuildProgram(), "Typing/TerIntelIndexedAddressingMode.txt"); }
public void TerUnionConstants() { ProgramBuilder prog = new ProgramBuilder(); prog.Add("proc1", m => { Identifier bx = m.Local16("bx"); m.Assign(bx, m.Shr(bx, 2)); // makes bx unsigned uint16 m.Assign(m.LocalBool("f"), m.Lt(bx, 4)); // makes bx also signed; assembler bug, but forces a union. m.Assign(bx, m.Word16(4)); // what type should 4 have? }); RunTest(prog.BuildProgram(), "Typing/TerUnionConstants.txt"); }
public void TerComparison() { ProgramBuilder prog = new ProgramBuilder(); prog.Add("proc1", m => { Identifier p = m.Local32("p"); Expression fetch = m.Load(new Pointer(new StructureType("foo", 8), 4), m.IAdd(p, 4)); m.Assign(m.LocalBool("f"), m.Lt(fetch, m.Word32(0x00001028))); }); RunTest(prog.BuildProgram(), "Typing/TerComparison.txt"); }
public void TerSignedCompare() { ProgramBuilder prog = new ProgramBuilder(); prog.Add("proc1", m => { Identifier ds = m.Local16("ds"); ds.DataType = PrimitiveType.SegmentSelector; Identifier ds2 = m.Local16("ds2"); ds2.DataType = PrimitiveType.SegmentSelector; m.Assign(ds2, ds); m.Store( m.SegMem(PrimitiveType.Bool, ds, m.Word16(0x5400)), m.Lt(m.SegMemW(ds, m.Word16(0x5404)), m.Word16(20))); m.Store(m.SegMemW(ds2, m.Word16(0x5404)), m.Word16(0)); }); RunTest(prog.BuildProgram(), "Typing/TerSignedCompare.txt"); }
public void TerAddNonConstantToPointer() { ProgramBuilder prog = new ProgramBuilder(); prog.Add("proc1", m => { Identifier i = m.Local16("i"); Identifier p = m.Local16("p"); m.Store(p, m.Word16(4)); m.Store(m.IAdd(p, 4), m.Word16(4)); m.Assign(p, m.IAdd(p, i)); }); RunTest(prog.BuildProgram(), "Typing/TerAddNonConstantToPointer.txt"); }
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 TerStaggeredArrays() { ProgramBuilder prog = new ProgramBuilder(); prog.Add(new StaggeredArraysFragment()); RunTest(prog.BuildProgram(), "Typing/TerStaggeredArrays.txt"); }
//[Ignore("scanning-development")] public void TerSegmentedCall() { var pb = new ProgramBuilder(); pb.Add(new SegmentedCallFragment()); RunTest(pb.BuildProgram(), "Typing/TerSegmentedCall.txt"); }
public void TerPointerChain() { var pb = new ProgramBuilder(); pb.Add(new PointerChainFragment()); RunTest(pb.BuildProgram(), "Typing/TerPointerChain.txt"); }
public void TerTypedAddressOf() { var pb = new ProgramBuilder(); pb.Add("TypedAddressOf", m => { var str = new TypeReference("foo", new StructureType("foo", 0) { Fields = { { 0, PrimitiveType.Int16, "word00" }, { 4, PrimitiveType.Byte, "byte004"} } }); var foo = new Identifier("foo", str, new MemoryStorage()); var r1 = m.Reg32("r1", 1); m.Declare(r1, m.AddrOf(foo)); m.Store(r1, m.Word16(0x1234)); m.Store(m.IAdd(r1, 4), m.Byte(0x0A)); m.Return(); }); RunTest(pb.BuildProgram()); }
public void TerArrayExpression() { var m = new ProgramBuilder(); m.Add(new ArrayExpressionFragment()); RunTest(m.BuildProgram(), "Typing/TerArrayExpression.txt"); }
public void TerVector() { ProgramBuilder mock = new ProgramBuilder(); mock.Add(new VectorFragment()); RunTest(mock.BuildProgram(), "Typing/TerVector.txt"); }
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 TerSegMemPtr2() { ProgramBuilder mock = new ProgramBuilder(); mock.Add(new SegmentedMemoryPointerMock2()); RunTest(mock.BuildProgram(), "Typing/TerSegMemPtr2.txt"); }
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); }
public void TerSegMem3() { ProgramBuilder mock = new ProgramBuilder(); mock.Add(new SegMem3Mock()); RunTest(mock.BuildProgram(), "Typing/TerSegMem3.txt"); }