Exemple #1
0
def break_rand(nums: list, next_num: int):
    n_nums = len(nums)
    # print(f'len nums: {n_nums}')

    states = {
        f'state_{i}': z.BitVec(f'state_{i}', 32)
        for i in range(1, n_nums + 2)
    }
    # print(states)
    output_next = z.BitVec('output_next', 32)

    s = z.Solver()

    for i in range(2, n_nums + 2):
        s.add(states[f'state_{i}'] == states[f'state_{i - 1}'] * 214013 +
              2531011)

    for i in range(1, n_nums + 1):
        s.add(
            z.URem((states[f'state_{i}'] >> 16) & 0x7FFF, 100) == nums[i - 1])

    s.add(output_next == z.URem((states[f'state_{n_nums + 1}'] >> 16)
                                & 0x7FFF, 100))

    # print(s)

    if s.check() == z.sat:
        print(f'For the sequence: {nums}, problem is satisfiable')
        print(
            f'We were expecting: {next_num} and got: {s.model()[output_next]}\n'
        )
    else:
        print(f'For the sequence: {nums}, problem is unsatisfiable')

    return s, states, output_next
Exemple #2
0
 def urem(self, ctx, return_type, a, atype, b, btype, nuw=False, nsw=False, exact=False):
     assert atype == return_type
     assert atype == btype
     assert not nuw and not nsw and not exact
     assert util.path_condition_implies(
         ctx, b != z3.BitVecVal(0, btype.size())), "urem by zero"
     return z3.URem(a, b)
Exemple #3
0
 def URem(self, other):
     if isinstance(other, int):
         other = BVV(other, self.size)
     else:
         assert isinstance(other, BV)
         assert self.size == other.size
     return BVExpr(self.size, z3.URem(self.z3obj, other.z3obj), self.interval.URem(other.interval))
Exemple #4
0
    def from_ExprOp(self, expr):
        args = map(self.from_expr, expr.args)
        res = args[0]

        if len(args) > 1:
            for arg in args[1:]:
                if expr.op in self.trivial_ops:
                    res = eval("res %s arg" % expr.op)
                elif expr.op == ">>":
                    res = z3.LShR(res, arg)
                elif expr.op == "a>>":
                    res = res >> arg
                elif expr.op == "<<<":
                    res = z3.RotateLeft(res, arg)
                elif expr.op == ">>>":
                    res = z3.RotateRight(res, arg)
                elif expr.op == "idiv":
                    res = self._idivC(res, arg)
                elif expr.op == "udiv":
                    res = z3.UDiv(res, arg)
                elif expr.op == "imod":
                    res = res - (arg * (self._idivC(res, arg)))
                elif expr.op == "umod":
                    res = z3.URem(res, arg)
                else:
                    raise NotImplementedError("Unsupported OP yet: %s" %
                                              expr.op)
        elif expr.op == 'parity':
            arg = z3.Extract(7, 0, res)
            res = z3.BitVecVal(1, 1)
            for i in xrange(8):
                res = res ^ z3.Extract(i, i, arg)
        elif expr.op == '-':
            res = -res
        elif expr.op == "cnttrailzeros":
            size = expr.size
            src = res
            res = z3.If(src == 0, size, src)
            for i in xrange(size - 1, -1, -1):
                res = z3.If((src & (1 << i)) != 0, i, res)
        elif expr.op == "cntleadzeros":
            size = expr.size
            src = res
            res = z3.If(src == 0, size, src)
            for i in xrange(size, 0, -1):
                index = -i % size
                out = size - (index + 1)
                res = z3.If((src & (1 << index)) != 0, out, res)
        elif expr.op.startswith("zeroExt"):
            arg, = expr.args
            res = z3.ZeroExt(expr.size - arg.size, self.from_expr(arg))
        elif expr.op.startswith("signExt"):
            arg, = expr.args
            res = z3.SignExt(expr.size - arg.size, self.from_expr(arg))
        else:
            raise NotImplementedError("Unsupported OP yet: %s" % expr.op)

        return res
Exemple #5
0
def URem(a: BitVec, b: BitVec) -> BitVec:
    """Create an unsigned remainder expression.

    :param a:
    :param b:
    :return:
    """
    union = a.annotations + b.annotations
    return BitVec(z3.URem(a.raw, b.raw), annotations=union)
Exemple #6
0
 def URem(self, other):
     if isinstance(other, int):
         other = BVV(other, self.size)
     else:
         assert isinstance(other, BV)
         assert self.size == other.size
     if isinstance(other, BVV):
         return BVV((self.value % other.value) & self._mask, self.size)
     return BVExpr(self.size, z3.URem(self.z3obj, other.z3obj), self.interval.URem(other.interval))
Exemple #7
0
def ast_to_z3_expression(ast: Union[AstNode, AstLeaf], use_bitvecval=False):
    if not Z3_INSTALLED:
        raise D810Z3Exception("Z3 is not installed")
    if isinstance(ast, AstLeaf):
        if ast.is_constant():
            return z3.BitVecVal(ast.value, 32)
        return ast.z3_var
    if ast.opcode == m_neg:
        return -(ast_to_z3_expression(ast.left, use_bitvecval))
    elif ast.opcode == m_lnot:
        return not (ast_to_z3_expression(ast.left, use_bitvecval))
    elif ast.opcode == m_bnot:
        return ~(ast_to_z3_expression(ast.left, use_bitvecval))
    elif ast.opcode == m_add:
        return (ast_to_z3_expression(ast.left, use_bitvecval)) + (
            ast_to_z3_expression(ast.right, use_bitvecval))
    elif ast.opcode == m_sub:
        return (ast_to_z3_expression(ast.left, use_bitvecval)) - (
            ast_to_z3_expression(ast.right, use_bitvecval))
    elif ast.opcode == m_mul:
        return (ast_to_z3_expression(ast.left, use_bitvecval)) * (
            ast_to_z3_expression(ast.right, use_bitvecval))
    elif ast.opcode == m_udiv:
        return z3.UDiv(ast_to_z3_expression(ast.left, use_bitvecval=True),
                       ast_to_z3_expression(ast.right, use_bitvecval=True))
    elif ast.opcode == m_sdiv:
        return (ast_to_z3_expression(ast.left, use_bitvecval)) / (
            ast_to_z3_expression(ast.right, use_bitvecval))
    elif ast.opcode == m_umod:
        return z3.URem(ast_to_z3_expression(ast.left, use_bitvecval),
                       ast_to_z3_expression(ast.right, use_bitvecval))
    elif ast.opcode == m_smod:
        return (ast_to_z3_expression(ast.left, use_bitvecval)) % (
            ast_to_z3_expression(ast.right, use_bitvecval))
    elif ast.opcode == m_or:
        return (ast_to_z3_expression(ast.left,
                                     use_bitvecval)) | (ast_to_z3_expression(
                                         ast.right, use_bitvecval))
    elif ast.opcode == m_and:
        return (ast_to_z3_expression(ast.left, use_bitvecval)) & (
            ast_to_z3_expression(ast.right, use_bitvecval))
    elif ast.opcode == m_xor:
        return (ast_to_z3_expression(ast.left, use_bitvecval)) ^ (
            ast_to_z3_expression(ast.right, use_bitvecval))
    elif ast.opcode == m_shl:
        return (ast_to_z3_expression(ast.left, use_bitvecval)) << (
            ast_to_z3_expression(ast.right, use_bitvecval))
    elif ast.opcode == m_shr:
        return z3.LShR(ast_to_z3_expression(ast.left, use_bitvecval),
                       ast_to_z3_expression(ast.right, use_bitvecval))
    elif ast.opcode == m_sar:
        return (ast_to_z3_expression(ast.left, use_bitvecval)) >> (
            ast_to_z3_expression(ast.right, use_bitvecval))
    elif ast.opcode in [m_xdu, m_xds, m_low, m_high]:
        return ast_to_z3_expression(ast.left, use_bitvecval)
    raise D810Z3Exception("Z3 evaluation: Unknown opcode {0} for {1}".format(
        opcode_to_string(ast.opcode), ast))
Exemple #8
0
def _(term, smt):
  x = smt.eval(term.x)

  with smt.local_nonpoison() as ny:
    y = smt.eval(term.y)

  smt.add_defs(y != 0, *ny)

  return z3.URem(x,y)
Exemple #9
0
def do_P(op, stack, state):
    c1 = z3.BitVecVal(0x0101010101010101, SIZE)
    c2 = z3.BitVecVal(0x8040201008040201, SIZE)
    c3 = z3.BitVecVal(0x1FF, SIZE)

    cur = prepare(state.esil["cur"])
    lsb = cur & z3.BitVecVal(0xff, SIZE)
    #pf = (((((lsb * c1) & c2) % c3) & ONE) != 1)
    pf = ((z3.URem(((lsb * c1) & c2), c3) & ONE) != ONE)
    stack.append(z3.If(pf, ONE, ZERO))
Exemple #10
0
        def make_hash_equation(pj: int, var_b: Tuple[int], b1: int):
            domain_bit_count = int(ceil(log2(pj)))
            bc = int(ceil(log2(pj + 1)))
            slices = get_slices(domain_bit_count)

            return z3.URem(
                z3.Sum([
                    z3.ZeroExt(bc - s.size(), s) * z3.BitVecVal(var_b[i], bc)
                    for i, s in enumerate(slices)
                ]) + z3.BitVecVal(b1, bc),
                z3.BitVecVal(pj, bc)) == z3.BitVecVal(0, bc)
Exemple #11
0
    def from_ExprOp(self, expr):
        args = map(self.from_expr, expr.args)
        res = args[0]

        if len(args) > 1:
            for arg in args[1:]:
                if expr.op in self.trivial_ops:
                    res = eval("res %s arg" % expr.op)
                elif expr.op == ">>":
                    res = z3.LShR(res, arg)
                elif expr.op == "a>>":
                    res = res >> arg
                elif expr.op == "a<<":
                    res = res << arg
                elif expr.op == "<<<":
                    res = z3.RotateLeft(res, arg)
                elif expr.op == ">>>":
                    res = z3.RotateRight(res, arg)
                elif expr.op == "idiv":
                    res = res / arg
                elif expr.op == "udiv":
                    res = z3.UDiv(res, arg)
                elif expr.op == "imod":
                    res = res % arg
                elif expr.op == "umod":
                    res = z3.URem(res, arg)
                else:
                    raise NotImplementedError("Unsupported OP yet: %s" %
                                              expr.op)
        elif expr.op == 'parity':
            arg = z3.Extract(7, 0, res)
            res = z3.BitVecVal(1, 1)
            for i in xrange(8):
                res = res ^ z3.Extract(i, i, arg)
        elif expr.op == '-':
            res = -res
        elif expr.op == "bsf":
            size = expr.size
            src = res
            res = z3.If((src & (1 << (size - 1))) != 0, size - 1, src)
            for i in xrange(size - 2, -1, -1):
                res = z3.If((src & (1 << i)) != 0, i, res)
        elif expr.op == "bsr":
            size = expr.size
            src = res
            res = z3.If((src & 1) != 0, 0, src)
            for i in xrange(size - 1, 0, -1):
                index = -i % size
                res = z3.If((src & (1 << index)) != 0, index, res)
        else:
            raise NotImplementedError("Unsupported OP yet: %s" % expr.op)

        return res
Exemple #12
0
def guess_next_number(known):
    n_nums = len(known)
    
    states = {f'state_{i}': z3.BitVec(f'state_{i}', 32) for i in range(1, n_nums + 2)}
    next_number = z3.BitVec('next_number', 32)
    
    s = z3.Solver()

    a = 1103515245
    c = 12345
    m = 16
    for i in range(2, n_nums + 2):
        s.add(states[f'state_{i}'] == states[f'state_{i - 1}'] * a + c)

    for i in range(1, n_nums + 1):
        s.add(z3.URem((states[f'state_{i}'] >> m) & 0x7fff, (0x7f - 0x21)) + 0x21 == known[i - 1])
        
    s.add(next_number == z3.URem((states[f'state_{n_nums + 1}'] >> m) & 0x7fff,  (0x7f - 0x21)) + 0x21)
    
    if s.check() == z3.sat:
        return s.model()[next_number]
    else:
        print(f"Couldn't satisfy constraints for {known}")
        sys.exit(1)
Exemple #13
0
    def initial(self, instance):
        def trim(var, type):
            if var.size() == type.size():
                return var
            return z3.Extract(type.size() - 1, 0, var)
        def extend(var):
            if var.size() < self.get_types()[-1].size():
                v = z3.ZeroExt(self.get_types()[2].size() - var.size(), var)
                return v
            return var

        ref = instance._fields[self._name][0]
        perm1 = lambda fn, idx: trim(z3.UDiv(idx, 16) + 1 , type=self.get_types()[1][0])
        perm2 = lambda fn, idx: trim(z3.URem(idx, 16), type=self.get_types()[1][1])
        perm_inv = lambda fn, owned1, owned2: extend(owned1 - 1) * 16 + extend(owned2 % 16)
        instance._fields[self._name] = (ref, perm1, perm2, perm_inv)
Exemple #14
0
    def from_ExprOp(self, expr):
        args = map(self.from_expr, expr.args)
        res = args[0]

        if len(args) > 1:
            for arg in args[1:]:
                if expr.op in self.trivial_ops:
                    res = eval("res %s arg" % expr.op)
                elif expr.op == ">>":
                    res = z3.LShR(res, arg)
                elif expr.op == "a>>":
                    res = res >> arg
                elif expr.op == "a<<":
                    res = res << arg
                elif expr.op == "<<<":
                    res = z3.RotateLeft(res, arg)
                elif expr.op == ">>>":
                    res = z3.RotateRight(res, arg)
                elif expr.op == "idiv":
                    res = res / arg
                elif expr.op == "udiv":
                    res = z3.UDiv(res, arg)
                elif expr.op == "imod":
                    res = res % arg
                elif expr.op == "umod":
                    res = z3.URem(res, arg)
                else:
                    raise NotImplementedError("Unsupported OP yet: %s" %
                                              expr.op)
        elif expr.op == 'parity':
            arg = z3.Extract(7, 0, res)
            res = z3.BitVecVal(1, 1)
            for i in xrange(8):
                res = res ^ z3.Extract(i, i, arg)
        elif expr.op == '-':
            res = -res
        else:
            raise NotImplementedError("Unsupported OP yet: %s" % expr.op)

        return res
Exemple #15
0
 def walk_bv_urem(self, formula, args, **kwargs):
     return z3.URem(args[0], args[1])
Exemple #16
0
    def to_z3(self, expr):
        """
        Transform an expression into an z3 expression
        :param expr: str
        :return: z3 expression
        """
        stack = []
        # walk over expression
        for e in expr.split(" "):
            # ternary operator
            if e in self.grammar.op3:
                op1 = stack.pop()
                op2 = stack.pop()
                op3 = stack.pop()
                op_type = stack.pop()

                if e == "sign_extend":
                    op1 = self.to_z3_variable(op1)
                    result = z3.SignExt(int(op3) - op1.size(), op1)
                elif e == "bvextract":
                    op3 = self.to_z3_variable(op3)
                    result = z3.Extract(int(op1), int(op2), op3)
                stack.append(result)
            # binary operator
            elif e in self.grammar.op2:
                # operands
                op1 = self.to_z3_variable(stack.pop())
                op2 = self.to_z3_variable(stack.pop())
                op_type = stack.pop()

                # operator
                if e == "bvadd":
                    result = (op2 + op1)
                elif e == "bvsub":
                    result = (op2 - op1)
                elif e == "bvmul":
                    result = (op2 * op1)
                elif e == "bvudiv":
                    result = z3.UDiv(op2, op1)
                elif e == "bvsdiv":
                    result = (op2 / op1)
                elif e == "bvurem":
                    result = z3.URem(op2, op1)
                elif e == "bvsrem":
                    result = z3.SRem(op2, op1)
                elif e == "bvshl":
                    if self.bitsize == 64:
                        op1 &= 63
                    else:
                        op1 &= 31
                    result = (op2 << op1)
                elif e == "bvlshr":
                    if self.bitsize == 64:
                        op1 &= 63
                    else:
                        op1 &= 31
                    result = z3.LShR(op2, op1)
                elif e == "bvashr":
                    if self.bitsize == 64:
                        op1 &= 63
                    else:
                        op1 &= 31
                    result = (op2 >> op1)
                elif e == "bvand":
                    result = (op2 & op1)
                elif e == "bvor":
                    result = (op2 | op1)
                elif e == "bvxor":
                    result = (op2 ^ op1)
                elif e == "zero_extend":
                    result = z3.ZeroExt(int(op2) - op1.size(), op1)
                elif e == "bvconcat":
                    result = z3.Concat(op2, op1)

                stack.append(result)
            # unary operator
            elif e in self.grammar.op1:
                # operand
                op = self.to_z3_variable(stack.pop())
                op_type = stack.pop()

                # operator
                if e == "bvnot":
                    result = ~ op
                elif e == "bvneg":
                    result = - op

                stack.append(result)
            else:
                stack.append(e)

        return stack.pop()
Exemple #17
0
        def _z3_exp(exp, size):

            if isinstance(exp, SymVal):

                if state.has_key(exp.name):

                    return state[exp.name]

                else:

                    return z3.BitVec(exp.name, _z3_size(exp.size))

            elif isinstance(exp, SymConst):

                return z3.BitVecVal(exp.val, _z3_size(exp.size))

            elif isinstance(exp, SymExp):

                a, b = exp.a, exp.b

                assert isinstance(a, SymVal) or isinstance(a, SymConst)
                assert b is None or isinstance(b, SymVal) or isinstance(
                    b, SymConst)
                assert b is None or a.size == b.size

                a = a if a is None else _z3_exp(a, a.size)
                b = b if b is None else _z3_exp(b, b.size)

                # makes 1 bit bitvectors from booleans
                _z3_bool_to_bv = lambda exp: z3.If(exp, z3.BitVecVal(1, 1),
                                                   z3.BitVecVal(0, 1))

                # z3 expression from SymExp
                ret = {
                    I_ADD: lambda: a + b,
                    I_SUB: lambda: a - b,
                    I_NEG: lambda: -a,
                    I_MUL: lambda: a * b,
                    I_DIV: lambda: z3.UDiv(a, b),
                    I_MOD: lambda: z3.URem(a, b),
                    I_SHR: lambda: z3.LShR(a, b),
                    I_SHL: lambda: a << b,
                    I_OR: lambda: a | b,
                    I_AND: lambda: a & b,
                    I_XOR: lambda: a ^ b,
                    I_NOT: lambda: ~a,
                    I_EQ: lambda: _z3_bool_to_bv(a == b),
                    I_LT: lambda: _z3_bool_to_bv(z3.ULT(a, b))
                }[exp.op]()

                size_src = _z3_size(exp.a.size)
                size_dst = _z3_size(size)

                if size_src > size_dst:

                    # convert to smaller value
                    return z3.Extract(size_dst - 1, 0, ret)

                elif size_src < size_dst:

                    # convert to bigger value
                    return z3.Concat(z3.BitVecVal(0, size_dst - size_src), ret)

                else:

                    return ret

            else:

                assert False
    def __init__(self, ns):
        super(Z3python, self).__init__(False, ns, False, True, True)
        self.ctx = z3.Context()
        self.ast_list = []
        self.sort_list = []
        self.bool_sort = self.mk_sort((esbmc.solve.smt_sort_kind.bool, ))
        self.solver = z3.Solver(solver=None, ctx=self.ctx)
        self.fresh_arr_idx = 0

        # No 'int' support at this time
        self.func_map = {
          #SMT_FUNC_ADD
            esbmc.solve.smt_func_kind.bvadd :
                lambda ctx, args, asts: asts[0] + asts[1],
          #SMT_FUNC_SUB
            esbmc.solve.smt_func_kind.bvsub :
                lambda ctx, args, asts: asts[0] - asts[1],
          #SMT_FUNC_MUL,
            esbmc.solve.smt_func_kind.bvmul :
                lambda ctx, args, asts: asts[0] * asts[1],
          #SMT_FUNC_DIV,
            esbmc.solve.smt_func_kind.bvudiv :
                lambda ctx, args, asts: z3.UDiv(asts[0], asts[1]),
            esbmc.solve.smt_func_kind.bvsdiv :
                lambda ctx, args, asts: asts[0] / asts[1],
          #SMT_FUNC_MOD,
            esbmc.solve.smt_func_kind.bvsmod :
                lambda ctx, args, asts: asts[0] % asts[1],
            esbmc.solve.smt_func_kind.bvumod :
                lambda ctx, args, asts: z3.URem(asts[0], asts[1]),
          #SMT_FUNC_SHL,
            esbmc.solve.smt_func_kind.bvshl :
                lambda ctx, args, asts: asts[0] << asts[1],
            esbmc.solve.smt_func_kind.bvashr :
                lambda ctx, args, asts: asts[0] >> asts[1],
          #SMT_FUNC_NEG,
            esbmc.solve.smt_func_kind.bvneg :
                lambda ctx, args, asts: -asts[0],
            esbmc.solve.smt_func_kind.bvlshr :
                lambda ctx, args, asts: z3.LShR(asts[0], asts[1]),
            esbmc.solve.smt_func_kind.bvnot :
                lambda ctx, args, asts: ~asts[0],
          #SMT_FUNC_BVNXOR, These aren't actually used anywhere
          #SMT_FUNC_BVNOR,
          #SMT_FUNC_BVNAND,
            esbmc.solve.smt_func_kind.bvxor :
                lambda ctx, args, asts: asts[0] ^ asts[1],
            esbmc.solve.smt_func_kind.bvor :
                lambda ctx, args, asts: asts[0] | asts[1],
            esbmc.solve.smt_func_kind.bvand :
                lambda ctx, args, asts: asts[0] & asts[1],
            esbmc.solve.smt_func_kind.implies :
                lambda ctx, args, asts: z3.Implies(asts[0], asts[1], ctx),
            esbmc.solve.smt_func_kind.xor :
                lambda ctx, args, asts: asts[0] ^ asts[1],
            esbmc.solve.smt_func_kind._or : # or is a keyword in python
                lambda ctx, args, asts: z3.Or(asts[0], asts[1]),
            esbmc.solve.smt_func_kind._and :
                lambda ctx, args, asts: z3.And(asts[0], asts[1]),
            esbmc.solve.smt_func_kind._not :
                lambda ctx, args, asts: z3.Not(asts[0]),
          #SMT_FUNC_LT,
            esbmc.solve.smt_func_kind.bvslt :
                lambda ctx, args, asts: asts[0] < asts[1],
            esbmc.solve.smt_func_kind.bvult :
                lambda ctx, args, asts: z3.ULT(asts[0], asts[1]),
          #SMT_FUNC_GT,
            esbmc.solve.smt_func_kind.bvsgt :
                lambda ctx, args, asts: asts[0] > asts[1],
            esbmc.solve.smt_func_kind.bvugt :
                lambda ctx, args, asts: z3.UGT(asts[0], asts[1]),
            #SMT_FUNC_LTE,
            # Z3 doesn't do lte's, so invert gt
            esbmc.solve.smt_func_kind.bvslte :
                lambda ctx, args, asts: z3.Not(asts[0] > asts[1]),
            esbmc.solve.smt_func_kind.bvulte :
                lambda ctx, args, asts: z3.Not(z3.UGT(asts[0], asts[1])),
          #SMT_FUNC_GTE,
            esbmc.solve.smt_func_kind.bvsgte :
                lambda ctx, args, asts: z3.Not(asts[0] < asts[1]),
            esbmc.solve.smt_func_kind.bvugte :
                lambda ctx, args, asts: z3.Not(z3.ULT(asts[0], asts[1])),
            esbmc.solve.smt_func_kind.eq :
                lambda ctx, args, asts: asts[0] == asts[1],
            esbmc.solve.smt_func_kind.noteq :
                lambda ctx, args, asts: asts[0] != asts[1],
            esbmc.solve.smt_func_kind.ite :
                lambda ctx, args, asts: z3.If(asts[0], asts[1], asts[2], ctx),
          #SMT_FUNC_STORE, Handled via ast functions
          #SMT_FUNC_SELECT,
            esbmc.solve.smt_func_kind.concat :
                lambda ctx, args, asts: z3.Concat(asts[0], asts[1]),
          #SMT_FUNC_EXTRACT, // Not for going through mk app due to sillyness.
          # Int related stuff
          #SMT_FUNC_INT2REAL,
          #SMT_FUNC_REAL2INT,
          #SMT_FUNC_IS_INT,
        }

        # Various accounting structures for the address space modeling need to
        # be set up, but that needs to happen after the solver is online. Thus,
        # we have to call this once the object is ready to create asts.
        self.smt_post_init()
Exemple #19
0
from rfb_mc.implementation.eamp.eamp_rfmi_z3 import EampRfmiZ3
from rfb_mc.implementation.runner_z3 import FormulaParamsZ3, RunnerZ3
from rfb_mc.types import Params
from rfb_mc.implementation.aws.dynamodb_store import DynamodbStore

dynamodb = boto3.resource("dynamodb")
# should be replaced with used table and requires AWS CLI credentials to be setup
table = dynamodb.Table("rfb_mc_store_test")

RunnerZ3.register_restrictive_formula_module_implementation(EampRfmiZ3)

if __name__ == "__main__":
    k = 20
    x, y, z = z3.BitVecs("x y z", k)
    f = z3.And([
        z3.URem(x, 200) == 0,
        z3.URem(y, 200) == 0,
        z3.ULT(z, x + y),
    ])

    a = 100

    ident = DynamodbStore.create_store_data_entry(
        table,
        Params(bit_width_counter=Counter({k: 2}), ),
    )

    store = DynamodbStore(table, ident)

    scheduler = EampEdgeScheduler(
        store=store,
Exemple #20
0
from rfb_mc.implementation.eamp.eamp_rfmi_z3 import EampRfmiZ3
from rfb_mc.implementation.multi_processing_integrator_z3 import MultiProcessingIntegratorZ3
from rfb_mc.implementation.runner_z3 import RunnerZ3, FormulaParamsZ3
from rfb_mc.implementation.in_memory_store import InMemoryStore
from rfb_mc.store import StoreData
from rfb_mc.types import Params

RunnerZ3.register_restrictive_formula_module_implementation(EampRfmiZ3)

if __name__ == "__main__":
    k = 18
    x, y, z = z3.BitVecs("x y z", k)
    f = z3.And([
        z3.UGE(x, 0),
        z3.UGE(y, 0),
        z3.URem(x, 4) == 0,
        z3.URem(y, 5) == 0,
        z3.ULT(z, x + y),
    ])

    s2 = perf_counter()
    s = perf_counter()

    a = 100

    store = InMemoryStore(data=StoreData(params=Params(
        bit_width_counter=Counter({k: 2}))))

    print(
        f"Initializing InMemoryApproxExecutionManager took {perf_counter() - s:.3f} seconds"
    )
import z3
from rfb_mc.implementation.direct_integrator_z3 import DirectIntegratorZ3
from rfb_mc.implementation.eamp.eamp_edge_scheduler import EampEdgeScheduler
from rfb_mc.implementation.eamp.eamp_rfmi_z3 import EampRfmiZ3
from rfb_mc.implementation.runner_z3 import FormulaParamsZ3, RunnerZ3
from rfb_mc.implementation.in_memory_store import InMemoryStore
from rfb_mc.store import StoreData
from rfb_mc.types import Params

RunnerZ3.register_restrictive_formula_module_implementation(EampRfmiZ3)

if __name__ == "__main__":
    k = 14
    x, y, z = z3.BitVecs("x y z", k)
    f = z3.And([
        z3.URem(x, 13) == 0,
        z3.URem(y, 18) == 0,
        z3.ULT(z, x + y),
    ])

    store = InMemoryStore(data=StoreData(params=Params(
        bit_width_counter=Counter({k: 2}), ), ), )

    scheduler = EampEdgeScheduler(
        store=store,
        confidence=Fraction(0.99),
        a=100,
        q=1,
    )

    integrator = DirectIntegratorZ3(formula_params=FormulaParamsZ3(
Exemple #22
0
def chicken_hash(bytes, m, r):
    return z3.URem(chicken_hash_xor(bytes, m, r), z3.BitVecVal(m, 64))
Exemple #23
0
 def MOD(self, gstate, a, b):
     a, b = map(svm_utils.convert_to_bitvec, (a, b))
     gstate.mstate.stack.append(0 if b == 0 else z3.URem(a, b))
Exemple #24
0
## Compute the average of a and b.  The initial computation we provided
## naively adds them and divides by two, but that is not correct.  Modify
## these lines to implement your solution for both unsigned (u_avg) and
## signed (s_avg) division.
##
## Watch out for the difference between signed and unsigned integer
## operations.  For example, the Z3 expression (x/2) performs signed
## division, meaning it treats the 32-bit value as a signed integer.
## Similarly, (x>>16) shifts x by 16 bits to the right, treating it
## as a signed integer.
##
## Use z3.UDiv(x, y) for unsigned division of x by y.
## Use z3.LShR(x, y) for unsigned (logical) right shift of x by y bits.
# a/2 + b/2 + (a%2) * (b%2)
u_avg = z3.UDiv(a, 2) + z3.UDiv(b, 2) + z3.URem(a, 2) * z3.URem(b, 2)

t = (a & b) + ((a ^ b) >> 1)
s_avg = t + z3.LShR(t, 31) & (a ^ b)

## Do not change the code below.

## To compute the reference answers, we extend both a and b by one
## more bit (to 33 bits), add them, divide by two, and shrink back
## down to 32 bits.  You are not allowed to "cheat" in this way in
## your answer.
az33 = z3.ZeroExt(1, a)
bz33 = z3.ZeroExt(1, b)
real_u_avg = z3.Extract(31, 0, z3.UDiv(az33 + bz33, 2))

as33 = z3.SignExt(1, a)
Exemple #25
0
 def bvurem(self, other):
     return type(self)(z3.URem(self.value, other.value))
# solution space.  Proof takes about 40s on my Haswell-era Xeon.
seed = z3.BitVec('seed', 66)
s.add(seed >= 0, seed < mod)
#s.add(seed >= 0, seed < 1000)

# Start adding constraints to find the seed from a series of outputs.  In my
# testing, only two observed outputs were necessary to find the correct seed.
num_outputs = 2
states = {0: seed}
for i in range(1, num_outputs + 1):
    # Each intermediary state is a function of the previous state (doesn't need
    # an independent z3 variable):
    states[i] = m31_mod((states[i - 1] * mult) + add)

    # Add constraint based on observed output:
    s.add(z3.URem(states[i], outmod) == next(lcg))

# Run the solver!
if s.check() == z3.unsat:
    print "If this happens, enable proof mode w/ z3.set_param above and re-run."
    print s.proof()
    exit()

res = s.model()
print "Solved model:", res

# Test our model:
lcg_verbose = False
# Couldn't find a better way to extract an integer from a z3 BitVec ...
test_model = day18_lcg(int(str( res[seed] )))
test_lcg = day18_lcg(680)
def opcode_mod(opcode_data1, opcode_data2):

    return z3.simplify(z3.URem(opcode_data1, opcode_data2))
Exemple #28
0
def do_MOD(op, stack, state):
    arg1, arg2 = pop_values(stack, state, 2)
    stack.append(z3.URem(arg1, arg2))
Exemple #29
0
 def _op_mod(a, b):
     return z3.URem(a, b)
Exemple #30
0
def run_block(s, solver, log_trace=False):
    def end_trace(reason, *args):
        s.end_type = reason
        s.end_info = args
        pass

    while True:
        op = s.code[s.pc]
        try:
            instr = vm_isa.opcodes[op]
        except KeyError:
            end_trace('invalid')
            return

        if log_trace:
            print('{:04}: {}'.format(s.pc, instr.name))
            print('> ' + ';; '.join(str(z3.simplify(x)) for x in s.stack))
            #print('> {} | {} | {}'.format(stack, mem, store))

        try:
            instr_args = [s.stack.pop() for i in range(instr.pop)]
        except IndexError:
            end_trace('stack underflow')
            return

        def reducestack(fn):
            s.stack.append(fn(*instr_args))

        oplen = 1

        s.gas = s.gas - instr.base_gas
        if instr.extra_gas is not None:
            s.gas = s.gas - instr.extra_gas(s, *instr_args)
        s.gas = z3.simplify(s.gas)

        if op >= 0x80 and op <= 0x8f:  # DUPn
            # instr_args[0] = old top of stack
            for v in reversed(instr_args):
                s.stack.append(v)
            s.stack.append(instr_args[-1])
        elif op >= 0x90 and op <= 0x9f:  #SWAPn
            # Old top of stack pushed first
            s.stack.append(instr_args[0])
            # Then the middle section (in original order)
            for v in reversed(instr_args[1:-1]):
                s.stack.append(v)
            # Then bottom value on top
            s.stack.append(instr_args[-1])
        elif op >= 0x60 and op <= 0x7f:  #PUSHn
            npush = op - 0x60 + 1
            s.stack.append(z3.BitVecVal(util.pushval(s.code, s.pc), 256))
            oplen += npush
        elif instr.name == 'ADD':
            reducestack(lambda x, y: x + y)
        elif instr.name == 'MUL':
            reducestack(lambda x, y: x * y)
        elif instr.name == 'SUB':
            reducestack(lambda x, y: x - y)
        elif instr.name == 'DIV':
            reducestack(lambda x, y: z3.If(y == 0, z3.BitVecVal(0, 256),
                                           z3.UDiv(x, y)))
        elif instr.name == 'SDIV':
            reducestack(lambda x, y: z3.If(
                y == 0, z3.BitVecVal(0, 256),
                z3.If(x == -2**255 and y == -1, z3.BitVecVal(-2**255, 256), x /
                      y)))
        elif instr.name == 'MOD':
            reducestack(lambda x, y: z3.If(y == 0, z3.BitVecVal(0, 256),
                                           z3.URem(x, y)))
        elif instr.name == 'SMOD':
            reducestack(lambda x, y: z3.If(y == 0, z3.BitVecVal(0, 256),
                                           z3.SRem(x, y)))
        elif instr.name == 'ADDMOD':
            reducestack(lambda x, y, z: z3.If(
                z == 0, z3.BitVecVal(0, 256),
                z3.Extract(
                    255, 0,
                    z3.URem(
                        z3.ZeroExt(1, x) + z3.ZeroExt(1, y), z3.ZeroExt(1, z)))
            ))
        elif instr.name == 'MULMOD':
            reducestack(lambda x, y, z: z3.If(
                z == 0, z3.BitVecVal(0, 256),
                z3.Extract(
                    255, 0,
                    z3.URem(
                        z3.ZeroExt(256, x) * z3.ZeroExt(256, y),
                        z3.ZeroExt(256, z)))))
        elif instr.name == 'EXP':
            # TODO z3 currently doesn't seem to provide __pow__ on BitVecs?
            reducestack(lambda x, y: z3.BitVecVal(
                pow(x.as_long(), y.as_long(), 1 << 256), 256))
        elif instr.name == 'LT':
            reducestack(lambda x, y: _bool_to_01(z3.ULT(x, y)))
        elif instr.name == 'GT':
            reducestack(lambda x, y: _bool_to_01(z3.UGT(x, y)))
        elif instr.name == 'SLT':
            reducestack(lambda x, y: _bool_to_01(x < y))
        elif instr.name == 'SGT':
            reducestack(lambda x, y: _bool_to_01(x > y))
        elif instr.name == 'EQ':
            reducestack(lambda x, y: _bool_to_01(x == y))
        elif instr.name == 'ISZERO':
            reducestack(lambda x: _bool_to_01(x == 0))
        elif instr.name == 'AND':
            reducestack(lambda x, y: x & y)
        elif instr.name == 'OR':
            reducestack(lambda x, y: x | y)
        elif instr.name == 'XOR':
            reducestack(lambda x, y: x ^ y)
        elif instr.name == 'NOT':
            reducestack(lambda x: ~x)
        elif instr.name == 'BYTE':
            idx, val = instr_args
            bidx = as_concrete(idx)
            if bidx <= 31:
                s.stack.append(z3.ZeroExt(248, get_byte(val, bidx)))
            else:
                s.stack.append(z3.BitVecVal(0, 256))
        elif instr.name == 'SIGNEXTEND':
            idx, val = instr_args
            bidx = as_concrete(idx)
            if bidx <= 31:
                nbits = 8 * (bidx + 1)
                to_extend = z3.Extract(nbits - 1, 0, val)
                s.stack.append(z3.SignExt(256 - nbits, to_extend))
            else:
                s.stack.append(val)
        elif instr.name == 'CODESIZE':
            s.stack.append(z3.BitVecVal(s.code.size(), 256))
        elif instr.name == 'SHA3':
            start, sz = instr_args
            v = MemoryEmpty
            n = as_concrete(sz)
            for i in range(n):
                v = z3.Store(v, i, s.memory.select(start + i))
            s.stack.append(sha3(v))
            # TODO when n == 0 or all values are concrete, simplify!
            #start, sz = as_concrete(start), as_concrete(sz)
            #stack.append(ethereum.utils.sha3_256([as_concrete(
        elif instr.name in {
                'GASPRICE', 'COINBASE', 'TIMESTAMP', 'NUMBER', 'DIFFICULTY',
                'GASLIMIT', 'ORIGIN'
        }:
            reducestack(getattr(s.transaction, instr.name.lower()))
        elif instr.name in {'BALANCE', 'BLOCKHASH', 'EXTCODESIZE'}:
            reducestack(lambda x: (getattr(s.transaction, instr.name.lower())
                                   ())(x))
        elif instr.name == 'ADDRESS':
            s.stack.append(s.addr)
        elif instr.name == 'CALLVALUE':
            s.stack.append(s.callinfo.value)
        elif instr.name == 'CALLDATASIZE':
            s.stack.append(s.callinfo.calldata.size)
        elif instr.name == 'CALLER':
            s.stack.append(s.caller)
        elif instr.name == 'CODECOPY':
            # TODO handle non-concrete size
            start_mem, start_code, sz = instr_args
            start_code = as_concrete(start_code)
            for i in range(as_concrete(sz)):
                s.memory.store(start_mem + i, s.code[start_code + i])
        elif instr.name == 'CALLDATACOPY':
            src, dest, sz = instr_args
            cd_mem, cd_off, cd_sz = s.callinfo.calldata
            # TODO cache this limited calldata memory object - this is so that
            # out of range calldata reads correctly return 0s
            limited_cdmem = mem.Memory()
            limited_cdmem.overlay(cd_mem, 0, cd_off, cd_sz)
            s.memory.overlay(limited_cdmem, dest, cd_off + src, sz)
        elif instr.name == 'CALLDATALOAD':
            addr, = instr_args
            cd_mem, cd_off, cd_sz, *_ = s.callinfo.calldata
            s.stack.append(
                z3.simplify(
                    z3.Concat(*[
                        z3.If(addr + i < cd_sz, cd_mem.select(cd_off + addr +
                                                              i), 0)
                        for i in range(32)
                    ])))
        elif instr.name == 'RETURNDATASIZE':
            if hasattr(s, retdata):
                s.stack.append(s.retdata.size)
            else:
                s.stack.append(z3.BitVecVal(0, 256))
        elif instr.name == 'RETURNDATACOPY':
            src, dest, sz = instr_args
            # TODO non-concrete length, retdata overflow (should terminate)
            if hasattr(s, retdata):
                for i in range(sz.as_long()):
                    s.memory.store(
                        dest + i,
                        z3.Select(s.retdata.mem, s.retdata.offset + src + i))
        elif instr.name == 'POP':
            pass
        elif instr.name == 'MLOAD':
            addr, = instr_args
            s.stack.append(
                z3.simplify(
                    z3.Concat(*[s.memory.select(addr + i)
                                for i in range(32)])))
        elif instr.name == 'MSTORE':
            dst, word = instr_args
            for i in range(32):
                s.memory.store(dst + i, get_byte(word, i))
        elif instr.name == 'MSTORE8':
            dst, word = instr_args
            s.memory.store(dst, get_byte(word, 31))
        elif instr.name == 'SLOAD':
            addr, = instr_args
            s.stack.append(z3.simplify(z3.Select(s.storage, addr)))
        elif instr.name == 'SSTORE':
            addr, word = instr_args
            s.storage = z3.Store(s.storage, addr, word)
        elif instr.name == 'PC':
            s.stack.append(z3.BitVecVal(s.pc, 256))
        elif instr.name == 'GAS':
            # TODO actually track gas usage?
            s.stack.append(z3.BitVec('{}:GAS'.format(s.pc), 256))
        elif instr.name in 'STOP':
            end_trace('stop')
            return
        elif instr.name == 'RETURN':
            ret_start, ret_size = instr_args
            s.make_child_return(ret_start, ret_size)
            return
        elif instr.name == 'REVERT':
            ret_start, ret_size = instr_args
            s.make_child_revert(ret_start, ret_size)
            return
        elif instr.name in {'CALL', 'CALLCODE', 'DELEGATECALL'}:
            if instr.name in {'CALL', 'CALLCODE'}:
                gas, addr, value, in_off, in_sz, out_off, out_sz = instr_args
                caller = s.addr
            elif instr.name == 'DELEGATECALL':
                gas, addr, in_off, in_sz, out_off, out_sz = instr_args
                value = s.callinfo.value
                caller = s.caller
            else:
                assert False, instr.name
            addr = z3.simplify(addr)
            if instr.name == 'CALL':
                call_addr = addr
                code_addr = addr
            else:
                call_addr = z3.BitVecVal(s.addr, 256)
                code_addr = addr

            callres = z3.BitVec(
                '{}:{}({})'.format(s.pc, instr.name, z3.simplify(call_addr)),
                256)
            s.stack.append(callres)
            if is_concrete(call_addr):
                s.make_child_call(addr=call_addr.as_long(),
                                  code_addr=code_addr.as_long(),
                                  caller=caller,
                                  retinfo=ReturnInfo(s, s.pc + 1, out_off,
                                                     out_sz, callres),
                                  callinfo=CallInfo(
                                      MemRange(s.memory, in_off, in_sz),
                                      z3.BV2Int(gas), value))
                return
            else:
                end_trace('call', call_addr, value, gas)
                s.make_child_branch(
                    new_pc=s.pc + 1,
                    preds=[s.gas > 0,
                           z3.Or(callres == 1, callres == 0)])
                return
        elif instr.name == 'CREATE':
            value, in_off, in_sz = instr_args
            res = z3.BitVec('{}:CREATE({})'.format(s.pc, value), 256)
            s.stack.append(res)
            end_trace('create', value)
            s.make_child_branch(new_pc=s.pc + 1,
                                preds=[s.gas > 0,
                                       z3.Or(res == 0, res == 1)])
            return
        elif instr.name == 'SELFDESTRUCT':
            to_addr = instr_args
            end_trace('suicide', to_addr)
            # No successors
            return
        elif instr.name == 'JUMPI':
            end_trace(None)
            loc, cond = instr_args

            fallthrough_pc = None

            solver.push()
            solver.add(cond == 0)
            fallthrough_state = None
            if solver.check() == z3.sat:
                # Also might not take the jump
                fallthrough_pc = s.pc + 1
            solver.pop()

            solver.push()
            solver.add(cond != 0)
            if solver.check() == z3.sat:
                # OK, can take the jump
                if is_concrete(loc):
                    loc_conc = loc.as_long()
                    if loc_conc == fallthrough_pc:
                        # Fuse fallthrough and jump if to same location
                        fallthrough_pc = None
                        s.make_child_branch(new_pc=loc_conc, preds=[s.gas > 0])
                    else:
                        s.make_child_branch(new_pc=loc_conc,
                                            preds=[s.gas > 0, cond != 0])
                else:
                    for dest in s.code.all_jumpdests():
                        solver.push()
                        solver.add(loc == dest)
                        if solver.check() == z3.sat:
                            if dest == fallthrough_pc:
                                fallthrough_pc = None
                                s.make_child_branch(
                                    new_pc=dest,
                                    preds=[s.gas > 0, loc == dest])
                            else:
                                s.make_child_branch(
                                    new_pc=dest,
                                    preds=[s.gas > 0, cond != 0, loc == dest])
                        solver.pop()
            solver.pop()
            if fallthrough_pc is not None:
                s.make_child_branch(new_pc=fallthrough_pc,
                                    preds=[s.gas > 0, cond == 0])
            return
        elif instr.name == 'JUMP':
            end_trace(None)
            (loc, ) = instr_args
            if is_concrete(loc):
                s.make_child_branch(new_pc=loc.as_long(), preds=[s.gas > 0])
            else:
                successors = []
                for dest in s.code.all_jumpdests():
                    solver.push()
                    solver.add(loc == dest)
                    if solver.check() == z3.sat:
                        s.make_child_branch(new_pc=dest,
                                            preds=[s.gas > 0, loc == dest])
                    solver.pop()
            # No fallthrough
            return
        elif instr.name == 'JUMPDEST':
            s.jumpdests.add(s.pc)
        elif instr.name in {'LOG0', 'LOG1', 'LOG2', 'LOG3', 'LOG4'}:
            pass
        else:
            raise NotImplementedError(instr.name)

        if log_trace:
            print('< ' + ';; '.join(str(z3.simplify(x)) for x in s.stack))
        s.pc += oplen