Example #1
0
        private static BoolExpr CreateModel(Context ctx, uint ec, uint pid, bool shiny, out BitVecExpr s0)
        {
            s0 = ctx.MkBVConst("s0", 64);
            BitVecExpr s1 = ctx.MkBV(Xoroshiro128Plus.XOROSHIRO_CONST, 64);

            var and_val   = ctx.MkBV(0xFFFFFFFF, 64);
            var and_val16 = ctx.MkBV(0xFFFF, 64);
            var bit16     = ctx.MkBV(1 << 16, 64);
            var comp_with = ctx.MkBV(0xF, 64);

            var real_ec  = ctx.MkBV(ec, 64);
            var real_pid = ctx.MkBV(pid, 64);

            var ec_check  = AdvanceSymbolic(ctx, ref s0, ref s1);
            var tidsid    = AdvanceSymbolic(ctx, ref s0, ref s1);
            var pid_check = AdvanceSymbolic(ctx, ref s0, ref s1);

            var exp = ctx.MkEq(ec_check, real_ec);

            if (shiny)
            {
                exp = ctx.MkAnd(exp, ctx.MkEq(ctx.MkBVAND(pid_check, and_val16), ctx.MkBVAND(real_pid, and_val16)));
                var st  = ctx.MkBVAND(tidsid, and_val);
                var tsv = ctx.MkBVXOR(ctx.MkBVUDiv(st, bit16), ctx.MkBVAND(st, and_val16));
                var psv = ctx.MkBVXOR(ctx.MkBVUDiv(pid_check, bit16), ctx.MkBVAND(pid_check, and_val16));
                return(ctx.MkAnd(exp, ctx.MkBVSLE(ctx.MkBVXOR(tsv, psv), comp_with)));
            }
            else
            {
                return(ctx.MkAnd(exp, ctx.MkEq(pid_check, real_pid)));
            }
        }
Example #2
0
 public static BitVecExpr GetBit_BV(BitVecExpr value, BitVecExpr pos, Context ctx)
 {
     return(ctx.MkExtract(0, 0, ctx.MkBVLSHR(value, pos)));
 }
Example #3
0
        public static (BitVecExpr result, BoolExpr cf) ShiftOperations(
            Mnemonic op,
            BitVecExpr value,
            BitVecExpr nShifts,
            Context ctx,
            Random rand)
        {
            Debug.Assert(nShifts.SortSize == 8);

            BitVecExpr value_out;

            BitVecNum  one     = ctx.MkBV(1, 8);
            BitVecExpr nBitsBV = ctx.MkBV(value.SortSize, 8);
            BitVecExpr bitPos;
            BitVecExpr nShifts64 = ctx.MkZeroExt(value.SortSize - 8, nShifts);

            switch (op)
            {
            case Mnemonic.SHR:
            {
                bitPos    = ctx.MkBVSub(nShifts, one);
                value_out = ctx.MkBVLSHR(value, nShifts64);
            }
            break;

            case Mnemonic.SAR:
            {
                bitPos    = ctx.MkBVSub(nShifts, one);
                value_out = ctx.MkBVASHR(value, nShifts64);
            }
            break;

            case Mnemonic.ROR:
            {
                bitPos    = ctx.MkBVSub(nShifts, one);
                value_out = ctx.MkBVRotateRight(value, nShifts64);
            }
            break;

            case Mnemonic.SHL:     // SHL and SAL are equal in functionality
            case Mnemonic.SAL:
            {
                bitPos = ctx.MkBVSub(nBitsBV, nShifts);
                //Console.WriteLine("BitOperations:SHL: bitPos=" + bitPos.Simplify());
                value_out = ctx.MkBVSHL(value, nShifts64);
            }
            break;

            case Mnemonic.ROL:
            {
                bitPos    = ctx.MkBVSub(nBitsBV, nShifts);
                value_out = ctx.MkBVRotateLeft(value, nShifts64);
            }
            break;

            default: throw new Exception();
            }
            bitPos = ctx.MkZeroExt(value.SortSize - 8, bitPos);
            BoolExpr bitValue = ToolsZ3.GetBit(value, bitPos, ctx);

            BoolExpr CF_undef = Tools.Create_Flag_Key_Fresh(Flags.CF, rand, ctx);
            BoolExpr cf       = ctx.MkITE(ctx.MkEq(nShifts, ctx.MkBV(0, 8)), CF_undef, bitValue) as BoolExpr;

            return(result : value_out, cf : cf);
        }
Example #4
0
 public static BoolExpr GetBit(BitVecExpr value, uint pos, BitVecNum one, Context ctx)
 {
     Debug.Assert(one.SortSize == 1);
     Debug.Assert(one.Int == 1);
     return(ctx.MkEq(GetBit_BV(value, pos, ctx), one));
 }
Example #5
0
 public static Tv[] GetTvArray(BitVecExpr value, int nBits, Solver solver, Solver solver_U, Context ctx)
 {
     return(GetTvArray(value, value, nBits, solver, solver_U, ctx));
 }
Example #6
0
 private bool IsGrounded(BitVecExpr value, Solver solver, Context ctx)
 {
     return(ToolsZ3.GetUlong(value, value.SortSize, solver, ctx) != null);
 }
        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();
                }
            }
        }
Example #8
0
        public void Set_Mem(BitVecExpr address, Tv[] value)
        {
            var tup = ToolsZ3.MakeVecExpr(value, this._ctx);

            this.Set_Mem(address, tup.value, tup.undef);
        }
Example #9
0
 public void Set_Mem(BitVecExpr address, BitVecExpr value)
 {
     this.Set_Mem(address, value, value);
 }
Example #10
0
        public void Set_Mem(BitVecExpr address, ulong value, int nBytes)
        {
            BitVecExpr valueExpr = this._ctx.MkBV(value, (uint)nBytes << 3);

            this.Set_Mem(address, valueExpr);
        }
Example #11
0
 public void Set_Mem(BitVecExpr address, string value)
 {
     this.Set_Mem(address, ToolsZ3.GetTvArray(value));
 }
Example #12
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);
                    var(High, 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;
                }
            }
        }
Example #13
0
 public void Set(Rn reg, BitVecExpr value)
 {
     this.Set(reg, value, value);
 }
Example #14
0
        public void Set(Rn reg, ulong value)
        {
            BitVecExpr valueExpr = this._ctx.MkBV(value, (uint)RegisterTools.NBits(reg));

            this.Set(reg, valueExpr, valueExpr);
        }
Example #15
0
        private void AddInstruction_Xor(Rn reg1, Rn reg2, int lineNumber)
        {
            Context ctx = this._ctx;
            string  asm = "XOR_" + reg1 + "_" + reg2;

            int      ln0 = lineNumber - 1;
            int      ln1 = lineNumber;
            BoolExpr instruction_Switch = ctx.MkBoolConst("L" + lineNumber + "_" + asm);

            this._switches[lineNumber].Add(instruction_Switch);

            if (true)
            {
                BitVecExpr x = ctx.MkBVXOR(GetReg(Rn.RAX, ln0, ctx), GetReg(reg2, ln0, ctx));
                this._solver.Assert(ctx.MkImplies(
                                        instruction_Switch,
                                        MakeRuleRegResult(reg1, this._registers, x, lineNumber, ctx)
                                        ));


                if (reg1 == reg2)
                {
                    this._solver.Assert(ctx.MkImplies(
                                            instruction_Switch,
                                            ctx.MkAnd(
                                                //GetRegGoal(reg1, ln0, ctx), // rax0_goal is irelevant
                                                GetRegGoal(reg1, ln1, ctx),    // make application of this rule goal directed
                                                //GetRegProvided(reg1, ln0, ctx), // TODO: could this create inconsistencies with other instructions that updated rax!0
                                                GetRegProvided(reg1, ln1, ctx) // rax1 is not based on (variable) input but is a constant
                                                )
                                            ));
                }
                else
                {
                }
            }

            if (false)
            {
                BitVecExpr x           = ctx.MkBVXOR(GetReg(Rn.RAX, ln0, ctx), GetReg(reg2, ln0, ctx));
                BoolExpr   newRegState = MakeRuleRegResult(reg1, this._registers, x, lineNumber, ctx);

                BoolExpr newFlagState = ctx.MkAnd(
                    SetFlag(Flags.OF, Tv.ZERO, lineNumber, ctx),
                    SetFlag(Flags.CF, Tv.ZERO, lineNumber, ctx),
                    SetFlag(Flags.AF, Tv.UNDEFINED, lineNumber, ctx),

                    ZeroFlag(reg1, lineNumber, ctx),
                    SignFlag(reg1, lineNumber, ctx),
                    OverFlowFlag(reg1, lineNumber, ctx)
                    );
                // this._solver.Assert(ctx.MkImplies(instruction_Switch, newFlagState));
                this._solver.Assert(ctx.MkImplies(instruction_Switch, newRegState));
            }
            if (false)
            {
                BoolExpr newState = ctx.MkAnd(
                    ctx.MkEq(GetRegKnown(Rn.RAX, ln1, ctx), (reg1 == Rn.RAX) ? GetRegKnown(reg2, ln0, ctx) : GetRegKnown(Rn.RAX, ln0, ctx)),
                    ctx.MkEq(GetRegKnown(Rn.RBX, ln1, ctx), (reg1 == Rn.RBX) ? GetRegKnown(reg2, ln0, ctx) : GetRegKnown(Rn.RBX, ln0, ctx)),
                    ctx.MkEq(GetRegKnown(Rn.RCX, ln1, ctx), (reg1 == Rn.RCX) ? GetRegKnown(reg2, ln0, ctx) : GetRegKnown(Rn.RCX, ln0, ctx)),
                    ctx.MkEq(GetRegKnown(Rn.RDX, ln1, ctx), (reg1 == Rn.RDX) ? GetRegKnown(reg2, ln0, ctx) : GetRegKnown(Rn.RDX, ln0, ctx)),
                    ZeroFlag(reg1, lineNumber, ctx),
                    OverFlowFlag(reg1, lineNumber, ctx)
                    );
                this._solver.Assert(ctx.MkImplies(instruction_Switch, newState));
                //this._solver.Assert(ctx.MkImplies(instruction_Switch, IsKnownTest(reg1, ln0, ctx)));
                //this._solver.Assert(ctx.MkImplies(instruction_Switch, IsKnownTest(reg2, ln0, ctx)));
            }
        }
Example #16
0
 public void Set(Operand operand, BitVecExpr value)
 {
     this.Set(operand, value, value);
 }
Example #17
0
        public void Run()
        {
            Context ctx = this._ctx;

            #region Fill Solver
            for (int lineNumber = 1; lineNumber <= this._nLines; ++lineNumber)
            {
                //this.AddInstruction_Shl(lineNumber);

                foreach (Rn reg1 in this._registers)
                {
                    foreach (Rn reg2 in this._registers)
                    {
                        //this.AddInstruction_Add(reg1, reg2, lineNumber);
                        //this.AddInstruction_Sub(reg1, reg2, lineNumber);
                        //this.AddInstruction_Mov(reg1, reg2, lineNumber);
                        this.AddInstruction_Xor(reg1, reg2, lineNumber);
                    }
                    this.AddInstruction_Inc(reg1, lineNumber);
                    //this.AddInstruction_Dec(reg1, lineNumber);
                    //this.AddInstruction_Mov(reg1, lineNumber);
                }
                this.AddInstruction_Nop(lineNumber);

                BoolExpr[] switches_line = this._switches[lineNumber].ToArray();
                this._solver.Assert(ctx.MkAtMost(switches_line, 1));
                this._solver.Assert(ctx.MkOr(switches_line));
            }

            // assume all registers are initially unknown
            foreach (Rn reg in this._registers)
            {
                //this._solver.Assert(ctx.MkEq(GetRegKnown(reg, 0, ctx), MakeUnknownConst(reg, ctx)));
            }
            #endregion

            #region Add Target Constains

            // rax_1: negate the lowest bit
            BitVecExpr rax_1 = ctx.MkConcat(ctx.MkExtract(63, 1, GetReg(Rn.RAX, 0, ctx)), ctx.MkBVNeg(ctx.MkExtract(0, 0, GetReg(Rn.RAX, 0, ctx))));
            // rax_2: add 1
            BitVecExpr rax_2 = ctx.MkBVAdd(GetReg(Rn.RAX, 0, ctx), ctx.MkBV(1, 64));
            // rax_3: constant 32
            BitVecExpr rax_3 = ctx.MkBV(32, 64);

            BitVecExpr rax_n = GetReg(Rn.RAX, this._nLines, ctx);
            BitVecExpr rax_0 = GetReg(Rn.RAX, 0, ctx);

            if (true)
            {
                if (true)
                {   // increment rax with 1
                    this._solver.Assert(ctx.MkEq(rax_n, ctx.MkBVAdd(GetReg(Rn.RAX, 0, ctx), ctx.MkBV(1, 64))));
                    this._solver.Assert(GetRegGoal(Rn.RAX, this._nLines, ctx));
                    this._solver.Assert(ctx.MkNot(GetRegProvided(Rn.RAX, 0, ctx)));
                    this._solver.Assert(GetRegProvided(Rn.RAX, this._nLines, ctx));
                }
                else
                {   // set rax to constant 32
                    this._solver.Assert(ctx.MkEq(rax_n, ctx.MkBV(0, 64)));
                    this._solver.Assert(GetRegGoal(Rn.RAX, this._nLines, ctx));
                    this._solver.Assert(ctx.MkNot(GetRegProvided(Rn.RAX, 0, ctx)));
                    this._solver.Assert(GetRegProvided(Rn.RAX, this._nLines, ctx));
                }
            }
            else
            {
                this._solver.Assert(ctx.MkEq(rax_n, rax_2));
                this._solver.Assert(IsKnownTest(Rn.RAX, this._nLines, ctx));
            }

            #endregion

            Console.WriteLine(ToString(this._solver));
            if (this._solver.Check() == Status.SATISFIABLE)
            {
                this.GetAllModels(this._solver, ctx);
            }
            else
            {
                Console.WriteLine("INFO: No code exists that implements the target constraints.");
                foreach (BoolExpr b in this._solver.UnsatCore)
                {
                    Console.WriteLine(b);
                }
            }
        }
Example #18
0
 public static BoolExpr Create_ZF(BitVecExpr value, Context ctx)
 {
     Contract.Requires(value != null, "BitVecExpr value cannot be null");
     Contract.Requires(ctx != null, "Context cannot be null");
     return(ctx.MkEq(value, ctx.MkBV(0, value.SortSize)));
 }
        public void Test_BitTricks_Min_Signed()
        {
            Tools tools = this.CreateTools();

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

            return;                        // this trick does not seem to be correct?!

            string line1 = "sub rax, rbx"; // Will not work if overflow here!
            string line2 = "cqo";          // rdx1 = (rax0 > rbx0) ? -1 : 0
            string line3 = "and rdx, rax"; // rdx2 = (rax0 > rbx0) ? 0 : (rax0 - rbx0)
            string line4 = "add rbx, rdx"; // rbx1 = (rax0 > rbx0) ? (rbx0 + 0) : (rbx0 + rax0 - rbx0)

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

                if (true)
                {
                    ulong       rax_value   = 0x61a4292198602827;
                    ulong       rbx_value   = 0x8739140220c24080;
                    StateUpdate updateState = new StateUpdate("!PREVKEY", "!NEXTKEY", state.Tools);
                    updateState.Set(Rn.RAX, rax_value);
                    updateState.Set(Rn.RBX, rbx_value);
                    state.Update_Forward(updateState);
                    if (LogToDisplay)
                    {
                        Console.WriteLine("Initially, we know:\n" + state);
                    }
                }

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

                {
                    state.Solver.Assert(state.Ctx.MkNot(ToolsFlags.Create_OF_Sub(rax0, rbx0, rax0.SortSize, ctx))); // this code only works when there is no overflow in line1
                }
                {                                                                                                   // line 1
                    state = Runner.SimpleStep_Forward(line1, state);
                    // retrieve the overflow after line 1, OF has to be zero for the code to work
                    state.Solver.AssertAndTrack(ctx.MkNot(state.Create(Flags.OF)), ctx.MkBoolConst("OF-ZERO"));
                    Assert.AreEqual(Status.SATISFIABLE, state.Solver.Check());
                    if (LogToDisplay)
                    {
                        Console.WriteLine("After \"" + line1 + "\", we know:\n" + state);
                    }
                }
                { // line 2
                    state = Runner.SimpleStep_Forward(line2, state);
                    // if (logToDisplay) Console.WriteLine("After \"" + line2 + "\", we know:\n" + state);
                    BoolExpr t2 = ctx.MkEq(state.Create(Rn.RDX), ctx.MkITE(ctx.MkBVSGT(rax0, rbx0), ctx.MkBV(0xFFFF_FFFF_FFFF_FFFF, 64), ctx.MkBV(0, 64)));
                    // Assert.AreEqual(Tv5.ONE, ToolsZ3.GetTv5(t2, state.Solver, state.Ctx));
                }
                {
                    state = Runner.SimpleStep_Forward(line3, state);
                    // if (logToDisplay) Console.WriteLine("After \"" + line3 + "\", we know:\n" + state);
                    // BoolExpr t2 = ctx.MkEq(state.Get(Rn.RDX), ctx.MkITE(ctx.MkBVSGT(rax0, rbx0), ctx.MkBV(0, 64), ctx.MkBVSub(rax0, rbx0)));
                    // Assert.AreEqual(Tv5.ONE, ToolsZ3.GetTv5(t2, state.Solver, state.Ctx));
                }
                {
                    state = Runner.SimpleStep_Forward(line4, state);
                    if (LogToDisplay)
                    {
                        Console.WriteLine("After \"" + line4 + "\", we know:\n" + state);
                    }
                }

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

                if (false)
                {
                    state.Solver.Push();
                    state.Solver.AssertAndTrack(t, ctx.MkBoolConst("MIN_RAX_RBX"));
                    Status s = state.Solver.Check();
                    if (LogToDisplay)
                    {
                        Console.WriteLine("Status A = " + s + "; expected " + Status.SATISFIABLE);
                    }

                    if (s == Status.UNSATISFIABLE)
                    {
                        if (LogToDisplay)
                        {
                            Console.WriteLine("UnsatCore has " + state.Solver.UnsatCore.Length + " elements");
                        }

                        foreach (BoolExpr b in state.Solver.UnsatCore)
                        {
                            if (LogToDisplay)
                            {
                                Console.WriteLine("UnsatCore=" + b);
                            }
                        }

                        if (LogToDisplay)
                        {
                            Console.WriteLine(state.Solver);
                        }

                        Assert.Fail();
                    }
                    state.Solver.Pop();
                }
                if (true)
                {
                    state.Solver.Push();
                    state.Solver.Assert(ctx.MkNot(t), ctx.MkBoolConst("NOT_MIN_RAX_RBX"));
                    Status s = state.Solver.Check();
                    if (LogToDisplay)
                    {
                        Console.WriteLine("Status B = " + s + "; expected " + Status.UNSATISFIABLE);
                    }

                    if (s == 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));
            }
        }
Example #20
0
 public static BoolExpr Create_OF_Mul(BitVecExpr a, BitVecExpr b, uint nBits, Context ctx)
 {
     //return ctx.MkNot(ctx.MkBVMulNoOverflow(a, b, true));
     Contract.Requires(ctx != null, "State Context cannot be null");
     return(Create_OF(a, b, ctx.MkBVMul(a, b), nBits, ctx));
 }
        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));
                }
            }
        }
Example #22
0
 public static void AreEqual(BitVecExpr expr, ulong expected, State state)
 {
     Tv[] expectedTvArray = ToolsZ3.GetTvArray(expected, (int)expr.SortSize);
     Assert.IsNotNull(expectedTvArray);
     TestTools.AreEqual(expr, expectedTvArray, state);
 }
Example #23
0
 public static BitVecExpr GetBit_BV(BitVecExpr value, uint pos, Context ctx)
 {
     Debug.Assert(ctx != null, "Context ctx cannot be null");
     Debug.Assert(value != null, "BitVecExpr v cannot be null");
     return(ctx.MkExtract(pos, pos, value));
 }
Example #24
0
 public static void AreEqual(BitVecExpr expr, string expected, State state)
 {
     Tv[] expectedTvArray = ToolsZ3.GetTvArray(expected);
     Assert.AreEqual(expr.SortSize, (uint)expectedTvArray.Length);
     TestTools.AreEqual(expr, expectedTvArray, state);
 }
Example #25
0
 public static BoolExpr GetBit(BitVecExpr value, BitVecExpr pos, Context ctx)
 {
     return(ctx.MkEq(GetBit_BV(value, pos, ctx), ctx.MkBV(1, 1)));
 }
Example #26
0
 private static BoolExpr IsKnownTest(BitVecExpr expr, Context ctx)
 {
     //return ctx.MkITE(ctx.MkEq(expr, MakeKnownConst((int)expr.SortSize, ctx)), ctx.MkTrue(), ctx.MkEq(ctx.MkTrue(), ctx.MkFalse())) as BoolExpr;
     return(ctx.MkImplies(ctx.MkNot(ctx.MkEq(expr, MakeKnownConst((int)expr.SortSize, ctx))), ctx.MkEq(ctx.MkTrue(), ctx.MkFalse())));
 }
Example #27
0
        public static BitVecExpr Calc_Effective_Address(Operand op, string key, Context ctx)
        {
            Contract.Requires(op != null);
            Contract.Requires(ctx != null);

            uint nBitsOperand = (uint)op.NBits;
            uint nBitsAddress = 64;

            if (op.IsReg)
            {
                return(Create_Key(op.Rn, key, ctx));
            }
            else if (op.IsMem)
            {
                //Console.WriteLine("INFO: MemZ3:Calc_Effective_Address: operand=" + op);

                (Rn baseReg, Rn indexReg, int scale, long displacement1) = op.Mem;
                //Console.WriteLine(string.Format(AsmDudeToolsStatic.CultureUI, "INFO: Calc_Effective_Address: base={0}; index={1}; scale={2}; disp={3}", t.Item1, t.Item2, t.Item3, t.Item4));

                BitVecExpr address = null;
                //Offset = Base + (Index * Scale) + Displacement

                //1] set the address to the value of the displacement
                if (displacement1 != 0)
                {
                    BitVecNum displacement = ctx.MkBV(displacement1, nBitsAddress);
                    address = displacement;
                    //Console.WriteLine(string.Format(AsmDudeToolsStatic.CultureUI, "INFO: MemZ3:Calc_Effective_Address: A: address={0}", address));
                }

                //2] add value of the base register
                if (baseReg != Rn.NOREG)
                {
                    BitVecExpr baseRegister;
                    BitVecExpr keyBitVector = Create_Key(baseReg, key, ctx);
                    switch (RegisterTools.NBits(baseReg))
                    {
                    case 64: baseRegister = keyBitVector; break;

                    case 32: baseRegister = ctx.MkZeroExt(32, keyBitVector); break;

                    case 16: baseRegister = ctx.MkZeroExt(48, keyBitVector); break;

                    default: throw new Exception();
                    }
                    //Console.WriteLine("baseRegister.NBits = " + baseRegister.SortSize + "; address.NBits = " + address.SortSize);
                    address = (address == null) ? baseRegister : ctx.MkBVAdd(address, baseRegister);
                    //Console.WriteLine(string.Format(AsmDudeToolsStatic.CultureUI, "INFO: MemZ3:Calc_Effective_Address: B: address={0}", address));
                }

                //3] add the value of (Index * Scale)
                if (indexReg != Rn.NOREG)
                {
                    if (scale > 0)
                    {
                        BitVecExpr indexRegister = Create_Key(indexReg, key, ctx);
                        switch (scale)
                        {
                        case 0:
                            indexRegister = null;
                            break;

                        case 1:
                            break;

                        case 2:
                            indexRegister = ctx.MkBVSHL(indexRegister, ctx.MkBV(1, nBitsAddress));
                            break;

                        case 4:
                            indexRegister = ctx.MkBVSHL(indexRegister, ctx.MkBV(2, nBitsAddress));
                            break;

                        case 8:
                            indexRegister = ctx.MkBVSHL(indexRegister, ctx.MkBV(3, nBitsAddress));
                            break;

                        default:
                            throw new Exception();
                        }
                        if (address == null)
                        {
                            address = indexRegister;
                        }
                        else if (indexRegister != null)
                        {
                            address = ctx.MkBVAdd(address, indexRegister);
                            //Console.WriteLine(string.Format(AsmDudeToolsStatic.CultureUI, "INFO: MemZ3:Calc_Effective_Address: C: address={0}", address));
                        }
                    }
                }
                if (address == null)
                { // then the operand was "qword ptr [0]"
                    return(ctx.MkBV(0, nBitsAddress));
                }
                return(address);
            }
            else
            {
                throw new Exception();
            }
        }
Example #28
0
        private void AddInstruction_Shl(int lineNumber)
        {
            int ln0 = lineNumber - 1;
            int ln1 = lineNumber;

            Context ctx = this._ctx;

            foreach (Rn reg in this._registers)
            {
                if (true)
                {
                    string   asm = "SHL_" + reg + "_CL";
                    BoolExpr instruction_Switch = ctx.MkBoolConst("L" + lineNumber + "_" + asm);
                    this._switches[lineNumber].Add(instruction_Switch);

                    {
                        BitVecExpr x        = ctx.MkBVSHL(GetReg(reg, ln0, ctx), ctx.MkBVAND(GetReg(Rn.RCX, ln0, ctx), ctx.MkBV(0x3F, 64)));
                        BoolExpr   newState = MakeRuleRegResult(reg, this._registers, x, lineNumber, ctx);
                        this._solver.Assert(ctx.MkImplies(instruction_Switch, newState));
                    }
                    {
                        BitVecExpr shiftedValue = ctx.MkBVSHL(GetRegKnown(reg, ln0, ctx), ctx.MkBVAND(GetReg(Rn.RCX, ln0, ctx), ctx.MkBV(0x3F, 64)));
                        BoolExpr   newState     = ctx.MkAnd(
                            ctx.MkEq(GetRegKnown(Rn.RAX, ln1, ctx), (reg == Rn.RAX) ? shiftedValue : GetRegKnown(Rn.RAX, ln0, ctx)),
                            ctx.MkEq(GetRegKnown(Rn.RBX, ln1, ctx), (reg == Rn.RBX) ? shiftedValue : GetRegKnown(Rn.RBX, ln0, ctx)),
                            ctx.MkEq(GetRegKnown(Rn.RCX, ln1, ctx), (reg == Rn.RCX) ? shiftedValue : GetRegKnown(Rn.RCX, ln0, ctx)),
                            ctx.MkEq(GetRegKnown(Rn.RDX, ln1, ctx), (reg == Rn.RDX) ? shiftedValue : GetRegKnown(Rn.RDX, ln0, ctx))
                            );
                        this._solver.Assert(ctx.MkImplies(instruction_Switch, newState));
                        //this._solver.Assert(ctx.MkImplies(instruction_Switch, IsKnownTest(reg, ln1, ctx)));
                        //this._solver.Assert(ctx.MkImplies(instruction_Switch, IsKnownTest(ctx.MkBVAND(GetRegKnown(Rn.RCX, ln0, ctx), ctx.MkBV(0x3F, 64)), ctx)));
                    }
                }
                if (true)
                {
                    #region Create Constant
                    string     constantName_prev = "Const-SHL-" + reg + "-L" + (lineNumber - 1);
                    string     constantName      = "Const-SHL-" + reg + "-L" + lineNumber;
                    BitVecExpr constant;

                    if (true)
                    {
                        constant = ctx.MkBVConst(constantName, 64);
                        this._constants.Add(constantName, constant);
                        BoolExpr constantConstraint = ctx.MkNot(ctx.MkEq(ctx.MkBVAND(constant, ctx.MkBV(0x3F, 64)), ctx.MkBV(0, 64)));
                        this._solver.Assert(constantConstraint);
                    }
                    else
                    {
                        //IntNum t1 = ctx.MkInt("ShiftCount");
                        //BitVecExpr constant = ctx.MkBVConst(constantName, 64);

                        //IntExpr t1 = ctx.MkInt2BV(64, constant);
                        //BoolExpr constantConstraint = ctx.MkAnd(ctx.MkGt(ctx.MkInt(64), t1), ctx.MkGt(t1, ctx.MkInt(0)));
                        //this._constants.Add(constantName, constant);
                        // this._solver.Assert(constantConstraint);
                    }
                    #endregion

                    string   asm = "SHL_" + reg + "_" + constantName;
                    BoolExpr instruction_Switch = ctx.MkBoolConst("L" + lineNumber + "_" + asm);
                    this._switches[lineNumber].Add(instruction_Switch);

                    {
                        BitVecExpr shiftedValue = ctx.MkBVSHL(GetReg(reg, ln0, ctx), ctx.MkBVAND(constant, ctx.MkBV(0x3F, 64)));
                        BoolExpr   newState     = ctx.MkAnd(
                            ctx.MkEq(GetReg(Rn.RAX, ln1, ctx), (reg == Rn.RAX) ? shiftedValue : GetReg(Rn.RAX, ln0, ctx)),
                            ctx.MkEq(GetReg(Rn.RBX, ln1, ctx), (reg == Rn.RBX) ? shiftedValue : GetReg(Rn.RBX, ln0, ctx)),
                            ctx.MkEq(GetReg(Rn.RCX, ln1, ctx), (reg == Rn.RCX) ? shiftedValue : GetReg(Rn.RCX, ln0, ctx)),
                            ctx.MkEq(GetReg(Rn.RDX, ln1, ctx), (reg == Rn.RDX) ? shiftedValue : GetReg(Rn.RDX, ln0, ctx))
                            );
                        this._solver.Assert(ctx.MkImplies(instruction_Switch, newState));
                    }
                    {
                        BitVecExpr shiftedValue = ctx.MkBVSHL(GetRegKnown(reg, ln0, ctx), ctx.MkBVAND(constant, ctx.MkBV(0x3F, 64)));
                        BoolExpr   newState     = ctx.MkAnd(
                            ctx.MkEq(GetRegKnown(Rn.RAX, ln1, ctx), (reg == Rn.RAX) ? shiftedValue : GetRegKnown(Rn.RAX, ln0, ctx)),
                            ctx.MkEq(GetRegKnown(Rn.RBX, ln1, ctx), (reg == Rn.RBX) ? shiftedValue : GetRegKnown(Rn.RBX, ln0, ctx)),
                            ctx.MkEq(GetRegKnown(Rn.RCX, ln1, ctx), (reg == Rn.RCX) ? shiftedValue : GetRegKnown(Rn.RCX, ln0, ctx)),
                            ctx.MkEq(GetRegKnown(Rn.RDX, ln1, ctx), (reg == Rn.RDX) ? shiftedValue : GetRegKnown(Rn.RDX, ln0, ctx))
                            );
                        this._solver.Assert(ctx.MkImplies(instruction_Switch, newState));
                        //this._solver.Assert(ctx.MkImplies(instruction_Switch, IsKnownTest(reg, ln1, ctx)));
                    }
                }
            }
        }
Example #29
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));
            }
        }
Example #30
0
 public void Set_Mem(BitVecExpr address, Tv[] value)
 {
     (BitVecExpr value, BitVecExpr undef)tup = ToolsZ3.MakeVecExpr(value, this.ctx_);
     this.Set_Mem(address, tup.value, tup.undef);
 }