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