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))); } }
public static BitVecExpr GetBit_BV(BitVecExpr value, BitVecExpr pos, Context ctx) { return(ctx.MkExtract(0, 0, ctx.MkBVLSHR(value, pos))); }
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); }
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)); }
public static Tv[] GetTvArray(BitVecExpr value, int nBits, Solver solver, Solver solver_U, Context ctx) { return(GetTvArray(value, value, nBits, solver, solver_U, ctx)); }
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(); } } }
public void Set_Mem(BitVecExpr address, Tv[] value) { var tup = ToolsZ3.MakeVecExpr(value, this._ctx); this.Set_Mem(address, tup.value, tup.undef); }
public void Set_Mem(BitVecExpr address, BitVecExpr value) { this.Set_Mem(address, value, value); }
public void Set_Mem(BitVecExpr address, ulong value, int nBytes) { BitVecExpr valueExpr = this._ctx.MkBV(value, (uint)nBytes << 3); this.Set_Mem(address, valueExpr); }
public void Set_Mem(BitVecExpr address, string value) { this.Set_Mem(address, ToolsZ3.GetTvArray(value)); }
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; } } }
public void Set(Rn reg, BitVecExpr value) { this.Set(reg, value, value); }
public void Set(Rn reg, ulong value) { BitVecExpr valueExpr = this._ctx.MkBV(value, (uint)RegisterTools.NBits(reg)); this.Set(reg, valueExpr, valueExpr); }
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))); } }
public void Set(Operand operand, BitVecExpr value) { this.Set(operand, value, value); }
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); } } }
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)); } }
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)); } } }
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); }
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)); }
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); }
public static BoolExpr GetBit(BitVecExpr value, BitVecExpr pos, Context ctx) { return(ctx.MkEq(GetBit_BV(value, pos, ctx), ctx.MkBV(1, 1))); }
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()))); }
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(); } }
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))); } } } }
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)); } }
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); }