예제 #1
0
        private void RunTest(string sExp, IProcessorArchitecture arch, Action <SsaProcedureBuilder> builder)
        {
            var m = new SsaProcedureBuilder(arch);

            builder(m);
            var sac = new SegmentedAccessClassifier(m.Ssa);

            sac.Classify();
            var prpr = new ProjectionPropagator(m.Ssa, sac);

            prpr.Transform();
            var sw = new StringWriter();

            m.Ssa.Procedure.WriteBody(false, sw);
            sw.Flush();
            m.Ssa.Dump(true);
            var sActual = sw.ToString();

            if (sActual != sExp)
            {
                Console.WriteLine(sActual);
                Assert.AreEqual(sExp, sActual);
            }
            m.Ssa.Validate(s => Assert.Fail(s));
        }
예제 #2
0
        public void Cab_Sequence_MkSequence()
        {
            var m    = new SsaProcedureBuilder(nameof(Cab_Sequence));
            var r2_1 = m.Reg("r2_1", reg2);
            var r3_2 = m.Reg("r3_2", reg3);

            m.Assign(r2_1, 0x0001234);
            m.Assign(r3_2, 0x5678ABCD);
            var sigCallee = FunctionType.Action(
                new Identifier("r2_r3", PrimitiveType.Word64,
                               new SequenceStorage(PrimitiveType.Word64, reg2, reg3)));
            var callee = new ProcedureConstant(
                PrimitiveType.Ptr32,
                new ExternalProcedure("callee", sigCallee));
            var stmCall = m.Call(callee, 0,
                                 new Identifier[] { r3_2, r2_1 },
                                 new Identifier[] { });

            m.Return();

            var cab = new CallApplicationBuilder(
                m.Ssa,
                stmCall,
                (CallInstruction)stmCall.Instruction,
                callee);
            var instr = cab.CreateInstruction(sigCallee, null);

            Assert.AreEqual("callee(SEQ(r2_1, r3_2))", instr.ToString());
            m.Ssa.Validate(s => Assert.Fail(s));
        }
예제 #3
0
        private void RunTest(string sExpected, Action <SsaProcedureBuilder> builder)
        {
            var m = new SsaProcedureBuilder();

            builder(m);

            var ssa     = m.Ssa;
            var program = new Program
            {
                SegmentMap = new SegmentMap(Address.Ptr32(0x00123400))
            };
            var svp = new SparseValuePropagation(ssa, program, null, new FakeDecompilerEventListener());

            svp.Transform();
            var sw = new StringWriter();

            svp.Write(sw);
            ssa.Procedure.Write(false, sw);
            var sActual = sw.ToString();

            if (sExpected != sActual)
            {
                Console.WriteLine(sActual);
                Assert.AreEqual(sExpected, sActual);
            }
        }
예제 #4
0
        private Procedure RunSsaTest(string sExp, Action <SsaProcedureBuilder> builder)
        {
            var m = new SsaProcedureBuilder();

            builder(m);
            return(RunTest(sExp, m.Ssa));
        }
예제 #5
0
        private void RunClassifyTest(
            string sExp,
            string sidName,
            Action <SsaProcedureBuilder> gen,
            Func <Procedure, ProcedureFlow> mkFlow)
        {
            var m = new SsaProcedureBuilder();

            gen(m);
            var ssa = m.Ssa;

            pf.ProcedureFlows[ssa.Procedure] = mkFlow(ssa.Procedure);
            var urf = new UsedRegisterFinder(
                pf,
                new Procedure[] { ssa.Procedure },
                NullDecompilerEventListener.Instance);
            var sid  = ssa.Identifiers.Single(s => s.Identifier.Name == sidName);
            var flow = urf.Classify(ssa, sid, sid.Identifier.Storage, true);
            var sw   = new StringWriter();

            sw.Write("Used: ");
            sw.Write(string.Join(",", flow));
            var sActual = sw.ToString();

            if (sActual != sExp)
            {
                ssa.Procedure.Dump(true);
                Debug.WriteLine(sActual);
                Assert.AreEqual(sExp, sActual);
            }
        }
예제 #6
0
        private Procedure RunSsaTest(string sExp, Action <SsaProcedureBuilder> builder, Func <Procedure, ProcedureFlow> mkFlow = null)
        {
            var m = new SsaProcedureBuilder();

            builder(m);
            return(RunTest(sExp, m.Ssa, mkFlow));
        }
예제 #7
0
        public void SrtReg685()
        {
            var m   = new SsaProcedureBuilder(nameof(SrtReg685));
            var i_1 = m.Reg32("i_1");
            var i_2 = m.Reg32("i_2");
            var i_3 = m.Reg32("i_3");

            m.Assign(i_1, m.Int32(0));

            m.Label("m1");
            m.Phi(i_2, i_1, i_3);
            m.SideEffect(m.Fn("foo", i_2));
            m.SideEffect(m.Fn("foo", m.IAdd(i_2, 1)));
            m.Assign(i_3, m.IAdd(i_2, 2));
            m.BranchIf(m.Eq(i_3, 10), "m1");

            m.Label("m2");
            m.Return();

            var dom = m.Procedure.CreateBlockDominatorGraph();
            var lif = new LinearInductionVariableFinder(m.Procedure, m.Ssa.Identifiers, dom);

            lif.Find();
            Assert.AreEqual("(0 0x00000002 0x0000000C)", lif.InductionVariables[0].ToString());

            var ctx = lif.Contexts[lif.InductionVariables[0]];

            var str = new StrengthReduction(m.Ssa, lif.InductionVariables[0], ctx);

            str.ClassifyUses();
            Assert.AreEqual(2, str.IncrementedUses.Count);
            str.ModifyUses();
        }
 public void Setup()
 {
     arch           = new Mock <IProcessorArchitecture>().Object;
     importResolver = new Mock <IImportResolver>().Object;
     listener       = new FakeDecompilerEventListener();
     m = new SsaProcedureBuilder();
 }
예제 #9
0
 public void Setup()
 {
     mr             = new MockRepository();
     arch           = mr.Stub <IProcessorArchitecture>();
     importResolver = mr.Stub <IImportResolver>();
     listener       = new FakeDecompilerEventListener();
     m = new SsaProcedureBuilder();
 }
예제 #10
0
 public void Setup()
 {
     arch           = new Mock <IProcessorArchitecture>();
     importResolver = new Mock <IImportResolver>();
     listener       = new FakeDecompilerEventListener();
     m          = new SsaProcedureBuilder();
     segmentMap = new SegmentMap(Address.Ptr32(0));
 }
        public void Setup()
        {
            m = new SsaProcedureBuilder();
            var stStg = m.RegisterStorage("FakeST", PrimitiveType.Word32);

            ST = new MemoryIdentifier(stStg.Name, stStg.DataType, stStg);
            ((FakeArchitecture)m.Architecture).FpuStackBase = ST;
            Top = m.Architecture.FpuStackRegister;
        }
예제 #12
0
        public void Urb_Remove_many_blocks()
        {
            var m = new SsaProcedureBuilder(name: nameof(Urb_Remove_many_blocks));

            var r1_1 = m.Reg32("r1_1");
            var r1_2 = m.Reg32("r1_2");
            var r1_3 = m.Reg32("r1_3");
            var r1_4 = m.Reg32("r1_4");
            var r2   = m.Reg32("r2");

            m.AddDefToEntryBlock(r2);
            m.BranchIf(Constant.False(), "m2");

            m.Label("m1");
            m.Assign(r1_1, 1);
            m.Goto("m4");

            m.Label("m2");  // dead code
            m.BranchIf(m.Eq0(r2), "m3");

            m.Label("m2a");
            m.Assign(r1_2, 2);
            m.Goto("m4");

            m.Label("m3");
            m.Assign(r1_3, 3);
            // end of dead code.

            m.Label("m4");
            m.Phi(r1_4, (r1_1, "m1"), (r1_2, "m2a"), (r1_3, "m3"));
            m.Return(r1_4);

            var sExp =
                #region
                @"// Urb_Remove_many_blocks
// Return size: 0
define Urb_Remove_many_blocks
Urb_Remove_many_blocks_entry:
	def r2
	// succ:  l1
l1:
	// succ:  m1
m1:
	r1_1 = 1<32>
	// succ:  m4
m4:
	r1_4 = r1_1
	return r1_4
	// succ:  Urb_Remove_many_blocks_exit
Urb_Remove_many_blocks_exit:
";

            #endregion

            RunTest(sExp, m);
        }
예제 #13
0
        private void Given_Procedure(
            string name,
            Action <SsaProcedureBuilder> builder)
        {
            var m = new SsaProcedureBuilder(name);

            builder(m);
            pb.Add(m);
            ssaStates.Add(m.Ssa);
        }
예제 #14
0
 public void Setup()
 {
     arch = new Mock <IProcessorArchitecture>();
     arch.Setup(a => a.Name).Returns("FakeArch");
     dynamicLinker = new Mock <IDynamicLinker>();
     listener      = new FakeDecompilerEventListener();
     m             = new SsaProcedureBuilder();
     segmentMap    = new SegmentMap(Address.Ptr32(0));
     program       = new Program()
     {
         Architecture = arch.Object,
         SegmentMap   = segmentMap,
     };
 }
예제 #15
0
        private void RunTest(string sExpected, SsaProcedureBuilder pb)
        {
            var urb = new UnreachableBlockRemover(pb.Ssa, new FakeDecompilerEventListener());

            urb.Transform();
            var sw = new StringWriter();

            pb.Ssa.Procedure.Write(false, sw);
            var sActual = sw.ToString();

            if (sExpected != sActual)
            {
                Console.WriteLine(sActual);
                Assert.AreEqual(sExpected, sActual);
            }
            pb.Ssa.Validate(s => { pb.Ssa.Dump(true); Assert.Fail(s); });
        }
예제 #16
0
        public void Urb_Remove_false()
        {
            var m = new SsaProcedureBuilder(name: nameof(Urb_Remove_false));

            var r1_1 = m.Reg32("r1_1");
            var r1_2 = m.Reg32("r1_2");
            var r1_3 = m.Reg32("r1_3");

            m.BranchIf(Constant.False(), "m2");

            m.Label("m1");
            m.Assign(r1_1, 1);
            m.Goto("m3");

            m.Label("m2");  // dead code
            m.Assign(r1_2, 2);

            m.Label("m3");
            m.Phi(r1_3, (r1_1, "m1"), (r1_2, "m2"));
            m.Return(r1_3);

            var sExp =
                #region
                @"// Urb_Remove_false
// Return size: 0
define Urb_Remove_false
Urb_Remove_false_entry:
	// succ:  l1
l1:
	// succ:  m1
m1:
	r1_1 = 1<32>
	// succ:  m3
m3:
	r1_3 = r1_1
	return r1_3
	// succ:  Urb_Remove_false_exit
Urb_Remove_false_exit:
";

            #endregion

            RunTest(sExp, m);
        }
예제 #17
0
        public void Spbp_LinearProcedure()
        {
            var m = new SsaProcedureBuilder(nameof(Spbp_LinearProcedure));

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

            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);

            m.AddDefToEntryBlock(fp);

            m.Assign(sp_1, m.ISub(fp, m.Int32(4)));
            // Indirect call = hell node
            var ci = m.Call(m.Mem32(m.Word32(0x2)), 4,
                            new[] { sp_1 },
                            new[] { sp_2 });

            m.Assign(sp_3, m.IAdd(sp_2, m.Int32(4)));
            m.Return();

            m.AddUseToExitBlock(sp_3);

            RunTest(m.Ssa);

            var sExp =
                #region Expected
                @"Spbp_LinearProcedure_entry:
	def fp
l1:
	sp_1 = fp - 4
	call Mem4[0x00000002:word32] (retsize: 4;)
		uses: sp:sp_1
	sp_2 = fp - 4
	sp_3 = fp
	return
Spbp_LinearProcedure_exit:
	use sp_3
";

            #endregion
            AssertStringsEqual(sExp, m.Ssa);
        }
예제 #18
0
        public void Cab_GuessStackParameter()
        {
            var m  = new SsaProcedureBuilder(nameof(Cab_Sequence));
            var sp = m.Reg("sp", m.Procedure.Architecture.StackRegister);

            m.AddDefToEntryBlock(sp);
            var r2_1 = m.Reg("r2_1", reg2);
            var r3_2 = m.Reg("r3_2", reg3);

            m.MStore(sp, m.Word32(0x0001234));
            m.MStore(m.IAdd(sp, 4), m.Word32(0x5678ABCD));
            var sigCallee = FunctionType.Action(
                new Identifier("arg04", PrimitiveType.Word32,
                               new StackArgumentStorage(4, PrimitiveType.Word32)),
                new Identifier("arg08", PrimitiveType.Word32,
                               new StackArgumentStorage(8, PrimitiveType.Word32)));

            sigCallee.ReturnAddressOnStack = 4;
            var callee = new ProcedureConstant(
                PrimitiveType.Ptr32,
                new ExternalProcedure("callee", sigCallee));
            var stmCall = m.Call(callee, 0,
                                 new Identifier[] { sp },
                                 new Identifier[] { });

            m.Return();

            var cab = new CallApplicationBuilder(
                m.Ssa,
                stmCall,
                (CallInstruction)stmCall.Instruction,
                callee,
                true);
            var instr = cab.CreateInstruction(sigCallee, null);

            Assert.AreEqual("callee(Mem4[sp:word32], Mem4[sp + 4<i32>:word32])", instr.ToString());
            m.Ssa.Validate(s => Assert.Fail(s));
        }
        private void RunSsaTest(string sExpected, Action <SsaProcedureBuilder> generateCode)
        {
            var ssapb = new SsaProcedureBuilder();

            generateCode(ssapb);
            var program = new Program
            {
                Platform = platform,
            };
            var cce = new ConditionCodeEliminator(program, ssapb.Ssa, new FakeDecompilerEventListener());

            cce.Transform();
            var writer = new StringWriter();

            ssapb.Ssa.Procedure.WriteBody(true, writer);
            var sActual = writer.ToString();

            if (sActual != sExpected)
            {
                Console.WriteLine(sActual);
                Assert.AreEqual(sExpected, sActual);
            }
            ssapb.Ssa.Validate(s => { ssapb.Ssa.Dump(true); Assert.Fail(s); });
        }
예제 #20
0
        private void RunTest(string sExp, Action <SsaProcedureBuilder> builder)
        {
            var m = new SsaProcedureBuilder(arch);

            builder(m);

            var stfu = new StoreFuser(m.Ssa);

            stfu.Transform();

            var sw = new StringWriter();

            m.Ssa.Procedure.WriteBody(false, sw);
            sw.Flush();
            var sActual = sw.ToString();

            if (sExp != sActual)
            {
                m.Ssa.Dump(true);
                Console.WriteLine(sActual);
                Assert.AreEqual(sExp, sActual);
            }
            m.Ssa.Validate(s => Assert.Fail(s));
        }
예제 #21
0
 private void Given_FramePointer(SsaProcedureBuilder m)
 {
     this.fp = m.Ssa.Identifiers.Add(m.Frame.FramePointer, null, null, false).Identifier;
 }
예제 #22
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);
        }
예제 #23
0
 private void Given_StackPointer(SsaProcedureBuilder m)
 {
     this.sp = m.RegisterStorage("sp", PrimitiveType.Word32);
     m.Architecture.StackRegister = sp;
 }
예제 #24
0
 public void Setup()
 {
     m = new SsaProcedureBuilder();
     this.programDataFlow = new ProgramDataFlow();
     this.dynamicLinker   = new Mock <IDynamicLinker>();
 }
예제 #25
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);
        }
예제 #26
0
 public void Setup()
 {
     m = new SsaProcedureBuilder();
 }
예제 #27
0
 public void Setup()
 {
     m = new SsaProcedureBuilder();
     this.programDataFlow = new ProgramDataFlow();
     this.importResolver  = new Mock <IImportResolver>();
 }