Пример #1
0
def getTypedZ3ValFromIdentifier(identifier, types):
    if type(identifier) == dict:
        # FIXME how can we handle this here
        raise NotSupportedException('Complex objects as base for operations cannot be modelled in z3')
    if type(identifier) == list:
        arr = z3.Array('ignore_helper_constant_array_' + randomString(), z3.IntSort(), z3.StringSort())
        for i, arg in enumerate(identifier):
            GLOBAL_CONSTRAINTS.append(z3.Select(arr, i) == createZ3ExpressionFromConstraint(arg, types))
        ARRAY_LENGTHS[str(arr.decl())] = len(identifier)
        return arr

    cur_types = types
    GLOBAL_IDENTIFIER.add(identifier)
    cur_types = infered_types[identifier]
    # if cur_types == 'object':
    #    infered_types[identifier] = ''
    #    cur_types = ''
    if identifier.endswith('.length'):
        return z3.Length(z3.String(identifier[:-7]))

    if cur_types == 'string':
        return z3.String(identifier)
    elif cur_types == 'number':
        return z3.Int(identifier)
    elif cur_types == 'boolean':
        return z3.Bool(identifier)
    elif cur_types == 'array':
        return z3.Array(identifier, z3.IntSort(), z3.StringSort())

    if 'event.data' in identifier or 'event.origin' in identifier or 'event' == identifier:
        return z3.String(identifier)
    else:
        MAKE_UNSOLVABLE.add(identifier)
        return z3.String(identifier)
Пример #2
0
def get_z3py_variable(v):
    """Convert the given variable object to a z3py variable"""
    if v.type.base == "Boolean":
        if v.type.size < 1:
            return z3.Bool(v.name)
        else:
            return z3.Array(v.name, z3.IntSort(), z3.BoolSort())
    else:
        if v.type.size < 1:
            return z3.Int(v.name)
        else:
            return z3.Array(v.name, z3.IntSort(), z3.IntSort())
Пример #3
0
  def set_mem(self, address, value):
    unique_name = "mem_{}".format(self.mem_count)
    new_memory = z3.Array(unique_name, z3.BitVecSort(self.arch.bits), z3.BitVecSort(8))
    self.mem_count += 1

    self.memory = utils.z3_set_memory(self.memory, address, value, self.arch)
    self.append_assignment(new_memory, self.memory)
    self.memory = new_memory
Пример #4
0
    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
Пример #5
0
 def _symbol(self, name):
     lightdp_type = self._type_map[name]
     if isinstance(lightdp_type, NumType):
         return z3.Real(name)
     elif isinstance(lightdp_type, ListType):
         if isinstance(lightdp_type.elem_type, NumType):
             return z3.Array(name, z3.RealSort(), z3.RealSort())
         elif isinstance(lightdp_type.elem_type, BoolType):
             return z3.Array(name, z3.BoolSort(), z3.RealSort())
         else:
             raise ValueError('Unsupported list inside list.')
     elif isinstance(lightdp_type, FunctionType):
         raise NotImplementedError(
             'Function type is currently not supported.')
     elif isinstance(lightdp_type, BoolType):
         return z3.Bool(name)
     else:
         assert False, 'No such type %s' % lightdp_type
Пример #6
0
def mem_to_z3(e,solver=None):
    e.simplify()
    M = z3.Array('M',z3.BitVecSort(e.a.size),z3.BitVecSort(8))
    p = e.a.to_smtlib(solver)
    b = []
    for i in range(0,e.length):
        b.insert(0,M[p+i])
    if e._endian==-1: b.reverse() # big-endian case
    if len(b) > 1: return z3.Concat(*b)
    return b[0]
Пример #7
0
    def __init__(self, name: str, domain: int, value_range: int):
        """Initializes a symbolic array.

        :param name: Name of the array
        :param domain: The domain for the array (10 -> all the values that a bv of size 10 could take)
        :param value_range: The range for the values in the array (10 -> all the values that a bv of size 10 could take)
        """
        self.domain = z3.BitVecSort(domain)
        self.range = z3.BitVecSort(value_range)
        self.raw = z3.Array(name, self.domain, self.range)
Пример #8
0
    def _switch_to_symbolic(self):
        if self._conc_store is not None:
            assert self._z3obj is None
            self._z3obj = z3.Array(self.name, z3.BitVecSort(self.index_width),
                                   z3.BitVecSort(self.value_width))
            for index in self._conc_store:
                self._z3obj = z3.Store(self._z3obj,
                                       z3.BitVecVal(index, self.index_width),
                                       self._conc_store[index].z3obj)

            self._conc_store = None
Пример #9
0
    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()
Пример #10
0
Файл: smt.py Проект: LRGH/amoco
def mem_to_z3(e, slv=None):
    "translate mem expression into z3 a Concat of BitVec bytes"
    e.simplify()
    M = z3.Array("M", z3.BitVecSort(e.a.size), z3.BitVecSort(8))
    p = e.a.to_smtlib(slv)
    b = []
    for i in range(0, e.length):
        b.insert(0, M[p + i])
    if e.endian == -1:
        b.reverse()  # big-endian case
    if len(b) > 1:
        return z3.Concat(*b)
    return b[0]
Пример #11
0
 def visit_Quantification(self, node : Quantification):
     bound_var = None
     if node.ty == TINT:
         bound_var = z3.Int(node.var.name)
     elif node.ty == TBOOL:
         bound_var = z3.Bool(node.var.name)
     elif isinstance(node.ty, TARR):
         bound_var = z3.Array(z3.IntSort(), self.translate_type(node.ty.ty))
     if bound_var is not None:
         self.name_dict[node.var.name] = bound_var
         return z3.ForAll(bound_var, self.visit(node.expr))
     else:
         raise Exception(f'Unsupported quantified type: {node.ty}')
Пример #12
0
  def get_smt_statements(self, irsb, irsb_num):
    self.irsb_num = irsb_num
    for stmt in irsb.statements:
      if hasattr(self, stmt.tag):
        getattr(self, stmt.tag)(stmt)
      else:
        return None

    # Make some _after variables so it's easy to get their value
    for name, reg in self.out_regs.items():
      self.append_assignment(reg, z3.BitVec('{}_after'.format(self.arch.translate_register_name(name)), reg.size()))
    self.append_assignment(self.memory, z3.Array("mem_after", z3.BitVecSort(self.arch.bits), z3.BitVecSort(8)))

    return self.stmt
Пример #13
0
 def get_mem_array(self, size):
     """Returns a z3 Array used internally to represent memory for addresses
     of size @size.
     @size: integer, size in bit of addresses in the memory to get.
     Return a z3 Array: BitVecSort(size) -> BitVecSort(8).
     """
     try:
         mem = self.mems[size]
     except KeyError:
         # Lazy instantiation
         self.mems[size] = z3.Array(self.name + str(size),
                                    z3.BitVecSort(size), z3.BitVecSort(8))
         mem = self.mems[size]
     return mem
Пример #14
0
    def _try_build_reduced_array(self, index_min, index_max):
        if self._z3obj is not None:
            # symbolic mode
            return self._z3obj
        if index_max - index_min >= 2**self.index_width:
            return self.z3obj

        res = z3.Array(self.name, z3.BitVecSort(self.index_width),
                       z3.BitVecSort(self.value_width))
        for i in range(index_min, index_max + 1):
            if i in self._conc_store:
                res = z3.Store(res, z3.BitVecVal(i, self.index_width),
                               self._conc_store[i].z3obj)
        return res
Пример #15
0
def get_z3_equality_list(stmt_node, z3_vars, direct_equality= False):
    global all_z3_vars
    z3_asserts = []
    if not direct_equality:
        stmt_node = stmt_node.children[0]  ## get the equalitystmt first

    left = stmt_node.children[0]
    right = stmt_node.children[1]
    zright = get_z3_expr(right, z3_vars)

    name = "stmt_rhs_{}".format(stmt_node.line)
    i = 0
    temp_name = name
    while (temp_name in all_z3_vars):
        temp_name = name + "_" + str(i)
        i += 1
    name = temp_name
    zright_temp = z3.Int(name)  
    z3_asserts.append(zright_temp == zright)
    all_z3_vars[name] = zright_temp

    if left.data == "select":
        # we need to update the z3_vars
        array_name = left.children[0].children[0].value
        current_label = z3_vars[array_name][1]
        current_array = z3_vars[array_name][0]
        new_label = current_label + 1
        new_name = "{}_{}".format(array_name, new_label)
        new_array = z3.Array(new_name, z3.IntSort(), z3.IntSort())
        all_z3_vars[new_name] = new_array
        if (left.children[1].data == "var"):
            index = z3_vars[left.children[1].children[0].value][0]
        else: #left children is num
            index = left.children[1].children[0].value

        store = z3.Store(current_array, index, zright_temp)
        z3_vars[array_name] = (new_array, new_label)
        z3_asserts.append(new_array == store)  #LHS equal to new variable

    if left.data == "var":
        var_name = left.children[0].value
        var_label = z3_vars[var_name][1]
        new_name = "{}_{}".format(var_name, var_label+1)
        new_var = z3.Int(new_name)
        all_z3_vars[new_name] = new_var # add the new variable to global list
        z3_vars[var_name] = (new_var, var_label + 1)
        z3_asserts.append(new_var == zright_temp)
    
    return [(assertion, stmt_node) for assertion in z3_asserts]
Пример #16
0
def substitute_bvset(bvset, prefix):
    index = 0
    substitution_dict = {}
    for bv in bvset:
        if type(bv) == z3.BitVecRef:
            substitution_dict[bv] = z3.BitVec(
                '{}_{}_{}'.format(bv, prefix, index), bv.size())
        elif type(bv) == z3.ArrayRef:
            substitution_dict[bv] = z3.Array(
                '{}_{}_{}'.format(bv, prefix, index),
                bv.sort().domain(),
                bv.sort().range())
        index += 1

    return substitution_dict
Пример #17
0
    def z3obj(self):
        if self._z3obj is not None:
            # symbolic mode
            return self._z3obj

        # concrete mode
        if self._z3objConcCache is not None:
            return self._z3objConcCache
        res = z3.Array(self.name, z3.BitVecSort(self.index_width),
                       z3.BitVecSort(self.value_width))
        for index in self._conc_store:
            res = z3.Store(res, z3.BitVecVal(index, self.index_width),
                           self._conc_store[index].z3obj)
        self._z3objConcCache = res
        return res
Пример #18
0
def main():
    b, c = z3.Ints("b c")
    a = z3.Array("a", z3.IntSort(), z3.IntSort())
    f = z3.Function("f", z3.IntSort(), z3.IntSort())
    solver = z3.Solver()
    solver.add(c == b + z3.IntVal(2))
    lhs = f(z3.Store(a, b, 3)[c - 2])
    rhs = f(c - b + 1)
    solver.add(lhs != rhs)
    res = solver.check()
    if res == z3.sat:
        print("sat")
    elif res == z3.unsat:
        print("unsat")
    else:
        print("unknown")
Пример #19
0
def main():
    b, c = z3.Ints('b c')
    a = z3.Array('a', z3.IntSort(), z3.IntSort())
    f = z3.Function('f', z3.IntSort(), z3.IntSort())
    solver = z3.Solver()
    solver.add(c == b + z3.IntVal(2))
    lhs = f(z3.Store(a, b, 3)[c - 2])
    rhs = f(c - b + 1)
    solver.add(lhs <> rhs)
    res = solver.check()
    if res == z3.sat:
        print 'sat'
    elif res == z3.unsat:
        print 'unsat'
    else:
        print 'unknown'
Пример #20
0
  def __init__(self, arch):
    self.arch = arch
    self.stmt = []
    self.out_regs = {}
    self.reg_count = collections.defaultdict(int, {})

    # Make sure all the registers have initial BitVecs in the constraints
    for name, (num, size) in self.arch.registers.items():
      real_name = self.arch.translate_register_name(num) # So we don't get both sp and rsp, ip and rip, etc.
      if real_name not in self.out_regs and real_name not in extra_archinfo.IGNORED_REGISTERS[self.arch.name]:
        self.out_regs[num] = z3.BitVec("{}_before".format(real_name), size * 8)

    # Setup the initial memory
    self.memory = z3.Array("mem_before", z3.BitVecSort(self.arch.bits), z3.BitVecSort(8))
    self.mem_count = 0
    self.first_mem = self.memory
Пример #21
0
    def get_sym_bitvec(self, constraint_type, gen, bv_size=256, unique=False, **kwargs):
        vector_name = ConstraintType[constraint_type.name].value
        label_template = vector_name + '_gen{}'
        for k in kwargs:
            label_template += '_' + k + '{' + k + '}'
        label = label_template.format(gen, **kwargs)
        if unique:
            unique_id = self.unique_vector_name_counter.get(vector_name, 0)
            self.unique_vector_name_counter[vector_name] = unique_id + 1
            label = label + '_uid' + str(unique_id)
        assert constraint_type != ConstraintType.CALLDATA or 'acc' not in kwargs

        if constraint_type == ConstraintType.CALLDATA_ARRAY:
            return z3.Array(label, z3.BitVecSort(bv_size), z3.BitVecSort(8))
        elif constraint_type in [ConstraintType.CALLER, ConstraintType.ORIGIN, ConstraintType.ENTRY_ACCOUNT]:
            return svm_utils.zpad_bv_right(z3.BitVec(label, svm_utils.ADDRESS_LEN), svm_utils.VECTOR_LEN)
        else:
            return z3.BitVec(label, bv_size)
Пример #22
0
def getZ3ValFromJSVal(val):
    if type(val) == str:
        return z3.StringVal(val)
    if type(val) == bool:
        return z3.BoolVal(val)
    if type(val) == int:
        return z3.IntVal(val)
    if type(val) == int:
        return z3.IntVal(val)
    if type(val) == list:
        arr = z3.Array('ignore_helper_constant_array_' + randomString(), z3.IntSort(), z3.StringSort())
        for i, arg in enumerate(val):
            GLOBAL_CONSTRAINTS.append(z3.Select(arr, i) == createZ3ExpressionFromConstraint(arg, {}))
        ARRAY_LENGTHS[str(arr.decl())] = len(val)
        return arr
    if type(val) == dict:
        raise NotSupportedException('Complex Objects as base for operations with proxy strings are not yet supported!')

    raise Exception('Could not transform Js val to Z3 Val' + repr(val))
Пример #23
0
    def _solve(self):
        self._field = z3.Array('f', z3.IntSort(), z3.BoolSort())
        self._solver = z3.Solver()
        width = len(self._vertical_hints)
        height = len(self._horizontal_hints)
        for i, c in enumerate(self._horizontal_hints):
            self._add_column(c, 1, i * width, width, 'h%d' % i)

        for i, c in enumerate(self._vertical_hints):
            self._add_column(c, width, i, height, 'v%d' % i)
        res = self._solver.check()
        if str(res) != 'sat':
            return None
        m = self._solver.model()
        f0 = [[False for i in xrange(height)] for j in xrange(width)]
        for j in xrange(height):
            for i in xrange(width):
                f0[i][j] = str(m.eval(self._field[j * width + i])) == 'True'
        return f0
Пример #24
0
    def VertexNameToSmt(self):
        assert(self.type != VertexNode.VertexType.NONE and \
               self.type != VertexNode.VertexType.FUNC)

        if self.type == VertexNode.VertexType.VAR:
            return z3.BitVec(self.__str__(), self.bitlength)

        if self.type == VertexNode.VertexType.TEMP:
            # is it a boolean?
            if self.bitlength == -1:
                return z3.Bool(self.__str__())
            return z3.BitVec(self.__str__(), self.bitlength)

        if self.type == VertexNode.VertexType.IMM:
            return z3.BitVecVal(self.value, self.bitlength)

        if self.type == VertexNode.VertexType.ARR:
            return z3.Array(self.__str__(), \
                            z3.BitVecSort(self.arrayIndexBitlength), \
                            z3.BitVecSort(self.arrayElBitlength))
Пример #25
0
    def getValue(self, op):
        assert (self.m <> None)

        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)

            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)
Пример #26
0
def string_split(x, args):
    st = x
    split_val = z3.StringVal(args[0].encode())
    x = transformNonBooleanLazyEvaluations(x)
    arr = z3.Array('__ignore_{}.split({})'.format(str(x), str(args[0])), z3.IntSort(), z3.StringSort())
    for i in range(3):
        index = z3.IndexOf(st, split_val, 0)
        s = z3.SubString(st, 0, index)
        st = z3.SubString(st, index + z3.Length(split_val), z3.Length(st))
        GLOBAL_CONSTRAINTS.append(z3.Select(arr, i) == s)
        GLOBAL_CONSTRAINTS.append(s != z3.StringVal(''))
        GLOBAL_ARRAY_HANDLER[arr].append(s)
    GLOBAL_CONSTRAINTS.append(z3.Select(arr, 3) == st)
    GLOBAL_CONSTRAINTS.append(st != z3.StringVal(''))
    GLOBAL_ARRAY_HANDLER[arr].append(st)
    # We just guess the length here and hope that this works for the program
    ARRAY_LENGTHS[str(arr.decl())] = 4

    GLOBAL_CONSTRAINTS.append(z3.IndexOf(GLOBAL_ARRAY_HANDLER[arr][-1], split_val, 0) == -1)
    # GLOBAL_CONSTRAINTS.append(z3.PrefixOf(GLOBAL_ARRAY_HANDLER[arr][0], x))

    return arr
Пример #27
0
    def _switch_to_symbolic(self, soft=False):
        if self._mode == BVArrayState.SEMI_CONCRETE_MODE and soft:
            return

        if self._mode == BVArrayState.SEMI_CONCRETE_MODE and not soft:
            self._mode = BVArrayState.SYMBOLIC_MODE
            self._conc_store = None
            return

        if self._mode == BVArrayState.CONCRETE_MODE:
            assert self._z3obj is None
            self._z3obj = z3.Array(self.name, z3.BitVecSort(self.index_width),
                                   z3.BitVecSort(self.value_width))
            # The solver needs to add those constraints! (even lazly)
            for index in self._conc_store:
                self._assertions[index] = \
                    BoolExpr(z3.Select(
                        self._z3obj, index) == self._conc_store[index].z3obj)

            if soft:
                self._mode = BVArrayState.SEMI_CONCRETE_MODE
            else:
                self._mode = BVArrayState.SYMBOLIC_MODE
                self._conc_store = None
Пример #28
0
def makeZ3Var(v):
    t = v.varType
    name = v.varName
    if t.startswith('INSTANCE:'):
        s = t[9:]
        if s == 'BYTE':
            return z3.Array(name, BitVecSort(32), z3.BitVecSort(8))
        elif s == 'SHORT':
            return z3.Array(name, BitVecSort(32), z3.BitVecSort(16))
        elif s == 'INT':
            return z3.Array(name, BitVecSort(32), z3.BitVecSort(32))
        elif s == 'LONG':
            return z3.Array(name, BitVecSort(32), z3.BitVecSort(64))
        elif s == 'FLOAT':
            return z3.Array(name, BitVecSort(32), Float)
        elif s == 'DOUBLE':
            return z3.Array(name, BitVecSort(32), Double)
        elif s == 'CHAR':
            return z3.Array(name, BitVecSort(32), z3.BitVecSort(16))
        else:
            raise Exception("unsupported type {}".format(t))
    elif t == 'BYTE':
        return z3.BitVec(name, 8)
    elif t == 'SHORT':
        return z3.BitVec(name, 16)
    elif t == 'INT':
        return z3.BitVec(name, 32)
    elif t == 'LONG':
        return z3.BitVec(name, 64)
    elif t == 'FLOAT':
        return z3.FP(name, Float)
    elif t == 'DOUBLE':
        return z3.FP(name, Double)
    elif t == 'CHAR':
        return z3.BitVec(name, 16)
    else:
        raise Exception("unsupported type {}".format(t))
Пример #29
0
import itertools
import re
import z3

base = 'plaidctf'
r = open('regex_57f2cf49f6a354b4e8896c57a4e3c973.txt').read().strip()

s = re.search(r'\((.*)\)', r).group(1)
s = s.split('|')[3:]
s = [re.findall(r'(.*?)\[(.*?)\]', it) for it in s]

solver = z3.Solver()
sol = z3.Array('sol', z3.IntSort(), z3.BoolSort())

for x in s:
    pos = 0
    rule = []
    for a, b in x:
        m = re.match(r'\.{(\d+)}', a)
        if m:
            pos += int(m.group(1))
        else:
            pos += len(a)
        b = [base.index(it) for it in b]
        b = [bin(it)[2:].rjust(3, '0') for it in b]
        b = zip(*b)
        for j, y in enumerate(b):
            y = [it == '1' for it in y]
            var = sol[pos * 3 + j]
            if all(it == True for it in y):
                rule.append(var)
Пример #30
0
 def get_mem(self, name):       return z3.Array("mem_{}".format(name), z3.BitVecSort(self.arch.bits), z3.BitVecSort(8))
 def get_mem_before(self):      return self.get_mem("before")