Пример #1
0
    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)}
Пример #2
0
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
Пример #3
0
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)
Пример #4
0
 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)
Пример #5
0
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)
Пример #6
0
 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)