예제 #1
0
        public void Spbp_SpaceOnStack()
        {
            var m = new SsaProcedureBuilder(nameof(Spbp_SpaceOnStack));

            var fp = m.Ssa.Identifiers.Add(m.Frame.FramePointer, null, null, false).Identifier;

            Given_StackPointer(m);
            var sp_1 = m.Reg("sp_1", sp);
            var sp_2 = m.Reg("sp_2", sp);
            var sp_3 = m.Reg("sp_3", sp);
            var sp_4 = m.Reg("sp_4", sp);
            var sp_5 = m.Reg("sp_5", sp);
            var sp_6 = m.Reg("sp_6", sp);
            var sp_7 = m.Reg("sp_7", sp);
            var sp_8 = m.Reg("sp_8", sp);
            var a    = m.Reg("a", new RegisterStorage("a", 1, 0, PrimitiveType.Word32));
            var b    = m.Reg("b", new RegisterStorage("b", 2, 0, PrimitiveType.Word32));
            var a_1  = m.Reg("a_1", (RegisterStorage)a.Storage);
            var b_1  = m.Reg("b_1", (RegisterStorage)b.Storage);

            m.AddDefToEntryBlock(fp);

            m.Assign(sp_2, m.ISub(fp, 4));  // space for a
            m.MStore(sp_2, a);
            m.Assign(sp_3, m.ISub(fp, 4));  // space for b
            m.MStore(sp_3, b);
            m.Assign(sp_4, m.ISub(fp, 40)); // 40 bytes of stack space
            m.MStore(sp_4, m.Word32(0xDEADBABE));
            m.Call(m.Mem32(m.Word32(0x00123400)), 4,
                   new[] { sp_4 },
                   new[] { sp_5 });
            m.Assign(sp_6, m.IAdd(sp_5, 40));
            m.Assign(b_1, m.Mem32(sp_6));
            m.Assign(sp_7, m.IAdd(sp_6, 4));
            m.Assign(a_1, m.Mem32(sp_7));
            m.Assign(sp_8, m.IAdd(sp_7, 4));
            m.Return();
            m.AddUseToExitBlock(sp_8);

            RunTest(m.Ssa);

            var sExp =
                #region Expected
                @"Spbp_SpaceOnStack_entry:
	def fp
l1:
	sp_2 = fp - 0x00000004
	Mem13[sp_2:word32] = a
	sp_3 = fp - 0x00000004
	Mem14[sp_3:word32] = b
	sp_4 = fp - 0x00000028
	Mem15[sp_4:word32] = 0xDEADBABE
	call Mem16[0x00123400:word32] (retsize: 4;)
		uses: sp:sp_4
	sp_5 = fp - 48
	sp_6 = fp - 8
	b_1 = Mem17[sp_6:word32]
	sp_7 = fp - 4
	a_1 = Mem18[sp_7:word32]
	sp_8 = fp
	return
Spbp_SpaceOnStack_exit:
	use sp_8
";

            #endregion

            this.AssertStringsEqual(sExp, m.Ssa);
        }
예제 #2
0
        public void VpReusedRegistersAtCall()
        {
            var sExp =
                #region Expected
                @"r2_1: orig: r2
    def:  r2_1 = Mem4[0x220200<32>:word32]
    uses: r4_1 = r2_1
          callee(r2_1)
r2_2: orig: r2
    def:  r2_2 = callee
r4_1: orig: r4
    def:  r4_1 = r2_1
r25_1: orig: r25
    def:  r25_1 = callee
Mem4: orig: Mem0
    uses: r2_1 = Mem4[0x220200<32>:word32]
Mem5: orig: Mem0
// SsaProcedureBuilder
// Return size: 0
define SsaProcedureBuilder
SsaProcedureBuilder_entry:
	// succ:  l1
l1:
	r2_1 = Mem4[0x220200<32>:word32]
	r4_1 = r2_1
	r2_2 = callee
	r25_1 = callee
	callee(r2_1)
	return
	// succ:  SsaProcedureBuilder_exit
SsaProcedureBuilder_exit:
";

            #endregion

            var uAddrGotSlot = m.Word32(0x0040000);
            var reg2         = new RegisterStorage("r2", 2, 0, PrimitiveType.Word32);
            var reg4         = new RegisterStorage("r4", 4, 0, PrimitiveType.Word32);
            var reg25        = new RegisterStorage("r25", 25, 0, PrimitiveType.Word32);
            var r2_1         = m.Reg("r2_1", reg2);
            var r2_2         = m.Reg("r2_2", reg2);
            var r4_1         = m.Reg("r4_1", reg4);
            var r25_1        = m.Reg("r25_1", reg25);
            m.Assign(r2_1, m.Mem32(m.Word32(0x0220200))); // fetch a string pointer perhaps
            m.Assign(r4_1, r2_1);
            m.Assign(r2_2, m.Mem32(uAddrGotSlot));        // pointer to a function in a lookup table.
            m.Assign(r25_1, r2_2);
            var stmCall = m.Call(r25_1, 0,
                                 new Identifier[] { r4_1, r2_2 },
                                 new Identifier[] { });
            m.Return();

            // Initially we don't know what r2_2 is pointing to.
            var vp = new ValuePropagator(segmentMap, m.Ssa, program.CallGraph, dynamicLinker.Object, listener);
            vp.Transform();

            // Later, Reko discovers information about the pointer in 0x400000<32>!

            var sigCallee = FunctionType.Action(
                new Identifier("r4", PrimitiveType.Word64, reg4));
            var callee = new ProcedureConstant(
                PrimitiveType.Ptr32,
                new ExternalProcedure("callee", sigCallee));
            // Add our new found knowledge to the import resolver.
            dynamicLinker.Setup(i => i.ResolveToImportedValue(
                                    It.IsNotNull <Statement>(),
                                    uAddrGotSlot)).
            Returns(callee);

            // Run Value propagation again with the newly gathered information.

            vp.Transform();

            m.Ssa.Validate(s => Assert.Fail(s));
            AssertStringsEqual(sExp, m.Ssa);
        }
예제 #3
0
        public void Spbp_TwoExits()
        {
            var m = new SsaProcedureBuilder(nameof(Spbp_TwoExits));

            Given_FramePointer(m);
            Given_StackPointer(m);
            var sp_1 = m.Reg("sp_1", m.Architecture.StackRegister);
            var sp_2 = m.Reg("sp_2", m.Architecture.StackRegister);
            var sp_3 = m.Reg("sp_3", m.Architecture.StackRegister);
            var sp_4 = m.Reg("sp_4", m.Architecture.StackRegister);
            var sp_5 = m.Reg("sp_5", m.Architecture.StackRegister);
            var sp_6 = m.Reg("sp_6", m.Architecture.StackRegister);

            m.AddDefToEntryBlock(fp);

            m.Assign(sp_1, m.ISub(fp, m.Int32(4)));
            m.BranchIf(m.Eq0(m.Mem32(m.Word32(0x1))), "m_eq0");

            m.Label("m_ne0");
            // Indirect call = hell node
            m.Call(m.Mem32(m.Word32(0x4)), 4,
                   new[] { sp_1 },
                   new[] { sp_2 });
            m.Assign(sp_3, m.IAdd(sp_2, m.Int32(4)));
            m.Return();

            m.Label("m_eq0");
            // Indirect call = hell node
            m.Call(m.Mem32(m.Word32(0x8)), 4,
                   new[] { sp_1 },
                   new[] { sp_4 });
            m.Assign(sp_5, m.IAdd(sp_4, m.Int32(4)));
            m.Return();

            m.AddPhiToExitBlock(sp_6, (sp_3, "m_ne0"), (sp_5, "m_eq0"));
            m.AddUseToExitBlock(sp_6);

            RunTest(m.Ssa);

            var sExp =
                #region Expected
                @"Spbp_TwoExits_entry:
	def fp
l1:
	sp_1 = fp - 4
	branch Mem7[0x00000001:word32] == 0x00000000 m_eq0
	goto m_ne0
m_eq0:
	call Mem9[0x00000008:word32] (retsize: 4;)
		uses: sp:sp_1
	sp_4 = fp - 4
	sp_5 = fp
	return
m_ne0:
	call Mem8[0x00000004:word32] (retsize: 4;)
		uses: sp:sp_1
	sp_2 = fp - 4
	sp_3 = fp
	return
Spbp_TwoExits_exit:
	sp_6 = PHI((sp_3, m_ne0), (sp_5, m_eq0))
	use sp_6
";

            #endregion
            AssertStringsEqual(sExp, m.Ssa);
        }