예제 #1
0
    def _constraints_to_z3(self):
        across_variables = {k: (z3.BitVec("{}-across({})".format(k, len(v)), len(self.words_by_length[len(v)])), v) for k, v in self.acrosses.items()}
        down_variables = {k: (z3.BitVec("{}-down({})".format(k, len(v)), len(self.words_by_length[len(v)])), v) for k, v in self.downs.items()}
        self.s = z3.Solver()
        for variable, info in list(across_variables.values()) + list(down_variables.values()):

            # n & -n == n iff n has exactly one bit set. So this constraint just says
            # each variable represents one exactly one index into the lexicographic ordering.
            # of words of that length.
            self.s.add(variable & -variable == variable)

        for restriction, indices in self.restrictions.items():
            across, across_info = across_variables[restriction[0]]
            down, down_info = down_variables[restriction[1]]
            across_ix, down_ix = indices

            across_letters = []
            down_letters = []
            for letter in string.ascii_uppercase:
                across_bitarray = self.lexicon_bitarrays[len(across_info)][across_ix][letter]
                across_ok = z3.BVRedOr(across_bitarray & across) #) != 0  # TODO check if n & -n == n is faster since we know there is exactly one or 0 set
                down_bitarray = self.lexicon_bitarrays[len(down_info)][down_ix][letter]
                down_ok = z3.BVRedOr(down_bitarray & down) # != 0 # z3.BVRedOr(down_bitarray & down)
                across_letters.append(across_ok)
                down_letters.append(down_ok)

            # for each restriction, the bitarray representing the letter
            # chosen must be the same.
            self.s.add(z3.Concat(across_letters) & z3.Concat(down_letters) != 0)
예제 #2
0
def get_norm_cons_bvArray(varValList, var2dim_dict, minDist):
    normConsList = []
    for (var, val) in varValList:
        n = var2dim_dict[str(var)]
        for i in range(n):
            c_upper_bound = -z3.Concat(var[INT_SIZE * i + 3],
                                       var[INT_SIZE * i + 2],
                                       var[INT_SIZE * i + 1],
                                       var[INT_SIZE * i + 0]) + val[i] >= minDist
            c_lower_bound = z3.Concat(var[INT_SIZE * i + 3],
                                      var[INT_SIZE * i + 2],
                                      var[INT_SIZE * i + 1],
                                      var[INT_SIZE * i + 0]) - val[i] >= minDist

            # c_ne = z3.Concat(var[INT_SIZE * i + 3],
            #                 var[INT_SIZE * i + 2],
            #                 var[INT_SIZE * i + 1],
            #                 var[INT_SIZE * i + 0])\
            #                 != val[i]

            normConsList.append(c_upper_bound)
            normConsList.append(c_lower_bound)

            # normConsList.append(c_ne)

    # return (c_ne)
    return z3.Or(*normConsList)
예제 #3
0
    def feistel(self, inp, key):
        assert key.size() == 96

        # Partition the key into batches of 24 bits.
        k1 = z3.Extract(23,  0, key)
        k2 = z3.Extract(47, 24, key)
        k3 = z3.Extract(71, 48, key)
        k4 = z3.Extract(95, 72, key)

        l = [ z3.Extract(b, b, inp) for b in reversed(fn2_groupB) ]
        l = z3.Concat(l)

        r = [ z3.Extract(a, a, inp) for a in reversed(fn2_groupA) ]
        r = z3.Concat(r)

        l ^= self.fn(r, self.f2_sbox[0], k1)
        r ^= self.fn(l, self.f2_sbox[1], k2)
        l ^= self.fn(r, self.f2_sbox[2], k3)
        r ^= self.fn(l, self.f2_sbox[3], k4)

        # Collect all bits for the return value.
        ret_in  = [ z3.Extract(i, i, l) for i in range(8) ]
        ret_in += [ z3.Extract(i, i, r) for i in range(8) ]

        # Apply the shuffle from groupA and B.
        ret = [None] * 16
        for i, b in enumerate(fn2_groupA + fn2_groupB):
            ret[b] = ret_in[i]

        return z3.simplify(z3.Concat(*reversed(ret)))
예제 #4
0
def itoa_helper(state, value, string, base, sign=True):
    addr = state.evalcon(string).as_long()

    # ok so whats going on here is... uhh it works
    data = [BZERO]
    nvalue = z3.SignExt(96, z3.Extract(31, 0, value))
    pvalue = z3.ZeroExt(64, value)
    do_neg = z3.And(nvalue < 0, base == 10, z3.BoolVal(sign))
    base = z3.ZeroExt(64, base)
    new_value = z3.If(do_neg, -nvalue, pvalue)
    shift = BV(0, 128)
    for i in range(32):
        d = (new_value % bvpow(base, i + 1)) / bvpow(base, i)
        c = z3.Extract(7, 0, d)
        shift = z3.If(c == BZERO, shift + BV(8, 128), BV(0, 128))
        data.append(z3.If(c < 10, c + BV_0, (c - 10) + BV_a))

    pbv = z3.Concat(*data)
    szdiff = pbv.size() - shift.size()
    pbv = pbv >> z3.ZeroExt(szdiff, shift)
    nbv = z3.simplify(z3.Concat(pbv, BV(ord("-"), 8)))
    pbv = z3.simplify(z3.Concat(BV(0, 8), pbv))  # oof
    state.memory[addr] = z3.If(do_neg, nbv, pbv)

    return string
예제 #5
0
def z3_get_memory(memory, address, size, arch):
    value = z3.Select(memory, address)
    for i in range(1, size / 8):
        new_byte = z3.Select(memory, address + i)
        if arch.memory_endness == 'Iend_LE':
            value = z3.Concat(new_byte, value)
        else:
            value = z3.Concat(value, new_byte)
    return value
def opcode_call_data(calldata, data_offset, data_length=32):
    parts = []
    if not is_z3_express(data_length):
        for i in range(format_to_int(data_length)):
            index = opcode_add(data_offset, i)
            parts.append(calldata[index])
        return z3.simplify(z3.Concat(parts))
    print data_length
    exit()
    return z3.Concat(parts)
예제 #7
0
파일: SMT.py 프로젝트: getwindow/SEA
    def getValue(self, op):
        assert (self.m <> None)

        if (op.isReg()):

            #if (literal):
            #
            #
            var = map(lambda b: z3.BitVec(b, 8), op.get_bytes())
            var = map(lambda b: self.m[b], var)
            if (len(var) > 1):
                return z3.simplify(z3.Concat(var)).as_signed_long()
            else:
                return z3.simplify(var[0]).as_signed_long()
        elif (op.isMem()):
            array = z3.Array(op.mem_source, z3.BitVecSort(16),
                             z3.BitVecSort(8))
            #print "debug getValue:"
            #print op, op.mem_offset ,"->", array
            f = self.m[array]
            #print f
            #
            #var = map(lambda b: z3.BitVec(b,8), op.get_bytes())
            #var = map(lambda b: self.m[b], var)
            #
            ##if (self.m):
            #print "eax:"
            #print "%x" % self.m[eax].as_unsigned()
            #assert(0)
            ##print op.mem_source
            ##print op.mem_offset

            es = f.as_list()[:-1]

            var = []

            for i in range(op.size):
                byte = None
                for entry in es:
                    if op.mem_offset + i == entry[0].as_signed_long():
                        byte = entry[1]  #.as_signed_long()
                        break

                if (byte == None):
                    byte = f.else_value()

                var.append(byte)

            var.reverse()

            if (len(var) > 1):
                return z3.simplify(z3.Concat(var)).as_signed_long()
            else:
                return z3.simplify(var[0]).as_signed_long()
def opcode_get_memory(memory, offset, length=32):
    parts = []
    if not is_z3_express(length):
        for i in range(format_to_int(length)):
            index = opcode_add(offset, i)
            parts.append(memory[index])

        return z3.simplify(z3.Concat(parts))

    # delete tail zero
    for i in range(opcode_memory.LENGTH):
        check_get_express = z3.And(i >= offset, i < offset + length)
        parts.append(z3.If(check_get_express, memory[i], z3.BitVecVal(0, 8)))

    return z3.simplify(z3.Concat(parts))
예제 #9
0
    def set_slice(self, ctx, lval, rval):
        slice_l = ctx.resolve_expr(lval.slice_l)
        slice_r = ctx.resolve_expr(lval.slice_r)
        lval = lval.val
        lval, slice_l, slice_r = self.find_nested_slice(lval, slice_l, slice_r)

        # need to resolve everything first, these can be members
        lval_expr = ctx.resolve_expr(lval)

        # z3 requires the extract value to be a bitvector, so we must cast ints
        # actually not sure where this could happen...
        if isinstance(lval_expr, int):
            lval_expr = lval_expr.as_bitvec

        rval_expr = ctx.resolve_expr(rval)

        lval_expr_max = lval_expr.size() - 1
        if slice_l == lval_expr_max and slice_r == 0:
            # slice is full lval, nothing to do
            ctx.set_or_add_var(lval, rval_expr)
            return
        assemble = []
        if slice_l < lval_expr_max:
            # left slice is smaller than the max, leave that chunk unchanged
            assemble.append(z3.Extract(lval_expr_max, slice_l + 1, lval_expr))
        # fill the rval_expr into the slice
        # this cast is necessary to match the margins and to handle integers
        rval_expr = z3_cast(rval_expr, slice_l + 1 - slice_r)
        assemble.append(rval_expr)
        if slice_r > 0:
            # right slice is larger than zero, leave that chunk unchanged
            assemble.append(z3.Extract(slice_r - 1, 0, lval_expr))
        rval_expr = z3.Concat(*assemble)
        ctx.set_or_add_var(lval, rval_expr)
        return
예제 #10
0
def Concat(*args: Union[BitVec, List[BitVec]]) -> BitVec:
    """Create a concatenation expression.

    :param args:
    :return:
    """
    # The following statement is used if a list is provided as an argument to concat
    if len(args) == 1 and isinstance(args[0], list):
        bvs = args[0]  # type: List[BitVec]
    else:
        bvs = cast(List[BitVec], args)

    nraw = z3.Concat([a.raw for a in bvs])
    annotations = []  # type: Annotations
    bitvecfunc = False
    for bv in bvs:
        annotations += bv.annotations
        if isinstance(bv, BitVecFunc):
            bitvecfunc = True

    if bitvecfunc:
        # Is there a better value to set func_name and input to in this case?
        return BitVecFunc(raw=nraw,
                          func_name=None,
                          input_=None,
                          annotations=annotations)

    return BitVec(nraw, annotations)
예제 #11
0
def ZConcat32(a, b):
    # Z3 concat of 32 bit numbers
    # Since the implementation only uses uint64's
    # we have to know the the sizes for the numbers being concated.
    assert a.size() == 32
    assert b.size() == 32
    return z3.Concat(a, b)
예제 #12
0
def Concat(*args: Union[BitVec, List[BitVec]]) -> BitVec:
    """Create a concatenation expression.

    :param args:
    :return:
    """
    # The following statement is used if a list is provided as an argument to concat
    if len(args) == 1 and isinstance(args[0], list):
        bvs = args[0]  # type: List[BitVec]
    else:
        bvs = cast(List[BitVec], args)

    nraw = z3.Concat([a.raw for a in bvs])
    annotations = set()  # type: Annotations

    nested_functions = []  # type: List[BitVecFunc]
    for bv in bvs:
        annotations = annotations.union(bv.annotations)
        if isinstance(bv, BitVecFunc):
            nested_functions += bv.nested_functions
            nested_functions += [bv]

    if nested_functions:
        return BitVecFunc(
            raw=nraw,
            func_name="Hybrid",
            input_=BitVec(z3.BitVec("", 256), annotations=annotations),
            nested_functions=nested_functions,
        )

    return BitVec(nraw, annotations)
예제 #13
0
def _(src, tgt, v):
  w = z3.fpToIEEEBV(v)
  i = z3.If(z3.Or(z3.fpIsZero(v), z3.fpIsSubnormal(v)),
    z3.BitVecVal(0,1),
    z3.BitVecVal(1,1))

  return z3.Concat(z3.Extract(78,63,w), i, z3.Extract(62,0,w))
예제 #14
0
def _padded_operation(a: z3.BitVec, b: z3.BitVec, operator):
    if a.size() == b.size():
        return operator(a, b)
    if a.size() < b.size():
        a, b = b, a
    b = z3.Concat(z3.BitVecVal(0, a.size() - b.size()), b)
    return operator(a, b)
예제 #15
0
def Concat(*args: Union[BitVec, List[BitVec]]) -> BitVec:
    """Create a concatenation expression.

    :param args:
    :return:
    """
    # The following statement is used if a list is provided as an argument to concat
    if len(args) == 1 and isinstance(args[0], list):
        bvs = args[0]  # type: List[BitVec]
    else:
        bvs = cast(List[BitVec], args)

    nraw = z3.Concat([a.raw for a in bvs])
    annotations = set()  # type: Annotations
    bitvecfunc = False
    for bv in bvs:
        annotations = annotations.union(bv.annotations)
        if isinstance(bv, BitVecFunc):
            bitvecfunc = True

    if bitvecfunc:
        # Added this not so good and misleading NOTATION to help with this
        str_hash = ",".join(["hashed({})".format(hash(bv)) for bv in bvs])
        input_string = "MisleadingNotationConcat({})".format(str_hash)

        return BitVecFunc(raw=nraw,
                          func_name="Hybrid",
                          input_=BitVec(z3.BitVec(input_string, 256),
                                        annotations=annotations))

    return BitVec(nraw, annotations)
예제 #16
0
def mkByteVar(op):
    locs = op.getLocations()

    if (len(locs) > 1):
        return z3.Concat(map(lambda b: z3.BitVec(str(b), 8), locs))
    else:
        return z3.BitVec(str(locs[0]), 8)
예제 #17
0
 def u16(r: list):
     if utils.is_all_real(r[0], r[1]):
         return ctypes.c_uint16(r[0] + (r[1] << 8)).value
     else:
         for i in range(len(r)):
             r[i] = utils.to_symbolic(r[i], 8)
         return z3.Concat(r[1], r[0])
예제 #18
0
 def Concat(self, other: BV):
     if isinstance(other, BVV):
         new_value = (self.value << other.size) + other.value
         new_size = self.size + other.size
         new_mask = 2**new_size-1
         return BVV(new_value & new_mask, new_size)
     return BVExpr(self.size + other.size, z3.Concat(self.z3obj, other.z3obj), self.interval.Concat(other.interval))
예제 #19
0
    def read_bv(self, addr, length):
        if type(addr) != int:
            addr = self.bv_to_int(addr)

        data = self.read(addr, length)
        bve = []

        if all(type(x) == int for x in data):
            bv = self.pack_bv(data)
            return bv

        for datum in data:
            if type(datum) == int:
                bve.append(z3.BitVecVal(datum, BYTE))

            else:
                bve.append(datum)

        if self.endian == "little":
            bve.reverse()

        #print(bve)
        if len(bve) > 1:
            bv = z3.simplify(z3.Concat(*bve))
        else:
            bv = z3.simplify(bve[0])

        return bv
예제 #20
0
 def _op_raw_Reverse(a):
     if a.size() == 8:
         return a
     elif a.size() % 8 != 0:
         raise ClaripyOperationError("can't reverse non-byte sized bitvectors")
     else:
         return z3.Concat(*[z3.Extract(i+7, i, a) for i in range(0, a.size(), 8)])
예제 #21
0
def zpad_bv_left(bv, target_len):
    bv_len = bv.size()
    if bv_len == target_len:
        return bv
    elif bv_len < target_len:
        return z3.Concat(bv, z3.BitVecVal(0, target_len - bv_len))
    else:
        raise ValueError('Target length is less then vector size!')
예제 #22
0
 def i32(r: list):
     if utils.is_all_real(r[0], r[1], r[2], r[3]):
         return ctypes.c_int32(r[0] + (r[1] << 8) + (r[2] << 16) +
                               (r[3] << 24)).value
     else:
         for i in range(len(r)):
             r[i] = utils.to_symbolic(r[i], 8)
         return z3.Concat(r[3], r[2], r[1], r[0])
예제 #23
0
def string_concat(x, args):
    cc = x
    if z3.is_string(x):
        for y in args:
            cc = z3.Concat(cc, createZ3ExpressionFromConstraint(y, {}))
        return cc
    else:
        raise NotSupportedException('We only support concat on stirngs as arrays are difficult in z3.')
예제 #24
0
def comp_to_z3(e,solver=None):
    e.simplify()
    parts = [x.to_smtlib(solver) for x in e]
    parts.reverse()
    if len(parts)>1:
        return z3.Concat(*parts)
    else:
        return parts[0]
예제 #25
0
파일: SMT.py 프로젝트: rongqinglee/SEA
    def __getitem__(self, op):

        if (op | iss | InputOp):
            r = ""
            for loc in op.getLocations():
                var = z3.BitVec(str(loc), 8)
                var = self.m[var]
                r = r + ("\\x%.2x" % var.as_long())
            return r

        if (op | iss | RegOp):
            var = map(lambda b: z3.BitVec(str(b), 8), op.getLocations())
            var = map(lambda b: self.m[b], var)
            if (len(var) > 1):
                return z3.simplify(z3.Concat(var)).as_signed_long()
            else:
                return z3.simplify(var[0]).as_signed_long()
        elif (op.isMem()):
            array = z3.Array(op.name, z3.BitVecSort(16), z3.BitVecSort(8))
            f = self.m[array]

            #print self.m

            es = f.as_list()[:-1]

            var = []

            for loc in op.getLocations():
                byte = None
                for entry in es:
                    #print entry
                    if loc.getIndex() == entry[0].as_signed_long():
                        byte = entry[1]  #.as_signed_long()
                        break

                if (byte == None):
                    byte = f.else_value()

                var.append(byte)
            r = ""
            for v in var:
                r = r + ("\\x%.2x" % v.as_long())

            return r

            #var.reverse()

            #if (len(var) > 1):
            #  return z3.simplify(z3.Concat(var)).as_signed_long()
            #else:
            #  return z3.simplify(var[0]).as_signed_long()
        else:
            assert (0)

        r = []
        for loc in i.getLocations():
            r.append(self.vars[str(loc)])
        return r
예제 #26
0
def ZEXTEND(s, size):
    if isinstance(s, Symbol):
        assert s.size <= size
        if s.size != size:
            return BitVec(z3.Concat(z3.BitVecVal(0, size - s.size), s.symbol))
        return s.simplify()
    if isInt(s):
        return s
    assert False
예제 #27
0
def do_POPCOUNT(op, stack, state):
    b, = pop_values(stack, state)

    n = b.size()
    bits = [z3.Extract(i, i, b) for i in range(n)]
    bvs = [z3.Concat(z3.BitVecVal(0, n - 1), b) for b in bits]
    nb = z3.Sum(*bvs)

    stack.append(z3.simplify(nb))
예제 #28
0
 def from_ExprCompose(self, expr):
     res = None
     for arg in expr.args:
         e = z3.Extract(arg.size - 1, 0, self.from_expr(arg))
         if res != None:
             res = z3.Concat(e, res)
         else:
             res = e
     return res
예제 #29
0
 def i64(r: list):
     if utils.is_all_real(r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7]):
         return ctypes.c_int64(r[0] + (r[1] << 8) + (r[2] << 16) +
                               (r[3] << 24) + (r[4] << 32) + (r[5] << 40) +
                               (r[6] << 48) + (r[7] << 56)).value
     else:
         for i in range(len(r)):
             r[i] = utils.to_symbolic(r[i], 8)
         return z3.Concat(r[7], r[6], r[5], r[4], r[3], r[2], r[1], r[0])
예제 #30
0
파일: smt.py 프로젝트: LRGH/amoco
def comp_to_z3(e, slv=None):
    "translate comp expression into its z3 Concat form"
    e.simplify()
    parts = [x.to_smtlib(slv) for x in e]
    parts.reverse()
    if len(parts) > 1:
        return z3.Concat(*parts)
    else:
        return parts[0]