Ejemplo n.º 1
0
 def __init__(self, result):
     self.result = result
     self._vars = dict()
     self.concrete_reads = set()
     self.concrete_writes = set()
     self.symbolic_reads = set()
     self.symbolic_writes = set()
     self.symbolic_hash_reads = set()
     self.symbolic_hash_writes = set()
     for addr in set(result.state.storage.reads):
         if concrete(addr):
             self.concrete_reads.add(addr)
         else:
             x_vars = get_vars_non_recursive(addr, True)
             self._vars[addr] = x_vars
             if set(x_vars) & set(result.sha_constraints.keys()):
                 self.symbolic_hash_reads.add(addr)
             else:
                 self.symbolic_reads.add(addr)
     for addr in set(result.state.storage.writes):
         if concrete(addr):
             self.concrete_writes.add(addr)
         else:
             x_vars = get_vars_non_recursive(addr, True)
             self._vars[addr] = x_vars
             if set(x_vars) & set(result.sha_constraints.keys()):
                 self.symbolic_hash_writes.add(addr)
             else:
                 self.symbolic_writes.add(addr)
Ejemplo n.º 2
0
def dependency_summary(constraints, sha_constraints, detailed=False):
    all_dependencies = set(x for c in constraints if z3.is_expr(c) for x in
                           get_vars_non_recursive(z3.simplify(c), include_select=detailed))
    changed = True
    while changed:
        changed = False
        for x in set(all_dependencies):
            if x in sha_constraints:
                changed = True
                all_dependencies.discard(x)
                all_dependencies.update(
                    get_vars_non_recursive(z3.simplify(sha_constraints[x], include_select=detailed)))
    return all_dependencies
Ejemplo n.º 3
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)
Ejemplo n.º 4
0
def check_and_model(constraints, sha_constraints, ne_constraints, second_try=False):
    # logging.debug(' ' * 16 + '-' * 16)

    unresolved = set(sha_constraints.keys())
    sol = get_solver()
    sol.add(ne_constraints)
    todo = constraints
    progress = True
    all_vars = dict()
    while progress:
        new_todo = []
        progress = False
        for c in todo:
            all_vars[c] = get_vars_non_recursive(c, include_select=True, include_indices=False)
            if any(x in unresolved for x in all_vars[c]):
                new_todo.append(c)
            else:
                progress = True
                sol.add(c)
        unresolved_vars = set(v.get_id() for c in new_todo for v in all_vars[c]) | set(v.get_id() for v in unresolved)
        # logging.debug("Unresolved vars: %s", ','.join(map(str, unresolved_vars)))
        if sol.check() != z3.sat:
            raise IntractablePath()
        m = sol.model()
        unresolved_todo = list(set(unresolved))
        while unresolved_todo:
            u = unresolved_todo.pop()
            c = sha_constraints[u]
            if isinstance(c, SymRead):
                vars = set()
                if not concrete(c.start):
                    vars |= get_vars_non_recursive(c.start, include_select=True)
                if not concrete(c.size):
                    vars |= get_vars_non_recursive(c.size, include_select=True)
                # logging.debug("Trying to resolve %s, start and size vars: %s", u, ','.join(map(str, vars)))
                if any(x.get_id() in unresolved_vars for x in vars):
                    continue
                start = c.start
                if not concrete(c.start):
                    tmp = m.eval(c.start)
                    if not z3util.is_expr_val(tmp):
                        continue
                    start = tmp.as_long()
                    sol.add(c.start == start)
                size = c.size
                if not concrete(c.size):
                    tmp = m.eval(c.size)
                    if not z3util.is_expr_val(tmp):
                        continue
                    size = tmp.as_long()
                    sol.add(c.size == size)

                data = c.memory.read(start, size)
                if isinstance(data, list):
                    if len(data) > 1:
                        data = z3.Concat(*data)
                    elif len(data) == 1:
                        data = data[0]
                    else:
                        raise IntractablePath()
                sha_constraints = dict(sha_constraints)
                sha_constraints[u] = data
                unresolved_todo.append(u)
            else:
                vars = get_vars_non_recursive(c, include_select=True)
                # logging.debug("Trying to resolve %s, vars: %s", u, ','.join(map(str, vars)))
                if any(x.get_id() in unresolved_vars for x in vars):
                    continue
                v = m.eval(c)
                if z3util.is_expr_val(v):
                    sha = big_endian_to_int(sha3(to_bytes(v)))
                    sol.add(c == v)
                    sol.add(u == sha)
                    unresolved.remove(u)
                    progress = True
        todo = new_todo
    if sol.check() != z3.sat:
        raise IntractablePath()
    if todo:
        if second_try:
            raise IntractablePath()
        raise UnresolvedConstraints(unresolved)
    return sol.model()