from mythril.laser.smt import Solver, symbol_factory, UGT, UGE, ULT, ULE import z3 import pytest import operator @pytest.mark.parametrize( "operation,expected", [ (operator.add, z3.unsat), (operator.sub, z3.unsat), (operator.and_, z3.sat), (operator.or_, z3.sat), (operator.xor, z3.unsat), ], ) def test_bitvecfunc_arithmetic(operation, expected): # Arrange s = Solver() input_ = symbol_factory.BitVecVal(1, 8) bvf = symbol_factory.BitVecFuncSym("bvf", "sha3", 256, input_=input_) x = symbol_factory.BitVecSym("x", 256) y = symbol_factory.BitVecSym("y", 256) # Act s.add(x != y) s.add(operation(bvf, x) == operation(y, bvf)) # Assert assert s.check() == expected @pytest.mark.parametrize( "operation,expected", [ (operator.eq, z3.sat), (operator.ne, z3.unsat), (operator.lt, z3.unsat), (operator.le, z3.sat), (operator.gt, z3.unsat), (operator.ge, z3.sat), (UGT, z3.unsat), (UGE, z3.sat), (ULT, z3.unsat), (ULE, z3.sat), ], ) def test_bitvecfunc_bitvecfunc_comparison(operation, expected): # Arrange s = Solver() input1 = symbol_factory.BitVecSym("input1", 256) input2 = symbol_factory.BitVecSym("input2", 256) bvf1 = symbol_factory.BitVecFuncSym("bvf1", "sha3", 256, input_=input1) bvf2 = symbol_factory.BitVecFuncSym("bvf2", "sha3", 256, input_=input2) # Act s.add(operation(bvf1, bvf2)) s.add(input1 == input2) # Assert assert s.check() == expected def test_bitvecfunc_bitvecfuncval_comparison(): # Arrange s = Solver() input1 = symbol_factory.BitVecSym("input1", 256) input2 = symbol_factory.BitVecVal(1337, 256) bvf1 = symbol_factory.BitVecFuncSym("bvf1", "sha3", 256, input_=input1) bvf2 = symbol_factory.BitVecFuncVal(12345678910, "sha3", 256, input_=input2) # Act s.add(bvf1 == bvf2) # Assert assert s.check() == z3.sat assert s.model().eval(input2.raw) == 1337 def test_bitvecfunc_nested_comparison(): # arrange s = Solver() input1 = symbol_factory.BitVecSym("input1", 256) input2 = symbol_factory.BitVecSym("input2", 256) bvf1 = symbol_factory.BitVecFuncSym("bvf1", "sha3", 256, input_=input1) bvf2 = symbol_factory.BitVecFuncSym("bvf2", "sha3", 256, input_=bvf1) bvf3 = symbol_factory.BitVecFuncSym("bvf3", "sha3", 256, input_=input2) bvf4 = symbol_factory.BitVecFuncSym("bvf4", "sha3", 256, input_=bvf3) # Act s.add(input1 == input2) s.add(bvf2 == bvf4) # Assert assert s.check() == z3.sat def test_bitvecfunc_unequal_nested_comparison(): # arrange s = Solver() input1 = symbol_factory.BitVecSym("input1", 256) input2 = symbol_factory.BitVecSym("input2", 256) bvf1 = symbol_factory.BitVecFuncSym("bvf1", "sha3", 256, input_=input1) bvf2 = symbol_factory.BitVecFuncSym("bvf2", "sha3", 256, input_=bvf1) bvf3 = symbol_factory.BitVecFuncSym("bvf3", "sha3", 256, input_=input2) bvf4 = symbol_factory.BitVecFuncSym("bvf4", "sha3", 256, input_=bvf3) # Act s.add(input1 != input2) s.add(bvf2 == bvf4) # Assert assert s.check() == z3.unsat def test_bitvecfunc_ext_nested_comparison(): # arrange s = Solver() input1 = symbol_factory.BitVecSym("input1", 256) input2 = symbol_factory.BitVecSym("input2", 256) input3 = symbol_factory.BitVecSym("input3", 256) input4 = symbol_factory.BitVecSym("input4", 256) bvf1 = symbol_factory.BitVecFuncSym("bvf1", "sha3", 256, input_=input1) bvf2 = symbol_factory.BitVecFuncSym("bvf2", "sha3", 256, input_=bvf1 + input3) bvf3 = symbol_factory.BitVecFuncSym("bvf3", "sha3", 256, input_=input2) bvf4 = symbol_factory.BitVecFuncSym("bvf4", "sha3", 256, input_=bvf3 + input4) # Act s.add(input1 == input2) s.add(input3 == input4) s.add(bvf2 == bvf4) # Assert assert s.check() == z3.sat def test_bitvecfunc_ext_unequal_nested_comparison(): # Arrange s = Solver() input1 = symbol_factory.BitVecSym("input1", 256) input2 = symbol_factory.BitVecSym("input2", 256) input3 = symbol_factory.BitVecSym("input3", 256) input4 = symbol_factory.BitVecSym("input4", 256) bvf1 = symbol_factory.BitVecFuncSym("bvf1", "sha3", 256, input_=input1) bvf2 = symbol_factory.BitVecFuncSym("bvf2", "sha3", 256, input_=bvf1 + input3) bvf3 = symbol_factory.BitVecFuncSym("bvf3", "sha3", 256, input_=input2) bvf4 = symbol_factory.BitVecFuncSym("bvf4", "sha3", 256, input_=bvf3 + input4) # Act s.add(input1 == input2) s.add(input3 != input4) s.add(bvf2 == bvf4) # Assert assert s.check() == z3.unsat def test_bitvecfunc_ext_unequal_nested_comparison_f(): # Arrange s = Solver() input1 = symbol_factory.BitVecSym("input1", 256) input2 = symbol_factory.BitVecSym("input2", 256) input3 = symbol_factory.BitVecSym("input3", 256) input4 = symbol_factory.BitVecSym("input4", 256) bvf1 = symbol_factory.BitVecFuncSym("bvf1", "sha3", 256, input_=input1) bvf2 = symbol_factory.BitVecFuncSym("bvf2", "sha3", 256, input_=bvf1 + input3) bvf3 = symbol_factory.BitVecFuncSym("bvf3", "sha3", 256, input_=input2) bvf4 = symbol_factory.BitVecFuncSym("bvf4", "sha3", 256, input_=bvf3 + input4) # Act s.add(input1 != input2) s.add(input3 == input4) s.add(bvf2 == bvf4) # Assert assert s.check() == z3.unsat def test_bitvecfunc_find_input(): # Arrange s = Solver() input1 = symbol_factory.BitVecSym("input1", 256) input2 = symbol_factory.BitVecSym("input2", 256) bvf1 = symbol_factory.BitVecFuncSym("bvf1", "sha3", 256, input_=input1) bvf2 = symbol_factory.BitVecFuncSym("bvf3", "sha3", 256, input_=input2) # Act s.add(input1 == symbol_factory.BitVecVal(1, 256)) s.add(bvf1 == bvf2) # Assert assert s.check() == z3.sat assert s.model()[input2.raw] == 1 def test_bitvecfunc_nested_find_input(): # Arrange s = Solver() input1 = symbol_factory.BitVecSym("input1", 256) input2 = symbol_factory.BitVecSym("input2", 256) bvf1 = symbol_factory.BitVecFuncSym("bvf1", "sha3", 256, input_=input1) bvf2 = symbol_factory.BitVecFuncSym("bvf2", "sha3", 256, input_=bvf1) bvf3 = symbol_factory.BitVecFuncSym("bvf3", "sha3", 256, input_=input2) bvf4 = symbol_factory.BitVecFuncSym("bvf4", "sha3", 256, input_=bvf3) # Act s.add(input1 == symbol_factory.BitVecVal(123, 256)) s.add(bvf2 == bvf4) # Assert assert s.check() == z3.sat assert s.model()[input2.raw] == 123