class StateTest(unittest.TestCase): _multiprocess_can_split_ = True def setUp(self): dirname = os.path.dirname(__file__) l = linux.Linux(os.path.join(dirname, 'binaries', 'basic_linux_amd64')) self.state = State(ConstraintSet(), l) def test_solve_one(self): val = 42 expr = BitVecVariable(32, 'tmp') self.state.constrain(expr == val) solved = self.state.solve_one(expr) self.assertEqual(solved, val) def test_solve_n(self): expr = BitVecVariable(32, 'tmp') self.state.constrain(expr > 4) self.state.constrain(expr < 7) solved = self.state.solve_n(expr, 2) self.assertEqual(solved, [5, 6]) def test_solve_n2(self): expr = BitVecVariable(32, 'tmp') self.state.constrain(expr > 4) self.state.constrain(expr < 100) solved = self.state.solve_n(expr, 5) self.assertEqual(len(solved), 5) def test_solve_min_max(self): expr = BitVecVariable(32, 'tmp') self.state.constrain(expr > 4) self.state.constrain(expr < 7) self.assertEqual(self.state.solve_min(expr), 5) self.assertEqual(self.state.solve_max(expr), 6) self.assertEqual(self.state.solve_minmax(expr), (5, 6)) def test_policy_one(self): expr = BitVecVariable(32, 'tmp') self.state.constrain(expr > 0) self.state.constrain(expr < 100) solved = self.state.concretize(expr, 'ONE') self.assertEqual(len(solved), 1) self.assertIn(solved[0], range(100)) def test_state(self): constraints = ConstraintSet() initial_state = State(constraints, FakePlatform()) arr = initial_state.symbolicate_buffer('+' * 100, label='SYMBA') initial_state.constrain(arr[0] > 0x41) self.assertTrue(len(initial_state.constraints.declarations) == 1) with initial_state as new_state: self.assertTrue(len(initial_state.constraints.declarations) == 1) self.assertTrue(len(new_state.constraints.declarations) == 1) arrb = new_state.symbolicate_buffer('+' * 100, label='SYMBB') self.assertTrue(len(initial_state.constraints.declarations) == 1) self.assertTrue(len(new_state.constraints.declarations) == 1) new_state.constrain(arrb[0] > 0x42) self.assertTrue(len(new_state.constraints.declarations) == 2) self.assertTrue(len(initial_state.constraints.declarations) == 1) def test_new_symbolic_buffer(self): length = 64 expr = self.state.new_symbolic_buffer(length) self.assertEqual(len(expr), length) def test_new_symbolic_value(self): length = 64 expr = self.state.new_symbolic_value(length) self.assertEqual(expr.size, length) def test_new_bad_symbolic_value(self): length = 62 with self.assertRaises(Exception): expr = self.state.new_symbolic_value(length) def test_tainted_symbolic_buffer(self): taint = ('TEST_TAINT', ) expr = self.state.new_symbolic_buffer(64, taint=taint) self.assertEqual(expr.taint, frozenset(taint)) def test_tainted_symbolic_value(self): taint = ('TEST_TAINT', ) expr = self.state.new_symbolic_value(64, taint=taint) self.assertEqual(expr.taint, frozenset(taint)) def testContextSerialization(self): import pickle as pickle initial_file = '' new_file = '' new_new_file = '' constraints = ConstraintSet() initial_state = State(constraints, FakePlatform()) initial_state.context['step'] = 10 initial_file = pickle.dumps(initial_state) with initial_state as new_state: self.assertEqual(initial_state.context['step'], 10) self.assertEqual(new_state.context['step'], 10) new_state.context['step'] = 20 self.assertEqual(initial_state.context['step'], 10) self.assertEqual(new_state.context['step'], 20) new_file = pickle.dumps(new_state) with new_state as new_new_state: self.assertEqual(initial_state.context['step'], 10) self.assertEqual(new_state.context['step'], 20) self.assertEqual(new_new_state.context['step'], 20) new_new_state.context['step'] += 10 self.assertEqual(initial_state.context['step'], 10) self.assertEqual(new_state.context['step'], 20) self.assertEqual(new_new_state.context['step'], 30) new_new_file = pickle.dumps(new_new_state) self.assertEqual(initial_state.context['step'], 10) self.assertEqual(new_state.context['step'], 20) self.assertEqual(new_new_state.context['step'], 30) self.assertEqual(initial_state.context['step'], 10) self.assertEqual(new_state.context['step'], 20) self.assertEqual(initial_state.context['step'], 10) del initial_state del new_state del new_new_state initial_state = pickle.loads(initial_file) self.assertEqual(initial_state.context['step'], 10) new_state = pickle.loads(new_file) self.assertEqual(new_state.context['step'], 20) new_new_state = pickle.loads(new_new_file) self.assertEqual(new_new_state.context['step'], 30) def _test_state_gen_helper(self, name, msg): self.assertEqual(name, 'statename') self.assertEqual(msg, 'statemsg') raise _CallbackExecuted def testContextSerialization(self): import pickle as pickle initial_file = '' new_file = '' new_new_file = '' constraints = ConstraintSet() initial_state = State(constraints, FakePlatform()) initial_state.context['step'] = 10 initial_file = pickle.dumps(initial_state) with initial_state as new_state: self.assertEqual(initial_state.context['step'], 10) self.assertEqual(new_state.context['step'], 10) new_state.context['step'] = 20 self.assertEqual(initial_state.context['step'], 10) self.assertEqual(new_state.context['step'], 20) new_file = pickle.dumps(new_state) with new_state as new_new_state: self.assertEqual(initial_state.context['step'], 10) self.assertEqual(new_state.context['step'], 20) self.assertEqual(new_new_state.context['step'], 20) new_new_state.context['step'] += 10 self.assertEqual(initial_state.context['step'], 10) self.assertEqual(new_state.context['step'], 20) self.assertEqual(new_new_state.context['step'], 30) new_new_file = pickle.dumps(new_new_state) self.assertEqual(initial_state.context['step'], 10) self.assertEqual(new_state.context['step'], 20) self.assertEqual(new_new_state.context['step'], 30) self.assertEqual(initial_state.context['step'], 10) self.assertEqual(new_state.context['step'], 20) self.assertEqual(initial_state.context['step'], 10) del initial_state del new_state del new_new_state initial_state = pickle.loads(initial_file) self.assertEqual(initial_state.context['step'], 10) new_state = pickle.loads(new_file) self.assertEqual(new_state.context['step'], 20) new_new_state = pickle.loads(new_new_file) self.assertEqual(new_new_state.context['step'], 30) def test_state_gen(self): self.state.subscribe('will_generate_testcase', self._test_state_gen_helper) with self.assertRaises(_CallbackExecuted): self.state.generate_testcase('statename', 'statemsg')
class StateTest(unittest.TestCase): _multiprocess_can_split_ = True def setUp(self): dirname = os.path.dirname(__file__) l = linux.Linux(os.path.join(dirname, "binaries", "basic_linux_amd64")) self.state = State(ConstraintSet(), l) def test_solve_one(self): val = 42 expr = BitVecVariable(32, "tmp") self.state.constrain(expr == val) solved = self.state.solve_one(expr) self.assertEqual(solved, val) def test_solve_n(self): expr = BitVecVariable(32, "tmp") self.state.constrain(expr > 4) self.state.constrain(expr < 7) solved = sorted(self.state.solve_n(expr, 2)) self.assertEqual(solved, [5, 6]) def test_solve_n2(self): expr = BitVecVariable(32, "tmp") self.state.constrain(expr > 4) self.state.constrain(expr < 100) solved = self.state.solve_n(expr, 5) self.assertEqual(len(solved), 5) def test_solve_min_max(self): expr = BitVecVariable(32, "tmp") self.state.constrain(expr > 4) self.state.constrain(expr < 7) self.assertEqual(self.state.solve_min(expr), 5) self.assertEqual(self.state.solve_max(expr), 6) self.assertEqual(self.state.solve_minmax(expr), (5, 6)) def test_policy_one(self): expr = BitVecVariable(32, "tmp") self.state.constrain(expr > 0) self.state.constrain(expr < 100) solved = self.state.concretize(expr, "ONE") self.assertEqual(len(solved), 1) self.assertIn(solved[0], range(100)) def test_state(self): constraints = ConstraintSet() initial_state = State(constraints, FakePlatform()) arr = initial_state.symbolicate_buffer("+" * 100, label="SYMBA") initial_state.constrain(arr[0] > 0x41) self.assertTrue(len(initial_state.constraints.declarations) == 1) with initial_state as new_state: self.assertTrue(len(initial_state.constraints.declarations) == 1) self.assertTrue(len(new_state.constraints.declarations) == 1) arrb = new_state.symbolicate_buffer("+" * 100, label="SYMBB") self.assertTrue(len(initial_state.constraints.declarations) == 1) self.assertTrue(len(new_state.constraints.declarations) == 1) new_state.constrain(arrb[0] > 0x42) self.assertTrue(len(new_state.constraints.declarations) == 2) self.assertTrue(len(initial_state.constraints.declarations) == 1) def test_new_symbolic_buffer(self): length = 64 expr = self.state.new_symbolic_buffer(length) self.assertEqual(len(expr), length) def test_new_symbolic_value(self): length = 64 expr = self.state.new_symbolic_value(length) self.assertEqual(expr.size, length) def test_new_bad_symbolic_value(self): length = 62 with self.assertRaises(Exception): expr = self.state.new_symbolic_value(length) def test_tainted_symbolic_buffer(self): taint = ("TEST_TAINT",) expr = self.state.new_symbolic_buffer(64, taint=taint) self.assertEqual(expr.taint, frozenset(taint)) def test_tainted_symbolic_value(self): taint = ("TEST_TAINT",) expr = self.state.new_symbolic_value(64, taint=taint) self.assertEqual(expr.taint, frozenset(taint)) def testContextSerialization(self): import pickle as pickle initial_file = "" new_file = "" new_new_file = "" constraints = ConstraintSet() initial_state = State(constraints, FakePlatform()) initial_state.context["step"] = 10 initial_file = pickle_dumps(initial_state) with initial_state as new_state: self.assertEqual(initial_state.context["step"], 10) self.assertEqual(new_state.context["step"], 10) new_state.context["step"] = 20 self.assertEqual(initial_state.context["step"], 10) self.assertEqual(new_state.context["step"], 20) new_file = pickle_dumps(new_state) with new_state as new_new_state: self.assertEqual(initial_state.context["step"], 10) self.assertEqual(new_state.context["step"], 20) self.assertEqual(new_new_state.context["step"], 20) new_new_state.context["step"] += 10 self.assertEqual(initial_state.context["step"], 10) self.assertEqual(new_state.context["step"], 20) self.assertEqual(new_new_state.context["step"], 30) new_new_file = pickle_dumps(new_new_state) self.assertEqual(initial_state.context["step"], 10) self.assertEqual(new_state.context["step"], 20) self.assertEqual(new_new_state.context["step"], 30) self.assertEqual(initial_state.context["step"], 10) self.assertEqual(new_state.context["step"], 20) self.assertEqual(initial_state.context["step"], 10) del initial_state del new_state del new_new_state initial_state = pickle.loads(initial_file) self.assertEqual(initial_state.context["step"], 10) new_state = pickle.loads(new_file) self.assertEqual(new_state.context["step"], 20) new_new_state = pickle.loads(new_new_file) self.assertEqual(new_new_state.context["step"], 30) def testContextSerialization(self): import pickle as pickle initial_file = "" new_file = "" new_new_file = "" constraints = ConstraintSet() initial_state = State(constraints, FakePlatform()) initial_state.context["step"] = 10 initial_file = pickle_dumps(initial_state) with initial_state as new_state: self.assertEqual(initial_state.context["step"], 10) self.assertEqual(new_state.context["step"], 10) new_state.context["step"] = 20 self.assertEqual(initial_state.context["step"], 10) self.assertEqual(new_state.context["step"], 20) new_file = pickle_dumps(new_state) with new_state as new_new_state: self.assertEqual(initial_state.context["step"], 10) self.assertEqual(new_state.context["step"], 20) self.assertEqual(new_new_state.context["step"], 20) new_new_state.context["step"] += 10 self.assertEqual(initial_state.context["step"], 10) self.assertEqual(new_state.context["step"], 20) self.assertEqual(new_new_state.context["step"], 30) new_new_file = pickle_dumps(new_new_state) self.assertEqual(initial_state.context["step"], 10) self.assertEqual(new_state.context["step"], 20) self.assertEqual(new_new_state.context["step"], 30) self.assertEqual(initial_state.context["step"], 10) self.assertEqual(new_state.context["step"], 20) self.assertEqual(initial_state.context["step"], 10) del initial_state del new_state del new_new_state initial_state = pickle.loads(initial_file) self.assertEqual(initial_state.context["step"], 10) new_state = pickle.loads(new_file) self.assertEqual(new_state.context["step"], 20) new_new_state = pickle.loads(new_new_file) self.assertEqual(new_new_state.context["step"], 30)
class StateTest(unittest.TestCase): _multiprocess_can_split_ = True def setUp(self): dirname = os.path.dirname(__file__) l = linux.Linux(os.path.join(dirname, "binaries", "basic_linux_amd64")) self.state = State(ConstraintSet(), l) def test_solve_one(self): val = 42 expr = BitVecVariable(32, "tmp") self.state.constrain(expr == val) solved = self.state.solve_one(expr) self.assertEqual(solved, val) def test_solve_n(self): expr = BitVecVariable(32, "tmp") self.state.constrain(expr > 4) self.state.constrain(expr < 7) solved = sorted(self.state.solve_n(expr, 2)) self.assertEqual(solved, [5, 6]) def test_solve_n2(self): expr = BitVecVariable(32, "tmp") self.state.constrain(expr > 4) self.state.constrain(expr < 100) solved = self.state.solve_n(expr, 5) self.assertEqual(len(solved), 5) def test_solve_min_max(self): expr = BitVecVariable(32, "tmp") self.state.constrain(expr > 4) self.state.constrain(expr < 7) self.assertEqual(self.state.solve_min(expr), 5) self.assertEqual(self.state.solve_max(expr), 6) self.assertEqual(self.state.solve_minmax(expr), (5, 6)) def test_policy_one(self): expr = BitVecVariable(32, "tmp") self.state.constrain(expr > 0) self.state.constrain(expr < 100) solved = self.state.concretize(expr, "ONE") self.assertEqual(len(solved), 1) self.assertIn(solved[0], range(100)) def test_state(self): constraints = ConstraintSet() initial_state = State(constraints, FakePlatform()) arr = initial_state.symbolicate_buffer("+" * 100, label="SYMBA") initial_state.constrain(arr[0] > 0x41) self.assertTrue(len(initial_state.constraints.declarations) == 1) with initial_state as new_state: self.assertTrue(len(initial_state.constraints.declarations) == 1) self.assertTrue(len(new_state.constraints.declarations) == 1) arrb = new_state.symbolicate_buffer("+" * 100, label="SYMBB") self.assertTrue(len(initial_state.constraints.declarations) == 1) self.assertTrue(len(new_state.constraints.declarations) == 1) new_state.constrain(arrb[0] > 0x42) self.assertTrue(len(new_state.constraints.declarations) == 2) self.assertTrue(len(initial_state.constraints.declarations) == 1) def test_new_symbolic_buffer(self): length = 64 expr = self.state.new_symbolic_buffer(length) self.assertEqual(len(expr), length) def test_new_symbolic_value(self): length = 64 expr = self.state.new_symbolic_value(length) self.assertEqual(expr.size, length) def test_new_bad_symbolic_value(self): length = 62 with self.assertRaises(Exception): expr = self.state.new_symbolic_value(length) def test_tainted_symbolic_buffer(self): taint = ("TEST_TAINT", ) expr = self.state.new_symbolic_buffer(64, taint=taint) self.assertEqual(expr.taint, frozenset(taint)) def test_tainted_symbolic_value(self): taint = ("TEST_TAINT", ) expr = self.state.new_symbolic_value(64, taint=taint) self.assertEqual(expr.taint, frozenset(taint)) def test_state_hook(self): initial_state = State(ConstraintSet(), FakePlatform()) def fake_hook(_: StateBase) -> None: return None self.assertTrue(len(initial_state._hooks) == 0) self.assertTrue(len(initial_state._after_hooks) == 0) # This hook should be propagated to child state initial_state.add_hook(0x4000, fake_hook, after=False) self.assertTrue(len(initial_state._hooks) == 1) self.assertTrue(len(initial_state._after_hooks) == 0) with initial_state as new_state: # Child state has parent's hook self.assertTrue(len(new_state._hooks) == 1) self.assertTrue(len(new_state._after_hooks) == 0) # Try adding the same hook new_state.add_hook(0x4000, fake_hook, after=False) # Should not add again self.assertTrue(len(new_state._hooks) == 1) # Add two hooks for after and before instruction new_state.add_hook(0x4001, fake_hook, after=True) new_state.add_hook(0x4001, fake_hook, after=False) # A new hook added to both lists self.assertTrue(len(new_state._hooks) == 2) self.assertTrue(len(new_state._after_hooks) == 1) # Ensure parent state was not affected self.assertTrue(len(initial_state._hooks) == 1) self.assertTrue(len(initial_state._after_hooks) == 0) # Remove one of the hooks we added new_state.remove_hook(0x4000, fake_hook, after=False) # Try to remove a non-existent hook self.assertFalse( new_state.remove_hook(0x4000, fake_hook, after=True)) # Ensure removal self.assertTrue(len(new_state._hooks) == 1) self.assertTrue(len(new_state._after_hooks) == 1) # Ensure parent state wasn't affected self.assertTrue(len(initial_state._hooks) == 1) self.assertTrue(len(initial_state._after_hooks) == 0) # Add hook to all PC in our parent state initial_state.add_hook(None, fake_hook, after=True) # Ensure only the hooks we added are still here self.assertTrue(len(initial_state._hooks) == 1) self.assertTrue(len(initial_state._after_hooks) == 1) def testContextSerialization(self): import pickle as pickle initial_file = "" new_file = "" new_new_file = "" constraints = ConstraintSet() initial_state = State(constraints, FakePlatform()) initial_state.context["step"] = 10 initial_file = pickle_dumps(initial_state) with initial_state as new_state: self.assertEqual(initial_state.context["step"], 10) self.assertEqual(new_state.context["step"], 10) new_state.context["step"] = 20 self.assertEqual(initial_state.context["step"], 10) self.assertEqual(new_state.context["step"], 20) new_file = pickle_dumps(new_state) with new_state as new_new_state: self.assertEqual(initial_state.context["step"], 10) self.assertEqual(new_state.context["step"], 20) self.assertEqual(new_new_state.context["step"], 20) new_new_state.context["step"] += 10 self.assertEqual(initial_state.context["step"], 10) self.assertEqual(new_state.context["step"], 20) self.assertEqual(new_new_state.context["step"], 30) new_new_file = pickle_dumps(new_new_state) self.assertEqual(initial_state.context["step"], 10) self.assertEqual(new_state.context["step"], 20) self.assertEqual(new_new_state.context["step"], 30) self.assertEqual(initial_state.context["step"], 10) self.assertEqual(new_state.context["step"], 20) self.assertEqual(initial_state.context["step"], 10) del initial_state del new_state del new_new_state initial_state = pickle.loads(initial_file) self.assertEqual(initial_state.context["step"], 10) new_state = pickle.loads(new_file) self.assertEqual(new_state.context["step"], 20) new_new_state = pickle.loads(new_new_file) self.assertEqual(new_new_state.context["step"], 30)