示例#1
0
        public void Set_Mem(BitVecExpr address, BitVecExpr value, BitVecExpr undef)
        {
            this.Empty = false;

            lock (this._ctxLock)
            {
                Context ctx = this._ctx;
                address = address.Translate(ctx) as BitVecExpr;
                value   = value.Translate(ctx) as BitVecExpr;
                undef   = undef.Translate(ctx) as BitVecExpr;

                ArrayExpr newMemContent   = Tools.Set_Value_To_Mem(value, address, this._prevKey_Regular, ctx);
                ArrayExpr newMemContent_U = Tools.Set_Value_To_Mem(undef, address, this._prevKey_Regular, ctx);
                ArrayExpr memKey          = Tools.Create_Mem_Key(this.NextKey, ctx);

                //Console.WriteLine("SetMem: memKey=" + memKey + "; new Value=" + newMemContent);
                if (this._mem_Update != null)
                {
                    Console.WriteLine("WARNING: StateUpdate:SetMem: multiple memory updates are not allowed");
                    //throw new Exception("Multiple memory updates are not allowed");
                }
                this._mem_Update   = ctx.MkEq(memKey, newMemContent);
                this._mem_Update_U = ctx.MkEq(memKey, newMemContent_U);
            }
        }
示例#2
0
        public void Set_SF_ZF_PF(BitVecExpr value)
        {
            Debug.Assert(value != null);
            this.Empty = false;

            lock (this._ctxLock)
            {
                Context ctx = this._ctx;
                value = value.Translate(ctx) as BitVecExpr;
                this.Set(Flags.SF, ToolsFlags.Create_SF(value, value.SortSize, ctx));
                this.Set(Flags.ZF, ToolsFlags.Create_ZF(value, ctx));
                this.Set(Flags.PF, ToolsFlags.Create_PF(value, ctx));
            }
        }
示例#3
0
        public void Set_SF_ZF_PF(BitVecExpr value)
        {
            Contract.Requires(value != null);
            this.Empty = false;

            lock (this.ctxLock_)
            {
                Context ctx = this.ctx_;
                value = value.Translate(ctx) as BitVecExpr;
                this.Set(Flags.SF, ToolsFlags.Create_SF(value, value.SortSize, ctx));
                this.Set(Flags.ZF, ToolsFlags.Create_ZF(value, ctx));
                this.Set(Flags.PF, ToolsFlags.Create_PF(value, ctx));
            }
        }
示例#4
0
        public void Set(Rn reg, BitVecExpr value, BitVecExpr undef)
        {
            Debug.Assert(value != null);
            Debug.Assert(undef != null);

            this.Empty = false;

            lock (this._ctxLock)
            {
                Context ctx = this._ctx;

                value = value.Translate(ctx) as BitVecExpr;
                undef = undef.Translate(ctx) as BitVecExpr;


                if (RegisterTools.IsGeneralPurposeRegister(reg))
                {
                    Rn   reg64 = RegisterTools.Get64BitsRegister(reg);
                    uint nBits = value.SortSize;
                    switch (nBits)
                    {
                    case 64: break;

                    case 32:
                    {
                        value = ctx.MkZeroExt(32, value);
                        undef = ctx.MkZeroExt(32, undef);
                        break;
                    }

                    case 16:
                    {
                        BitVecExpr reg64Expr = Tools.Create_Key(reg64, this._prevKey_Regular, ctx);
                        BitVecExpr prefix    = ctx.MkExtract(63, 16, reg64Expr);
                        value = ctx.MkConcat(prefix, value);
                        undef = ctx.MkConcat(prefix, undef);
                        break;
                    }

                    case 8:
                    {
                        BitVecExpr reg64Expr = Tools.Create_Key(reg64, this._prevKey_Regular, ctx);
                        if (RegisterTools.Is8BitHigh(reg))
                        {
                            BitVecExpr postFix = ctx.MkExtract(7, 0, reg64Expr);
                            BitVecExpr prefix  = ctx.MkExtract(63, 16, reg64Expr);
                            value = ctx.MkConcat(ctx.MkConcat(prefix, value), postFix);
                            undef = ctx.MkConcat(ctx.MkConcat(prefix, undef), postFix);
                        }
                        else
                        {
                            BitVecExpr prefix = ctx.MkExtract(63, 8, reg64Expr);
                            value = ctx.MkConcat(prefix, value);
                            undef = ctx.MkConcat(prefix, undef);
                        }
                        break;
                    }

                    default:
                    {
                        Console.WriteLine("ERROR: Set: bits=" + nBits + "; value=" + value + "; undef=" + undef);
                        throw new Exception();
                    }
                    }
                    {
                        BitVecExpr key = Tools.Create_Key(reg64, this.NextKey, ctx);
                        BoolExpr   value_Constraint = ctx.MkEq(key, value) as BoolExpr;
                        BoolExpr   undef_Constraint = ctx.MkEq(key, undef) as BoolExpr;

                        if (this.Get_Raw_Private(reg64, false) != null)
                        {
                            throw new Exception("Multiple assignments to register " + reg64);
                        }

                        this.Set_Private(reg64, value_Constraint, false);
                        this.Set_Private(reg64, undef_Constraint, true);
                    }
                }
                else if (RegisterTools.Is_SIMD_Register(reg))
                {
                    uint max = 512 * 32;

                    BitVecExpr prevKey = ctx.MkBVConst(Tools.Reg_Name(reg, this._prevKey_Regular), max);
                    (uint High, uint Low) = Tools.SIMD_Extract_Range(reg);


                    BitVecExpr top    = null;
                    BitVecExpr bottom = null;
                    if (High < (max - 1))
                    {
                        top = ctx.MkExtract(max - 1, High + 1, prevKey);
                    }

                    if (Low > 0)
                    {
                        bottom = ctx.MkExtract(Low - 1, 0, prevKey);
                    }

                    Console.WriteLine(top.SortSize + "+" + value.SortSize + "+" + bottom.SortSize + "=" + prevKey.SortSize);


                    BitVecExpr newValue = (top == null) ? value : ctx.MkConcat(top, value) as BitVecExpr;
                    newValue = (bottom == null) ? newValue : ctx.MkConcat(newValue, bottom);
                    BitVecExpr newUndef = (top == null) ? value : ctx.MkConcat(top, value) as BitVecExpr;
                    newUndef = (bottom == null) ? newUndef : ctx.MkConcat(newUndef, bottom);

                    BitVecExpr nextKey = ctx.MkBVConst(Tools.Reg_Name(reg, this.NextKey), 512 * 32);
                    //Debug.Assert(newValue.SortSize == nextKey.SortSize);

                    this._simd   = ctx.MkEq(nextKey, newValue);
                    this._simd_U = ctx.MkEq(nextKey, newUndef);
                }
                else
                {
                    // do nothing;
                }
            }
        }
示例#5
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));
                }
            }
        }
示例#6
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();
                }
            }
        }
示例#7
0
        public void Test_BitTricks_Min_Unsigned()
        {
            Tools tools = this.CreateTools();

            tools.StateConfig.Set_All_Reg_Off();
            tools.StateConfig.RAX = true;
            tools.StateConfig.RBX = true;
            tools.StateConfig.RDX = true;
            tools.StateConfig.CF  = true;

            string line1 = "sub rax, rbx";
            string line2 = "sbb rdx, rdx"; // copy CF to all bits of edx
            string line3 = "and rdx, rax";
            string line4 = "add rbx, rdx";

            { // forward
                State state = this.CreateState(tools);

                BitVecExpr rax0 = state.Create(Rn.RAX);
                BitVecExpr rbx0 = state.Create(Rn.RBX);

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

                // ebx is minimum of ebx and eax
                Context    ctx  = state.Ctx;
                BitVecExpr rbx1 = state.Create(Rn.RBX);
                rax0 = rax0.Translate(ctx) as BitVecExpr;
                rbx0 = rbx0.Translate(ctx) as BitVecExpr;
                BoolExpr t = ctx.MkEq(rbx1, ctx.MkITE(ctx.MkBVUGT(rax0, rbx0), rbx0, rax0));

                {
                    state.Solver.Push();
                    state.Solver.Assert(t);
                    if (state.Solver.Check() != Status.SATISFIABLE)
                    {
                        if (LogToDisplay)
                        {
                            Console.WriteLine("UnsatCore has " + state.Solver.UnsatCore.Length + " elements");
                        }

                        foreach (BoolExpr b in state.Solver.UnsatCore)
                        {
                            if (LogToDisplay)
                            {
                                Console.WriteLine("UnsatCore=" + b);
                            }
                        }
                        Assert.Fail();
                    }
                    state.Solver.Pop();
                }
                {
                    state.Solver.Push();
                    state.Solver.Assert(ctx.MkNot(t));
                    if (state.Solver.Check() == Status.SATISFIABLE)
                    {
                        if (LogToDisplay)
                        {
                            Console.WriteLine("Model=" + state.Solver.Model);
                        }

                        Assert.Fail();
                    }
                    state.Solver.Pop();
                }
                Assert.AreEqual(Tv.ONE, ToolsZ3.GetTv(t, state.Solver, state.Ctx));
            }
        }