Exemple #1
0
        public void Test_State_Redundant_Mem_2()
        {
            Tools tools = this.CreateTools(100000);

            tools.StateConfig.Set_All_Off();
            tools.StateConfig.RAX = true;
            tools.StateConfig.RBX = true;
            tools.StateConfig.Mem = true;

            string line1 = "mov ptr qword [rax], rbx";
            string line2 = "mov ptr qword [rax], rbx";

            State state = this.CreateState(tools);

            state = Runner.SimpleStep_Forward(line1, state);
            if (LogToDisplay)
            {
                Console.WriteLine("After \"" + line1 + "\", we know:\n" + state);
            }

            string key1 = state.HeadKey;

            state = Runner.SimpleStep_Forward(line2, state);
            if (LogToDisplay)
            {
                Console.WriteLine("After \"" + line2 + "\", we know:\n" + state);
            }

            string key2 = state.HeadKey;

            AsmTestTools.IsTrue(state.Is_Redundant_Mem(key1, key2));
        }
        public void Test_MemZ3_Forward_Eq1()
        {
            StateConfig stateConfig = new StateConfig();

            stateConfig.Set_All_Off();
            stateConfig.RAX = true;
            stateConfig.RBX = true;
            stateConfig.RCX = true;
            stateConfig.Mem = true;

            State   state = this.CreateState(stateConfig);
            Context ctx   = state.Ctx;
            Tools   tools = state.Tools;

            using (StateUpdate updateState = new StateUpdate(state.HeadKey, Tools.CreateKey(tools.Rand), tools))
            {
                // updateState.Set(Rn.RAX, 20);
                updateState.Set(Rn.RBX, 10);
                updateState.Set(Rn.RCX, 5);
                state.Update_Forward(updateState);
            }
            // TestTools.AreEqual(Rn.RAX, 20, state);
            AsmTestTools.AreEqual(Rn.RBX, 10, state);
            AsmTestTools.AreEqual(Rn.RCX, 5, state);

            BitVecExpr address1 = Tools.Calc_Effective_Address("qword ptr[rax + 2 * rbx + 10]", state.HeadKey, tools, ctx);
            BitVecExpr address2 = Tools.Calc_Effective_Address("qword ptr[rax + 4 * rcx + 10]", state.HeadKey, tools, ctx);

            Tv equalAddresses = state.EqualValues(address1, address2);

            if (LogToDisplay)
            {
                Console.WriteLine("equalAddresses=" + equalAddresses);
                Console.WriteLine("address1 = " + address1);
                Console.WriteLine("address2 = " + address2);
                Console.WriteLine(state);
            }
            AsmTestTools.AreEqual(Tv.ONE, equalAddresses);

            BitVecExpr value1 = state.Create(Rn.R8);

            using (StateUpdate updateState = new StateUpdate(state.HeadKey, Tools.CreateKey(tools.Rand), tools))
            {
                updateState.Set_Mem(address1, value1);
                state.Update_Forward(updateState);
            }
            BitVecExpr value2 = state.Create_Mem(address2, 8);

            if (LogToDisplay)
            {
                Console.WriteLine("value1 = " + value1);
                Console.WriteLine("value2 = " + value2);
                Console.WriteLine(state);
            }
            AsmTestTools.AreEqual(Tv.ONE, state.EqualValues(value1, value2));
        }
        public void Test_MemZ3_Forward_Eq5()
        {
            StateConfig stateConfig = new StateConfig();

            stateConfig.Set_All_Off();
            stateConfig.RAX = true;
            stateConfig.RBX = true;
            stateConfig.RCX = true;
            stateConfig.RDX = true;
            stateConfig.Mem = true;

            State   state = this.CreateState(stateConfig);
            Context ctx   = state.Ctx;
            Tools   tools = state.Tools;

            {
                StateUpdate updateState = new StateUpdate(state.HeadKey, Tools.CreateKey(tools.Rand), tools);
                updateState.Set(Rn.RAX, state.Create(Rn.RBX));
                state.Update_Forward(updateState);
            }
            BitVecExpr address1 = Tools.Calc_Effective_Address("byte ptr[rax]", state.HeadKey, tools, ctx);
            BitVecExpr address2 = Tools.Calc_Effective_Address("byte ptr[rbx]", state.HeadKey, tools, ctx);
            BitVecExpr value1a  = state.Create(Rn.CL);
            BitVecExpr value2a  = state.Create(Rn.DL);

            Debug.Assert(value1a.SortSize == value2a.SortSize);
            int nBytes = (int)value1a.SortSize >> 3;

            using (StateUpdate updateState = new StateUpdate(state.HeadKey, Tools.CreateKey(tools.Rand), tools))
            {
                updateState.Set_Mem(address1, value1a);
                state.Update_Forward(updateState);
            }
            BitVecExpr value1b = state.Create_Mem(address1, nBytes);

            using (StateUpdate updateState = new StateUpdate(state.HeadKey, Tools.CreateKey(tools.Rand), tools))
            {
                updateState.Set_Mem(address2, value2a);
                state.Update_Forward(updateState);
            }
            BitVecExpr value2b = state.Create_Mem(address2, nBytes);

            if (LogToDisplay)
            {
                Console.WriteLine("value1a = " + value1a);
                Console.WriteLine("value2a = " + value2a);
                Console.WriteLine("value1b = " + value1b);
                Console.WriteLine("value2b = " + value2b);
                Console.WriteLine(state);
            }
            AsmTestTools.AreEqual(Tv.ONE, state.EqualValues(value1a, value1b));
            AsmTestTools.AreEqual(Tv.ONE, state.EqualValues(value2a, value2b));
        }
Exemple #4
0
        public void Test_FlagTools_Create_OF_Add()
        {
            Context ctx = this.CreateContext();
            {
                uint  nBits = 8;
                ulong a     = 10;
                ulong b     = 20;

                BitVecExpr aExpr = ctx.MkBV(a, nBits);
                BitVecExpr bExpr = ctx.MkBV(b, nBits);

                BoolExpr resultExpr = ToolsFlags.Create_OF_Add(aExpr, bExpr, nBits, ctx).Simplify() as BoolExpr;
                Assert.IsTrue(AsmTestTools.Calc_OF_Add(nBits, a, b) ? resultExpr.IsTrue : resultExpr.IsFalse);
            }
        }
        public void Test_MemZ3_Forward_Eq6()
        {
            StateConfig stateConfig = new StateConfig();

            stateConfig.Set_All_Off();
            stateConfig.RAX = true;
            stateConfig.RBX = true;
            stateConfig.RCX = true;
            stateConfig.RDX = true;
            stateConfig.Mem = true;

            State   state = this.CreateState(stateConfig);
            Context ctx   = state.Ctx;
            Tools   tools = state.Tools;

            Rn  reg1   = Rn.CL;
            Rn  reg2   = Rn.DL;
            int nBytes = RegisterTools.NBits(reg1) >> 3;

            Debug.Assert(RegisterTools.NBits(reg1) == RegisterTools.NBits(reg2));

            BitVecExpr address1 = Tools.Calc_Effective_Address("qword ptr[rax]", state.HeadKey, tools, ctx);
            BitVecExpr address2 = Tools.Calc_Effective_Address("qword ptr[rbx]", state.HeadKey, tools, ctx);

            BitVecExpr value1 = state.Create_Mem(address1, nBytes);
            BitVecExpr value2 = state.Create_Mem(address2, nBytes);

            Assert.AreNotEqual(value1, value2); // value1 is not equal to value2 simply because rax and rbx are not related yet

            state.Add(new BranchInfo(state.Ctx.MkEq(state.Create(Rn.RAX), state.Create(Rn.RBX)), true));
            // value1 and value2 are now (intuitively) equal; however, the retrieved memory values have not been updated yet to reflect this.

            using (StateUpdate updateState = new StateUpdate(state.HeadKey, Tools.CreateKey(tools.Rand), tools))
            {
                updateState.Set(reg1, value1);
                updateState.Set(reg2, value2);
                state.Update_Forward(updateState);
            }
            if (LogToDisplay)
            {
                Console.WriteLine("value1 = " + value1);
                Console.WriteLine("value2 = " + value2);
                Console.WriteLine(reg1 + " = " + state.Create(reg1));
                Console.WriteLine(reg2 + " = " + state.Create(reg2));
                Console.WriteLine(state);
            }
            AsmTestTools.AreEqual(Tv.ONE, state.EqualValues(reg1, reg2));
        }
        public void Test_MemZ3_Forward_Eq3()
        {
            StateConfig stateConfig = new StateConfig();

            stateConfig.Set_All_Off();
            stateConfig.RAX = true;
            stateConfig.RBX = true;
            stateConfig.RCX = true;
            stateConfig.R8  = true;
            stateConfig.Mem = true;

            State   state = this.CreateState(stateConfig);
            Context ctx   = state.Ctx;
            Tools   tools = state.Tools;

            using (StateUpdate updateState = new StateUpdate(state.HeadKey, Tools.CreateKey(tools.Rand), tools))
            {
                updateState.Set(Rn.RBX, 10);
                updateState.Set(Rn.RCX, 5);
                state.Update_Forward(updateState);
            }
            BitVecExpr address1 = Tools.Calc_Effective_Address("qword ptr[rax + 2 * rbx + 10]", state.HeadKey, tools, ctx);
            {
                StateUpdate updateState = new StateUpdate(state.HeadKey, Tools.CreateKey(tools.Rand), tools);
                updateState.Set(Rn.RAX, state.Ctx.MkBVAdd(state.Create(Rn.RAX), state.Ctx.MkBV(0, 64)));
                state.Update_Forward(updateState);
            }
            BitVecExpr address2 = Tools.Calc_Effective_Address("qword ptr[rax + 4 * rcx + 10]", state.HeadKey, tools, ctx);

            BitVecExpr value1 = state.Create(Rn.R8B);
            int        nBytes = (int)value1.SortSize >> 3;

            using (StateUpdate updateState = new StateUpdate(state.HeadKey, Tools.CreateKey(tools.Rand), tools))
            {
                updateState.Set_Mem(address1, value1);
                state.Update_Forward(updateState);
            }
            BitVecExpr value2 = state.Create_Mem(address2, nBytes);

            if (LogToDisplay)
            {
                Console.WriteLine("value1 = " + value1);
                Console.WriteLine("value2 = " + value2);
                Console.WriteLine(state);
            }
            AsmTestTools.AreEqual(Tv.ONE, state.EqualValues(value1, value2));
        }
        public void Test_MemZ3_Forward_Eq4()
        {
            StateConfig stateConfig = new StateConfig();

            stateConfig.Set_All_Off();
            stateConfig.RAX = true;
            stateConfig.RBX = true;
            stateConfig.RCX = true;
            stateConfig.RDX = true;
            stateConfig.Mem = true;

            State   state = this.CreateState(stateConfig);
            Context ctx   = state.Ctx;
            Tools   tools = state.Tools;

            using (StateUpdate updateState = new StateUpdate(state.HeadKey, Tools.CreateKey(tools.Rand), tools))
            {
                updateState.Set(Rn.RAX, state.Create(Rn.RBX));
                state.Update_Forward(updateState);
            }
            BitVecExpr address1 = Tools.Calc_Effective_Address("qword ptr[rax]", state.HeadKey, tools, ctx);
            BitVecExpr address2 = Tools.Calc_Effective_Address("qword ptr[rbx]", state.HeadKey, tools, ctx);

            using (StateUpdate updateState = new StateUpdate(state.HeadKey, Tools.CreateKey(tools.Rand), tools))
            {
                updateState.Set_Mem(address1, state.Create(Rn.RCX));
                state.Update_Forward(updateState);
            }
            using (StateUpdate updateState = new StateUpdate(state.HeadKey, Tools.CreateKey(tools.Rand), tools))
            {
                updateState.Set_Mem(address2, state.Create(Rn.RDX));
                state.Update_Forward(updateState);
            }
            BitVecExpr value1 = state.Create_Mem(address1, 1);
            BitVecExpr value2 = state.Create_Mem(address2, 1);

            if (LogToDisplay)
            {
                Console.WriteLine("value1 = " + value1);
                Console.WriteLine("value2 = " + value2);
                Console.WriteLine(state);
            }
            AsmTestTools.AreEqual(Tv.ONE, state.EqualValues(value1, value2));
        }
Exemple #8
0
        public void Test_BitTricks_Parallel_Search_GPR_2()
        {
            Tools tools = this.CreateTools();

            tools.StateConfig.Set_All_Reg_Off();
            tools.StateConfig.RAX = true;
            tools.StateConfig.RBX = true;
            tools.StateConfig.RCX = true;
            tools.StateConfig.RSP = true;

            string line1 = "mov rax, 0x80_80_80_80_80_80_80_80";
            string line2 = "mov rsp, 0x01_01_01_01_01_01_01_01";

            string line3  = "mov rbx, 0x01_02_03_04_05_06_07_08"; // EBX contains 8 bytes
            string line4a = "mov rcx, rbx";                       // cannot substract with lea, now we need an extra mov
            string line4b = "sub rcx, rsp";                       // substract 1 from each byte
            string line5  = "not rbx";                            // invert all bytes
            string line6  = "and rcx, rbx";                       // and these two
            string line7  = "and rcx, rax";

            { // forward
                State      state = this.CreateState(tools);
                BitVecExpr bytes = state.Create(Rn.RBX);

                state = Runner.SimpleStep_Forward(line1, state);
                state = Runner.SimpleStep_Forward(line2, state);
                if (false)
                {
                    state = Runner.SimpleStep_Forward(line3, state);
                    if (LogToDisplay)
                    {
                        Console.WriteLine("After \"" + line3 + "\", we know:\n" + state);
                    }
                }
                state = Runner.SimpleStep_Forward(line4a, state);
                if (LogToDisplay)
                {
                    Console.WriteLine("After \"" + line4a + "\", we know:\n" + state);
                }

                state = Runner.SimpleStep_Forward(line4b, state);
                if (LogToDisplay)
                {
                    Console.WriteLine("After \"" + line4b + "\", we know:\n" + state);
                }

                state = Runner.SimpleStep_Forward(line5, state);
                if (LogToDisplay)
                {
                    Console.WriteLine("After \"" + line5 + "\", we know:\n" + state);
                }

                state = Runner.SimpleStep_Forward(line6, state);
                if (LogToDisplay)
                {
                    Console.WriteLine("After \"" + line6 + "\", we know:\n" + state);
                }

                state = Runner.SimpleStep_Forward(line7, state);
                if (LogToDisplay)
                {
                    Console.WriteLine("After \"" + line7 + "\", we know:\n" + state);
                }

                {
                    // if at least one of the bytes is equal to zero, then ECX cannot be equal to zero
                    // if ECX is zero, then none of the bytes is equal to zero.
                    Context    ctx   = state.Ctx;
                    BitVecExpr zero8 = ctx.MkBV(0, 8);
                    bytes = bytes.Translate(ctx) as BitVecExpr;

                    BitVecExpr byte1 = ctx.MkExtract((1 * 8) - 1, 0 * 8, bytes);
                    BitVecExpr byte2 = ctx.MkExtract((2 * 8) - 1, 1 * 8, bytes);
                    BitVecExpr byte3 = ctx.MkExtract((3 * 8) - 1, 2 * 8, bytes);
                    BitVecExpr byte4 = ctx.MkExtract((4 * 8) - 1, 3 * 8, bytes);
                    BitVecExpr byte5 = ctx.MkExtract((5 * 8) - 1, 4 * 8, bytes);
                    BitVecExpr byte6 = ctx.MkExtract((6 * 8) - 1, 5 * 8, bytes);
                    BitVecExpr byte7 = ctx.MkExtract((7 * 8) - 1, 6 * 8, bytes);
                    BitVecExpr byte8 = ctx.MkExtract((8 * 8) - 1, 7 * 8, bytes);

                    BoolExpr property = ctx.MkEq(
                        ctx.MkOr(
                            ctx.MkEq(byte1, zero8),
                            ctx.MkEq(byte2, zero8),
                            ctx.MkEq(byte3, zero8),
                            ctx.MkEq(byte4, zero8),
                            ctx.MkEq(byte5, zero8),
                            ctx.MkEq(byte6, zero8),
                            ctx.MkEq(byte7, zero8),
                            ctx.MkEq(byte8, zero8)
                            ),
                        ctx.MkNot(ctx.MkEq(state.Create(Rn.RCX), ctx.MkBV(0, 64)))
                        );
                    AsmTestTools.AreEqual(Tv.ONE, ToolsZ3.GetTv(property, state.Solver, ctx));
                }
            }
        }
Exemple #9
0
        public void Test_BitTricks_Parallel_Search_GPR_1()
        {
            Tools tools = this.CreateTools();

            tools.StateConfig.Set_All_Reg_Off();
            tools.StateConfig.RBX = true;
            tools.StateConfig.RCX = true;
            tools.StateConfig.RDX = true;

            string line1 = "mov ebx, 0x01_00_02_03";        // EBX contains four bytes
            string line2 = "lea ecx, [ebx-0x01_01_01_01]";  // substract 1 from each byte
            string line3 = "not ebx";                       // invert all bytes
            string line4 = "and ecx, ebx";                  // and these two
            string line5 = "and ecx, 80808080h";

            { // forward
                State      state = this.CreateState(tools);
                BitVecExpr bytes = state.Create(Rn.EBX);

                if (false)
                { // line 1
                    state = Runner.SimpleStep_Forward(line1, state);
                    // if (logToDisplay) Console.WriteLine("After \"" + line1 + "\", we know:\n" + state);
                }
                state = Runner.SimpleStep_Forward(line2, state);
                // if (logToDisplay) Console.WriteLine("After \"" + line2 + "\", we know:\n" + state);
                state = Runner.SimpleStep_Forward(line3, state);
                // if (logToDisplay) Console.WriteLine("After \"" + line3 + "\", we know:\n" + state);
                state = Runner.SimpleStep_Forward(line4, state);
                // if (logToDisplay) Console.WriteLine("After \"" + line4 + "\", we know:\n" + state);
                state = Runner.SimpleStep_Forward(line5, state);
                // if (logToDisplay) Console.WriteLine("After \"" + line5 + "\", we know:\n" + state);

                Context    ctx  = state.Ctx;
                BitVecExpr zero = ctx.MkBV(0, 8);
                bytes = bytes.Translate(ctx) as BitVecExpr;
                BitVecExpr byte1 = ctx.MkExtract((1 * 8) - 1, 0 * 8, bytes);
                BitVecExpr byte2 = ctx.MkExtract((2 * 8) - 1, 1 * 8, bytes);
                BitVecExpr byte3 = ctx.MkExtract((3 * 8) - 1, 2 * 8, bytes);
                BitVecExpr byte4 = ctx.MkExtract((4 * 8) - 1, 3 * 8, bytes);

                {
                    // if at least one of the bytes is equal to zero, then ECX cannot be equal to zero
                    // if ECX is zero, then none of the bytes is equal to zero.

                    BoolExpr property = ctx.MkEq(
                        ctx.MkOr(
                            ctx.MkEq(byte1, zero),
                            ctx.MkEq(byte2, zero),
                            ctx.MkEq(byte3, zero),
                            ctx.MkEq(byte4, zero)
                            ),
                        ctx.MkNot(ctx.MkEq(state.Create(Rn.ECX), ctx.MkBV(0, 32)))
                        );
                    AsmTestTools.AreEqual(Tv.ONE, ToolsZ3.GetTv(property, state.Solver, state.Ctx));
                }
                {
                    state.Solver.Push();
                    BoolExpr p = ctx.MkOr(ctx.MkEq(byte1, zero), ctx.MkEq(byte2, zero), ctx.MkEq(byte3, zero), ctx.MkEq(byte4, zero));
                    state.Solver.Assert(p);
                    if (LogToDisplay)
                    {
                        Console.WriteLine("After \"" + p + "\", we know:\n" + state);
                    }

                    state.Solver.Pop();
                }
                {
                    state.Solver.Push();
                    BoolExpr p = ctx.MkAnd(
                        ctx.MkEq(ctx.MkEq(byte1, zero), ctx.MkFalse()),
                        ctx.MkEq(ctx.MkEq(byte2, zero), ctx.MkFalse()),
                        ctx.MkEq(ctx.MkEq(byte3, zero), ctx.MkTrue()),
                        ctx.MkEq(ctx.MkEq(byte4, zero), ctx.MkFalse())
                        );
                    state.Solver.Assert(p);
                    if (LogToDisplay)
                    {
                        Console.WriteLine("After \"" + p + "\", we know:\n" + state);
                    }
                    // state.Solver.Pop();
                }
            }
        }
Exemple #10
0
        public void Test_DynamicFlow_Forward_1()
        {
            Tools tools = this.CreateTools();

            tools.StateConfig.Set_All_Off();
            tools.StateConfig.RAX      = true;
            tools.StateConfig.RBX      = true;
            tools.Quiet                = true;
            tools.ShowUndefConstraints = false;

            string programStr =
                "           mov     rax,        0       ; line 0        " + Environment.NewLine +
                "           mov     rbx,        10      ; line 1        " + Environment.NewLine +
                "           mov     rbx,        rax     ; line 2        ";
            StaticFlow sFlow = new StaticFlow(tools);

            sFlow.Update(programStr);
            if (LogToDisplay)
            {
                Console.WriteLine(sFlow);
            }

            if (true)
            {
                DynamicFlow dFlow = Runner.Construct_DynamicFlow_Forward(sFlow, tools);
                if (LogToDisplay)
                {
                    Console.WriteLine(dFlow.ToString(sFlow));
                }

                {
                    int           lineNumber    = 0;
                    IList <State> states_Before = new List <State>(dFlow.Create_States_Before(lineNumber));
                    Assert.AreEqual(1, states_Before.Count);
                    State state_Before = states_Before[0];

                    IList <State> states_After = new List <State>(dFlow.Create_States_After(lineNumber));
                    Assert.AreEqual(1, states_After.Count);
                    State state_After = states_After[0];

                    if (LogToDisplay)
                    {
                        Console.WriteLine("Tree_Forward: Before lineNumber " + lineNumber + " \"" + sFlow.Get_Line_Str(lineNumber) + "\", we know:\n" + state_Before);
                    }

                    AsmTestTools.AreEqual(Rn.RAX, "????????.????????.????????.????????.????????.????????.????????.????????", state_Before);
                    AsmTestTools.AreEqual(Rn.RBX, "????????.????????.????????.????????.????????.????????.????????.????????", state_Before);

                    if (LogToDisplay)
                    {
                        Console.WriteLine("Tree_Forward: After lineNumber " + lineNumber + " \"" + sFlow.Get_Line_Str(lineNumber) + "\", we know:\n" + state_After);
                    }

                    AsmTestTools.AreEqual(Rn.RAX, 0, state_After);
                    AsmTestTools.AreEqual(Rn.RBX, "????????.????????.????????.????????.????????.????????.????????.????????", state_After);
                }
                {
                    int           lineNumber    = 1;
                    IList <State> states_Before = new List <State>(dFlow.Create_States_Before(lineNumber));
                    Assert.AreEqual(1, states_Before.Count);
                    State state_Before = states_Before[0];

                    IList <State> states_After = new List <State>(dFlow.Create_States_After(lineNumber));
                    Assert.AreEqual(1, states_After.Count);
                    State state_After = states_After[0];

                    if (LogToDisplay)
                    {
                        Console.WriteLine("Tree_Forward: Before lineNumber " + lineNumber + " \"" + sFlow.Get_Line_Str(lineNumber) + "\", we know:\n" + state_Before);
                    }

                    AsmTestTools.AreEqual(Rn.RAX, 0, state_Before);
                    AsmTestTools.AreEqual(Rn.RBX, "????????.????????.????????.????????.????????.????????.????????.????????", state_Before);

                    if (LogToDisplay)
                    {
                        Console.WriteLine("Tree_Forward: After lineNumber " + lineNumber + " \"" + sFlow.Get_Line_Str(lineNumber) + "\", we know:\n" + state_After);
                    }

                    AsmTestTools.AreEqual(Rn.RAX, 0, state_After);
                    AsmTestTools.AreEqual(Rn.RBX, 10, state_After);
                }
                {
                    int           lineNumber    = 2;
                    IList <State> states_Before = new List <State>(dFlow.Create_States_Before(lineNumber));
                    Assert.AreEqual(1, states_Before.Count);
                    State state_Before = states_Before[0];

                    IList <State> states_After = new List <State>(dFlow.Create_States_After(lineNumber));
                    Assert.AreEqual(1, states_After.Count);
                    State state_After = states_After[0];

                    if (LogToDisplay)
                    {
                        Console.WriteLine("Tree_Forward: Before lineNumber " + lineNumber + " \"" + sFlow.Get_Line_Str(lineNumber) + "\", we know:\n" + state_Before);
                    }

                    AsmTestTools.AreEqual(Rn.RAX, 0, state_Before);
                    AsmTestTools.AreEqual(Rn.RBX, 10, state_Before);

                    if (LogToDisplay)
                    {
                        Console.WriteLine("Tree_Forward: After lineNumber " + lineNumber + " \"" + sFlow.Get_Line_Str(lineNumber) + "\", we know:\n" + state_After);
                    }

                    AsmTestTools.AreEqual(Rn.RAX, 0, state_After);
                    AsmTestTools.AreEqual(Rn.RBX, 0, state_After);
                }
            }
        }