def combine(self, storage=dict(), initial_balance=None): extra_subst = [] storage_base = z3.K(z3.BitVecSort(256), z3.BitVecVal(0, 256)) for k, v in storage.items(): storage_base = z3.Store(storage_base, k, v) for result in self.results: extra_subst.append((result.state.storage.base, storage_base)) storage_base = z3.substitute(result.state.storage.storage, extra_subst) extra_constraints = [] if initial_balance is not None: balance_base = z3.BitVecVal(initial_balance, 256) else: balance_base = None for result in self.results: if balance_base is not None: extra_subst.append((result.state.start_balance, balance_base)) balance_base = z3.substitute(result.state.balance, extra_subst) else: balance_base = result.state.balance self._states = [LazySubstituteState(r.state, extra_subst) for r in self.results] self._constraints = [z3.substitute(c, extra_subst) for r in self.results for c in r.constraints] + extra_constraints self._sha_constraints = { sha: z3.substitute(sha_value, extra_subst) if not isinstance(sha_value, SymRead) else sha_value for r in self.results for sha, sha_value in r.sha_constraints.items()} self._idx_dict = {r.xid: i for i, r in enumerate(self.results)}
def symread_substitute(x, subst): if not isinstance(x, SymRead): return z3.simplify(z3.substitute(x, subst)) else: new_symread = copy.copy(x) new_symread.memory.memory = z3.simplify(z3.substitute(new_symread.memory.memory, subst)) if not concrete(new_symread.start): new_symread.start = z3.simplify(z3.substitute(new_symread.start, subst)) if not concrete(new_symread.size): new_symread.size = z3.simplify(z3.substitute(new_symread.size, subst)) return new_symread
def check_model_and_resolve_inner(constraints, sha_constraints, second_try=False): # logging.debug('-' * 32) extra_constraints = [] s = z3.SolverFor("QF_ABV") z3.set_option(model_compress=False) s.add(constraints) if s.check() != z3.sat: raise IntractablePath("CHECK", "MODEL") else: if not sha_constraints: return s.model() while True: ne_constraints = [] for a, b in itertools.combinations(sha_constraints.keys(), 2): if (not isinstance(sha_constraints[a], SymRead) and not isinstance(sha_constraints[b], SymRead) and sha_constraints[a].size() != sha_constraints[b].size()): ne_constraints.append(a != b) continue s = z3.SolverFor("QF_ABV") z3.set_option(model_compress=False) s.add(constraints + ne_constraints + extra_constraints + [a != b, symread_neq(sha_constraints[a], sha_constraints[b])]) check_result = s.check() # logging.debug("Checking hashes %s and %s: %s", a, b, check_result) if check_result == z3.unsat: # logging.debug("Hashes MUST be equal: %s and %s", a, b) subst = [(a, b)] extra_constraints = [z3.simplify(z3.substitute(c, subst)) for c in extra_constraints] extra_constraints.append(symread_eq(symread_substitute(sha_constraints[a], subst), symread_substitute(sha_constraints[b], subst))) constraints = [z3.simplify(z3.substitute(c, subst)) for c in constraints] b_val = symread_substitute(sha_constraints[b], subst) sha_constraints = {z3.substitute(sha, subst): symread_substitute(sha_value, subst) for sha, sha_value in sha_constraints.items() if not sha is a or sha is b} sha_constraints[b] = b_val break else: # logging.debug("Hashes COULD be equal: %s and %s", a, b) pass else: break return check_and_model(constraints + extra_constraints, sha_constraints, ne_constraints, second_try=second_try)
def __init__(self, state, substitutions): self._state = state self._substitutions = list(substitutions) self.memory = LazySubstituteMemory(self._state.memory, substitutions) self.stack = LazySubstituteStack(self._state.stack, substitutions) self.code = self._state.code self.pc = self._state.pc self.trace = self._state.trace self.balance = z3.substitute(state.balance, substitutions)
def translate(expr, xid): substitutions = dict() def raw(s): return '_'.join(s.split('_')[:-1]) for v in get_vars_non_recursive(expr): if v not in substitutions: v_name = raw(v.decl().name()) if v.sort_kind() == z3.Z3_INT_SORT: substitutions[v] = z3.Int('%s_%d' % (v_name, xid)) elif v.sort_kind() == z3.Z3_BOOL_SORT: substitutions[v] = z3.Bool('%s_%d' % (v_name, xid)) elif v.sort_kind() == z3.Z3_BV_SORT: substitutions[v] = z3.BitVec('%s_%d' % (v_name, xid), v.size()) elif v.sort_kind() == z3.Z3_ARRAY_SORT: substitutions[v] = z3.Array('%s_%d' % (v_name, xid), v.domain(), v.range()) else: raise Exception('CANNOT CONVERT %s (%d)' % (v, v.sort_kind())) subst = list(substitutions.items()) return z3.substitute(expr, subst)
def __getitem__(self, index): r = self._stack[index] if isinstance(index, slice): return [x if concrete(x) else z3.substitute(x, self._substitutions) for x in r] else: return r if concrete(r) else z3.substitute(r, self._substitutions)