Beispiel #1
0
        public void Avoid()
        {
            m.Assign(SCZ, m.Cond(m.ISub(cx, 0x0030)));
            m.Assign(ax, m.IAdd(m.Word16(0x0000), CF));
            m.Assign(SCZ, m.Cond(ax));
            m.Assign(SCZ, m.Cond(m.ISub(cx, 0x003A)));
            m.Assign(CF, m.Not(CF));
            m.Assign(ax, m.IAdd(m.IAdd(ax, ax), CF));
            m.Assign(SCZ, m.Cond(ax));
            var block = m.Block;

            m.Return();

            rw.Transform();

            var sExp = @"l1:
	SCZ = cond(cx - 0x0030)
	ax = 0x0000 + C
	SCZ = cond(ax)
	SCZ = cond(cx - 0x003A)
	C = !C
	ax = ax + ax + C
	SCZ = cond(ax)
	return
";
            var sb   = new StringWriter();

            block.Write(sb);
            Assert.AreEqual(sExp, sb.ToString());
        }
Beispiel #2
0
        public void Exs_UnsignedRangeComparison()
        {
            Given_ExpressionSimplifier();
            var expr = m.Ugt(m.ISub(foo, 2), m.Word32(5));

            Assert.AreEqual("foo_0 >u 0x00000007 || foo_0 <u 0x00000002", expr.Accept(simplifier).ToString());
        }
Beispiel #3
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());
        }
Beispiel #4
0
        public void VpEquality2()
        {
            // Makes sure that
            // y = x - 2
            // if (y == 0) ...
            // doesn't get munged into
            // y = x - 2
            // if (x == 2)

            Identifier       x = Reg32("x");
            Identifier       y = Reg32("y");
            ProcedureBuilder m = new ProcedureBuilder();
            var stmX           = m.Assign(x, m.LoadDw(Constant.Word32(0x1000300)));

            ssaIds[x].DefStatement = m.Block.Statements.Last;
            var stmY = m.Assign(y, m.ISub(x, 2));

            ssaIds[y].DefStatement = m.Block.Statements.Last;
            var stm = m.BranchIf(m.Eq(y, 0), "test");

            Assert.AreEqual("x = Mem0[0x01000300:word32]", stmX.ToString());
            Assert.AreEqual("y = x - 0x00000002", stmY.ToString());
            Assert.AreEqual("branch y == 0x00000000 test", stm.ToString());

            var vp = new ValuePropagator(arch, ssaIds, null);

            vp.Transform(stm);
            Assert.AreEqual("branch x == 0x00000002 test", stm.Instruction.ToString());
        }
        public void CceSetnz()
        {
            Identifier r = Reg32("r");
            Identifier Z = FlagGroup("Z");
            Identifier f = Reg32("f");

            Statement stmZ = new Statement(0, m.Assign(Z, m.Cond(m.ISub(r, 0))), null);

            ssaIds[Z].DefStatement = stmZ;
            Statement stmF = new Statement(0, m.Assign(f, m.Test(ConditionCode.NE, Z)), null);

            ssaIds[f].DefStatement = stmF;
            ssaIds[Z].Uses.Add(stmF);

            Given_ConditionCodeEliminator();
            cce.Transform();
            Assert.AreEqual("f = r != 0x00000000", stmF.Instruction.ToString());
        }
        public void AtrcoIdMinusConst()
        {
            Identifier   r   = m.Local32("r");
            MemoryAccess mem = m.Load(PrimitiveType.Word32, m.ISub(r, 4));

            mem.Accept(eqb);
            atrco.Collect(null, 0, mem, mem.EffectiveAddress);
            Verify(null, "Typing/AtrcoIdMinusConst.txt");
        }
Beispiel #7
0
        public void VpShiftSum()
        {
            ProcedureBuilder m = new ProcedureBuilder();
            Expression       e = m.Shl(1, m.ISub(Constant.Byte(32), 1));
            var vp             = new ExpressionSimplifier(segmentMap, new SsaEvaluationContext(arch.Object, null, dynamicLinker.Object), listener);

            e = e.Accept(vp);
            Assert.AreEqual("0x80000000<32>", e.ToString());
        }
Beispiel #8
0
        public void VpShiftSum()
        {
            ProcedureBuilder m = new ProcedureBuilder();
            Expression       e = m.Shl(1, m.ISub(Constant.Byte(32), 1));
            var vp             = new ExpressionSimplifier(new SsaEvaluationContext(arch, null), listener);

            e = e.Accept(vp);
            Assert.AreEqual("0x80000000", e.ToString());
        }
Beispiel #9
0
        public void VpShiftSum()
        {
            Constant         c = Constant.Word32(1);
            ProcedureBuilder m = new ProcedureBuilder();
            Expression       e = m.Shl(1, m.ISub(Constant.Byte(32), 1));
            var vp             = new ExpressionSimplifier(new SsaEvaluationContext(ssaIds));

            e = e.Accept(vp);
            Assert.AreEqual("0x80000000", e.ToString());
        }
Beispiel #10
0
        public void VpPhiLoops()
        {
            var m   = new ProcedureBuilder();
            var ssa = new SsaState(m.Procedure, null);

            ssaIds = ssa.Identifiers;
            var fp = Reg16("fp");
            var a  = Reg16("a");
            var b  = Reg16("b");
            var c  = Reg16("c");
            var d  = Reg16("d");
            var x  = Reg16("x");
            var y  = Reg16("y");
            var z  = Reg16("z");

            m.Emit(m.Assign(y, m.IAdd(x, 4)));
            m.Emit(m.Assign(z, m.ISub(x, 8)));
            m.Emit(m.Assign(a, m.ISub(fp, 12)));
            m.Emit(m.Assign(b, m.ISub(fp, 12)));
            m.Emit(m.Assign(c, m.ISub(y, 4)));
            m.Emit(m.Assign(d, m.IAdd(z, 8)));
            var phiStm = m.Phi(x, a, b, c, d);
            var stms   = m.Procedure.EntryBlock.Succ[0].Statements;

            stms.ForEach(stm =>
            {
                var ass = stm.Instruction as Assignment;
                if (ass != null)
                {
                    ssaIds[ass.Dst].DefStatement = stm;
                }
                var phiAss = stm.Instruction as PhiAssignment;
                if (phiAss != null)
                {
                    ssaIds[phiAss.Dst].DefStatement = stm;
                }
            });
            var vp = new ValuePropagator(arch, ssa, listener);

            vp.Transform();
            Assert.AreEqual("x = fp - 0x000C", phiStm.Instruction.ToString());
        }
        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();
        }
Beispiel #12
0
        public void VpLoop()
        {
            var b = new ProgramBuilder();

            b.Add("main", m =>
            {
                var r  = m.Reg32("r0", 0);
                var zf = m.Flags("Z");
                m.Label("l0000");
                m.Store(r, 0);
                m.Assign(r, m.ISub(r, 4));
                m.Assign(zf, m.Cond(r));
                m.BranchCc(ConditionCode.NE, "l0000");

                m.Label("l0001");
                m.Assign(r, 42);

                m.Label("l0002");
                m.Store(r, 12);
                m.Assign(r, m.ISub(r, 4));
                m.BranchIf(m.Eq0(r), "l0002");

                m.Return();
            });
            RunFileTest(b.BuildProgram(), "Analysis/VpLoop.txt");
        }
Beispiel #13
0
        public void VpPhiLoopsSimplifyArgs()
        {
            var m    = new ProcedureBuilder();
            var sp   = Reg16("sp");
            var sp_1 = Reg16("sp_1");
            var sp_2 = Reg16("sp_2");
            var a    = Reg16("a");
            var b    = Reg16("b");
            var c    = Reg16("c");
            var d    = Reg16("d");
            var v    = Reg16("v");
            var w    = Reg16("w");
            var x    = Reg16("x");
            var y    = Reg16("y");
            var z    = Reg16("z");

            m.Phi(sp, sp_1, sp_2);
            m.Assign(v, m.ISub(sp, 4));
            m.Assign(w, m.ISub(sp, 8));
            m.Assign(y, m.IAdd(x, 4));
            m.Assign(z, m.ISub(x, 8));
            m.Assign(a, m.ISub(v, 8));
            m.Assign(b, m.ISub(w, 4));
            m.Assign(c, m.ISub(y, 4));
            m.Assign(d, m.IAdd(z, 8));
            var phiStm = m.Phi(x, a, b, c, d);

            RunValuePropagator(m);
            Assert.AreEqual("x = sp - 0x000C", phiStm.Instruction.ToString());
        }
Beispiel #14
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");
        }
Beispiel #15
0
        public void BwReg_00121()
        {
            var d0    = m.Reg32("d0", 0);
            var d3    = m.Reg32("d3", 3);
            var a5    = m.Reg32("a5", 5);
            var v38   = m.Temp(PrimitiveType.Word16, "v38");
            var v39   = m.Temp(PrimitiveType.Byte, "v39");
            var v40   = m.Temp(PrimitiveType.Word16, "v40");
            var VZN   = m.Flags("VZN");
            var ZN    = m.Flags("ZN");
            var C     = m.Flags("C");
            var V     = m.Flags("V");
            var CVZN  = m.Flags("CVZN");
            var CVZNX = m.Flags("CVZNX");

            m.Assign(d0, d3);
            m.Assign(CVZN, m.Cond(d0));
            m.Assign(v38, m.And(m.Cast(PrimitiveType.Word16, d0), 0xF0));
            m.Assign(d0, m.Dpb(d0, v38, 0));
            m.Assign(ZN, m.Cond(v38));
            m.Assign(C, false);
            m.Assign(V, false);
            m.Assign(v39, m.Shl(m.Cast(PrimitiveType.Byte, d0), 2));
            m.Assign(d0, m.Dpb(d0, v39, 0));
            m.Assign(CVZNX, m.Cond(v39));
            m.Assign(v40, m.ISub(m.Cast(PrimitiveType.Word16, d0), 44));
            m.Assign(CVZN, m.Cond(v40));
            m.BranchIf(m.Test(ConditionCode.GT, VZN), "lDefault");
            m.Assign(a5, m.Mem32(m.IAdd(Address.Ptr32(0x0000C046), d0)));
            var xfer = new RtlCall(a5, 4, RtlClass.Transfer);

            var bw = new Backwalker <Block, Instruction>(host, xfer, expSimp);

            Assert.IsTrue(bw.CanBackwalk());
            Assert.AreEqual("a5", bw.Index.Name);
            bw.BackWalk(m.Block);
            Assert.AreEqual("v40", bw.IndexExpression.ToString());
        }
Beispiel #16
0
        public void BwComparison()
        {
            var eax  = m.Frame.EnsureRegister(Registers.eax);
            var SCZO = m.Frame.EnsureFlagGroup((uint)(FlagM.SF | FlagM.ZF | FlagM.CF | FlagM.OF), "SCZO", PrimitiveType.Byte);
            var bw   = new Backwalker(host, new RtlGoto(m.LoadDw(m.IAdd(eax, 0x1000)), RtlClass.Transfer), expSimp);

            bw.UsedFlagIdentifier = m.Frame.EnsureFlagGroup((uint)FlagM.CF, "C", PrimitiveType.Byte);
            Assert.IsFalse(bw.BackwalkInstruction(
                               m.Assign(SCZO, new ConditionOf(m.ISub(eax, 3)))), "Encountering this comparison should terminate the backwalk");
            Assert.AreSame(Registers.eax, bw.Index);
            Assert.AreEqual("cmp 3", bw.Operations[0].ToString());
        }
Beispiel #17
0
        public void Larw_Avoid()
        {
            RunTest(m =>
            {
                m.Assign(SCZ, m.Cond(m.ISub(cx, 0x0030)));
                m.Assign(ax, m.IAdd(m.Word16(0x0000), CF));
                m.Assign(SCZ, m.Cond(ax));
                m.Assign(SCZ, m.Cond(m.ISub(cx, 0x003A)));
                m.Assign(CF, m.Not(CF));
                m.Assign(ax, m.IAdd(m.IAdd(ax, ax), CF));
                m.Assign(SCZ, m.Cond(ax));
                block = m.Block;
                m.Return();
            });

            rw.Transform();

            var sExp = @"l1:
	SCZ_2 = cond(cx - 0x30<16>)
	C_3 = SLICE(SCZ_2, bool, 2) (alias)
	ax_4 = 0<16> + C_3
	SCZ_5 = cond(ax_4)
	SCZ_6 = cond(cx - 0x3A<16>)
	C_7 = SLICE(SCZ_6, bool, 2) (alias)
	C_8 = !C_7
	ax_9 = ax_4 + ax_4 + C_8
	SCZ_10 = cond(ax_9)
	C_11 = SLICE(SCZ_10, bool, 2) (alias)
	S_12 = SLICE(SCZ_10, bool, 0) (alias)
	Z_13 = SLICE(SCZ_10, bool, 1) (alias)
	return
";
            var sb   = new StringWriter();

            block.Write(sb);
            Assert.AreEqual(sExp, sb.ToString());
        }
        /// <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();
        }
Beispiel #19
0
        public void SsaPushAndPop()
        {
            // Mirrors the pattern of stack accesses used by x86 compilers.
            var m   = new ProcedureBuilder("SsaPushAndPop");
            var esp = EnsureRegister32(m, "esp");
            var ebp = EnsureRegister32(m, "ebp");
            var eax = EnsureRegister32(m, "eax");

            m.Assign(esp, m.ISub(esp, 4));
            m.MStore(esp, ebp);
            m.Assign(ebp, esp);
            m.Assign(eax, m.Mem32(m.IAdd(ebp, 8)));  // dwArg04
            m.Assign(ebp, m.Mem32(esp));
            m.Assign(esp, m.IAdd(esp, 4));
            m.Return();

            RunUnitTest(m, "Analysis/SsaPushAndPop.txt");
        }
        public void TrfCopyBack()
        {
            var esp  = m.Frame.EnsureRegister(Registers.esp);
            var r2   = m.Register(2);
            var stm1 = m.MStore(m.ISub(esp, 0x10), r2);
            var stm2 = m.Assign(r2, m.Int32(0));
            var stm3 = m.Assign(r2, m.Mem32(m.ISub(esp, 0x10)));

            trf = CreateTrashedRegisterFinder();
            var flow = CreateBlockFlow(m.Block, m.Frame);

            flow.SymbolicIn.SetValue((Identifier)esp, (Expression)this.m.Frame.FramePointer);
            trf.StartProcessingBlock(m.Block);

            stm1.Instruction.Accept(trf);
            stm2.Accept(trf);
            stm3.Accept(trf);

            Assert.AreEqual(r2, trf.RegisterSymbolicValues[(RegisterStorage)r2.Storage]);
        }
 public void Exs_UnsignedRangeComparison()
 {
     Given_ExpressionSimplifier();
     var(expr, _) = m.Ugt(m.ISub(foo, 2), m.Word32(5)).Accept(simplifier);
     Assert.AreEqual("foo_1 >u 7<32> || foo_1 <u 2<32>", expr.ToString());
 }
Beispiel #22
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);
        }
Beispiel #23
0
        public void StrAnls_r00237()
        {
            //byte fn0800_0541(byte al, selector ds)

            var ds    = m.Temp(PrimitiveType.SegmentSelector, "ds");
            var cx_10 = m.Temp(PrimitiveType.Word16, "cx_10");
            var si_12 = m.Temp(PrimitiveType.Word16, "si_12");
            var ah_13 = m.Temp(PrimitiveType.Byte, "al_13");
            var al_43 = m.Temp(PrimitiveType.Byte, "al_43");
            var Z_26  = m.Temp(PrimitiveType.Byte, "Z_26");

            m.Assign(cx_10, 20000);
            m.Label("l0800_0544");
            m.Assign(si_12, 0x8E8A);
            m.Assign(ah_13, 0x00);
            m.Label("l0800_054A");
            m.Assign(si_12, m.IAdd(si_12, 0x01));
            m.BranchIf(m.Eq0(m.SegMem8(ds, si_12)), "l0800_0557");
            m.Label("l0800_054F");
            m.Assign(ah_13, 0x01);
            m.Assign(Z_26, m.Cond(m.ISub(si_12, m.SegMem16(ds, m.Word16(0x8F0B)))));
            m.BranchIf(m.Ne(si_12, m.SegMem16(ds, m.Word16(0x8F0B))), "l0800_055F");
            m.Label("l0800_0557");
            m.Assign(Z_26, m.Cond(m.ISub(si_12, 0x8F0A)));
            m.BranchIf(m.Eq(si_12, 0x8F0A), "l0800_055F");
            m.Label("l0800_055D");
            m.Goto("l0800_054A");
            m.Label("l0800_055F");
            m.BranchIf(Z_26, "l0800_0578");
            m.Label("l0800_0561");
            m.SegStore(ds, m.Word16(0x8F0B), si_12);
            m.Assign(al_43, m.SegMem8(ds, m.ISub(si_12, 0x8E31)));
            m.BranchIf(m.Eq0(al_43), "l0800_0576");
            m.Label("l0800_0571");
            m.BranchIf(m.Ge(al_43, 0x00), "l0800_0575");
            m.Label("l0800_0573");
            m.Assign(al_43, 0x00);
            m.Label("l0800_0575");
            m.Return(al_43);
            m.Label("l0800_0576");
            m.Goto("l0800_0583");
            m.Label("l0800_0578");
            m.BranchIf(m.Ne0(ah_13), "l0800_0583");
            m.Label("l0800_057D");
            m.SegStore(ds, m.Word16(0x8F0B), m.Byte(0));
            m.Label("l0800_0583");
            m.Assign(cx_10, m.ISub(cx_10, 0x01));
            m.BranchIf(m.Ne0(cx_10), "l0800_0544");
            m.Label("l0800_0585");
            m.Return(m.Byte(0x00));

            var sExp =
                #region Expected
                @"    cx_10 = 20000;
    do
    {
        si_12 = 0x8E8A;
        al_13 = 0x00;
        do
        {
            si_12 = si_12 + 0x01;
            if (Mem0[ds:si_12:byte] != 0x00)
            {
                al_13 = 0x01;
                Z_26 = cond(si_12 - Mem0[ds:0x8F0B:word16]);
                if (si_12 != Mem0[ds:0x8F0B:word16])
                    break;
            }
            Z_26 = cond(si_12 - 0x8F0A);
        } while (si_12 != 0x8F0A);
        if (!Z_26)
        {
            Mem0[ds:0x8F0B:word16] = si_12;
            al_43 = Mem0[ds:si_12 - 0x8E31:byte];
            if (al_43 != 0x00)
            {
                if (al_43 < 0x00)
                    al_43 = 0x00;
                return al_43;
            }
        }
        else if (al_13 == 0x00)
            Mem0[ds:0x8F0B:byte] = 0x00;
        cx_10 = cx_10 - 0x01;
    } while (cx_10 != 0x00);
    return 0x00;
";

            #endregion

            RunTest(sExp, m.Procedure);
        }
Beispiel #24
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);
        }