예제 #1
0
        /// <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());
        }
예제 #2
0
        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());
        }
        /// <summary>
        /// Models a call to an indirect function pointed to by
        /// ecx, with no arguments.
        /// </summary>
        private void indirect_call_no_arguments(ProcedureBuilder m)
        {
            var esp = m.Frame.EnsureIdentifier(m.Architecture.StackRegister);
            var eax = m.Frame.EnsureIdentifier(this.eax.Storage);
            var ecx = m.Frame.EnsureIdentifier(this.ecx.Storage);

            m.Assign(esp, m.Frame.FramePointer);
            m.Assign(eax, m.Mem32(m.IAdd(esp, 4)));
            m.Assign(ecx, m.Mem32(eax));
            m.Call(m.Mem32(ecx), 4);
            m.Return();
        }
예제 #4
0
        public void SsaCallIndirect()
        {
            var m  = new ProcedureBuilder("SsaCallIndirect");
            var r1 = m.Reg32("r1", 1);
            var r2 = m.Reg32("r2", 2);

            m.Assign(r1, m.Mem32(r2));
            m.Call(r1, 4);
            m.Return();

            RunUnitTest(m, "Analysis/SsaCallIndirect.txt");
        }
예제 #5
0
        public void CoaCallCallee()
        {
            var m  = new ProcedureBuilder("foo");
            var r2 = m.Register(2);
            var r3 = m.Register(3);

            m.Assign(r3, m.Fn(r2));
            m.Assign(r3, m.IAdd(r3, 4));
            m.Call(r3, 4);
            m.Return();
            RunFileTest(m, "Analysis/CoaCallCallee.txt");
        }
예제 #6
0
        public void SsaSwitchWithSharedBranches()
        {
            var m = new ProcedureBuilder("SsaSwitchWithSharedBranches");

            var sp  = m.Frame.EnsureRegister(m.Architecture.StackRegister);
            var r1  = m.Reg32("r1", 1);
            var r2  = m.Reg32("r2", 2);
            var foo = new ExternalProcedure("foo", new FunctionType(
                                                new Identifier("", VoidType.Instance, null),
                                                new Identifier("arg1", PrimitiveType.Int32, new StackArgumentStorage(4, PrimitiveType.Int32))));

            m.Assign(sp, m.Frame.FramePointer);
            m.Assign(r1, m.Mem32(m.IAdd(sp, 4)));
            m.BranchIf(m.Ugt(r1, m.Word32(0x5)), "m4_default");
            m.Label("m1");
            m.Switch(r1,
                     "m2", "m2", "m3", "m3", "m2", "m3");
            m.Label("m2");
            m.Assign(sp, m.ISub(sp, 4));
            m.MStore(sp, m.Word32(0x42));
            m.Call(foo, 4);
            m.Assign(sp, m.IAdd(sp, 4));
            // fall through
            m.Label("m3");
            m.Assign(sp, m.ISub(sp, 4));
            m.MStore(sp, m.Word32(42));
            m.Call(foo, 4);
            m.Assign(sp, m.IAdd(sp, 4));
            // fall through
            m.Label("m4_default");
            m.Assign(sp, m.ISub(sp, 4));
            m.MStore(sp, m.Word32(0));
            m.Call(foo, 4);
            m.Assign(sp, m.IAdd(sp, 4));

            m.Return();

            RunUnitTest(m, "Analysis/SsaSwitchWithSharedBranches.txt");
        }
예제 #7
0
        public void BlockTerminates()
        {
            var m = new ProcedureBuilder();

            m.Call(exit, 4);
            var b = m.CurrentBlock;

            m.Return();

            var a = new TerminationAnalysis(flow, eventListener);

            flow[b] = CreateBlockFlow(b, m.Frame);
            a.Analyze(b);
            Assert.IsTrue(flow[b].TerminatesProcess);
        }
        /// <summary>
        /// Models a call to an indirect function pointed to by
        /// ecx, with one stack argument.
        /// </summary>
        private void indirect_call_one_argument(ProcedureBuilder m)
        {
            var esp = m.Frame.EnsureIdentifier(m.Architecture.StackRegister);
            var eax = m.Frame.EnsureIdentifier(this.eax.Storage);
            var ecx = m.Frame.EnsureIdentifier(this.ecx.Storage);

            m.Assign(esp, m.Frame.FramePointer);
            m.Assign(eax, m.Mem32(m.IAdd(esp, 4)));
            m.Assign(ecx, m.Mem32(eax));
            m.Assign(esp, m.ISub(esp, 4));
            m.MStore(esp, m.Word32(0x000A));
            var c = m.Call(m.Mem32(m.IAdd(ecx, 4)), 4);

            c.CallSite.StackDepthOnEntry = 8;
            m.Return();
        }
        private void indirect_call_two_arguments(ProcedureBuilder m)
        {
            var esp = m.Frame.EnsureIdentifier(m.Architecture.StackRegister);
            var eax = m.Frame.EnsureIdentifier(this.eax.Storage);
            var ecx = m.Frame.EnsureIdentifier(this.ecx.Storage);

            m.Assign(esp, m.Frame.FramePointer);
            m.Assign(eax, m.Mem32(m.IAdd(esp, 4))); // get argument to this fn.
            m.Assign(ecx, m.Mem32(eax));
            m.Assign(esp, m.ISub(esp, 4));          // push arg2
            m.MStore(esp, m.Word32(0x000B));
            m.Assign(esp, m.ISub(esp, 4));          // push arg1
            m.MStore(esp, m.Word32(0x000A));
            // We expect the following call to be resolved as
            // (Mem0[ecx + 8:ptr32])(arg1, arg2)
            var c = m.Call(m.Mem32(m.IAdd(ecx, 8)), 4);

            c.CallSite.StackDepthOnEntry = 12;
            m.Return();
        }
예제 #10
0
        public void VpIndirectCall()
        {
            var callee = CreateExternalProcedure(
                "foo",
                12,
                RegArg(1, "r1"),
                StackArg(4),
                StackArg(8));
            var pc = new ProcedureConstant(PrimitiveType.Ptr32, callee);

            var m  = new ProcedureBuilder();
            var r1 = m.Reg32("r1", 1);
            var sp = m.Frame.EnsureRegister(m.Architecture.StackRegister);

            m.Assign(sp, m.Frame.FramePointer);
            m.Assign(r1, pc);
            m.Assign(sp, m.ISub(sp, 4));
            m.MStore(sp, m.Word32(3));
            m.Assign(sp, m.ISub(sp, 4));
            m.MStore(sp, m.Mem16(m.Word32(0x1231230)));
            m.Call(r1, 4);
            m.Return();

            arch.Setup(a => a.CreateStackAccess(
                           It.IsAny <IStorageBinder>(),
                           It.IsAny <int>(),
                           It.IsAny <DataType>()))
            .Returns((IStorageBinder f, int off, DataType dt) =>
                     m.Mem(dt, m.IAdd(f.EnsureRegister((RegisterStorage)sp.Storage), off)));
            arch.Setup(s => s.CreateFrameApplicationBuilder(
                           It.IsAny <IStorageBinder>(),
                           It.IsAny <CallSite>(),
                           It.IsAny <Expression>()))
            .Returns((IStorageBinder binder, CallSite site, Expression c) =>
                     new FrameApplicationBuilder(arch.Object, binder, site, c, false));

            var ssa  = RunTest(m);
            var sExp =
                #region Expected
                @"fp:fp
    def:  def fp
    uses: r63_2 = fp
          r63_4 = fp - 4<32>
          Mem5[fp - 4<32>:word32] = 3<32>
          r63_6 = fp - 8<32>
          Mem7[fp - 8<32>:word16] = Mem5[0x1231230<32>:word16]
          r1_8 = foo(Mem7[fp - 8<32>:word32], Mem7[fp - 4<32>:word32])
          r1_8 = foo(Mem7[fp - 8<32>:word32], Mem7[fp - 4<32>:word32])
r63_2: orig: r63
    def:  r63_2 = fp
r1_3: orig: r1
    def:  r1_3 = foo
r63_4: orig: r63
    def:  r63_4 = fp - 4<32>
Mem5: orig: Mem0
    def:  Mem5[fp - 4<32>:word32] = 3<32>
    uses: Mem7[fp - 8<32>:word16] = Mem5[0x1231230<32>:word16]
r63_6: orig: r63
    def:  r63_6 = fp - 8<32>
Mem7: orig: Mem0
    def:  Mem7[fp - 8<32>:word16] = Mem5[0x1231230<32>:word16]
    uses: r1_8 = foo(Mem7[fp - 8<32>:word32], Mem7[fp - 4<32>:word32])
          r1_8 = foo(Mem7[fp - 8<32>:word32], Mem7[fp - 4<32>:word32])
r1_8: orig: r1
    def:  r1_8 = foo(Mem7[fp - 8<32>:word32], Mem7[fp - 4<32>:word32])
// ProcedureBuilder
// Return size: 0
define ProcedureBuilder
ProcedureBuilder_entry:
	def fp
	// succ:  l1
l1:
	r63_2 = fp
	r1_3 = foo
	r63_4 = fp - 4<32>
	Mem5[fp - 4<32>:word32] = 3<32>
	r63_6 = fp - 8<32>
	Mem7[fp - 8<32>:word16] = Mem5[0x1231230<32>:word16]
	r1_8 = foo(Mem7[fp - 8<32>:word32], Mem7[fp - 4<32>:word32])
	return
	// succ:  ProcedureBuilder_exit
ProcedureBuilder_exit:
";

            #endregion
            AssertStringsEqual(sExp, ssa);
        }
예제 #11
0
        public void VpIndirectCall()
        {
            var callee = CreateExternalProcedure("foo", RegArg(1, "r1"), StackArg(4), StackArg(8));
            var pc     = new ProcedureConstant(PrimitiveType.Ptr32, callee);

            var m  = new ProcedureBuilder();
            var r1 = m.Reg32("r1", 1);
            var sp = m.Frame.EnsureRegister(m.Architecture.StackRegister);

            m.Assign(r1, pc);
            m.Assign(sp, m.ISub(sp, 4));
            m.MStore(sp, m.Word32(3));
            m.Assign(sp, m.ISub(sp, 4));
            m.MStore(sp, m.Mem16(m.Word32(0x1231230)));
            m.Call(r1, 4);
            m.Return();

            arch.Stub(a => a.CreateStackAccess(null, 0, null))
            .IgnoreArguments()
            .Do(new Func <IStorageBinder, int, DataType, Expression>((f, off, dt) => m.Mem(dt, m.IAdd(sp, off))));
            mr.ReplayAll();

            var ssa  = RunTest(m);
            var sExp =
                #region Expected
                @"r1_0: orig: r1
    def:  r1_0 = foo
r63:r63
    def:  def r63
    uses: r63_2 = r63 - 0x00000004
          Mem3[r63 - 0x00000004:word32] = 0x00000003
          r63_4 = r63 - 0x00000008
          Mem5[r63 - 0x00000008:word16] = Mem3[0x01231230:word16]
          r1_6 = foo(Mem8[r63 - 0x00000008:word32], Mem9[r63 - 0x00000004:word32])
          r1_6 = foo(Mem8[r63 - 0x00000008:word32], Mem9[r63 - 0x00000004:word32])
r63_2: orig: r63
    def:  r63_2 = r63 - 0x00000004
Mem3: orig: Mem0
    def:  Mem3[r63 - 0x00000004:word32] = 0x00000003
    uses: Mem5[r63 - 0x00000008:word16] = Mem3[0x01231230:word16]
r63_4: orig: r63
    def:  r63_4 = r63 - 0x00000008
Mem5: orig: Mem0
    def:  Mem5[r63 - 0x00000008:word16] = Mem3[0x01231230:word16]
r1_6: orig: r1
    def:  r1_6 = foo(Mem8[r63 - 0x00000008:word32], Mem9[r63 - 0x00000004:word32])
r63_7: orig: r63
Mem8: orig: Mem0
    uses: r1_6 = foo(Mem8[r63 - 0x00000008:word32], Mem9[r63 - 0x00000004:word32])
Mem9: orig: Mem0
    uses: r1_6 = foo(Mem8[r63 - 0x00000008:word32], Mem9[r63 - 0x00000004:word32])
// ProcedureBuilder
// Return size: 0
void ProcedureBuilder()
ProcedureBuilder_entry:
	def r63
	// succ:  l1
l1:
	r1_0 = foo
	r63_2 = r63 - 0x00000004
	Mem3[r63 - 0x00000004:word32] = 0x00000003
	r63_4 = r63 - 0x00000008
	Mem5[r63 - 0x00000008:word16] = Mem3[0x01231230:word16]
	r1_6 = foo(Mem8[r63 - 0x00000008:word32], Mem9[r63 - 0x00000004:word32])
	return
	// succ:  ProcedureBuilder_exit
ProcedureBuilder_exit:
";

            #endregion
            AssertStringsEqual(sExp, ssa);
        }