Exemplo n.º 1
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
Exemplo n.º 2
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
Exemplo n.º 3
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)
Exemplo n.º 4
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]
Exemplo n.º 5
0
Arquivo: SMT.py Projeto: 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()
Exemplo n.º 6
0
    def test_z3_to_array_doc(self):
        s = z3.BitVecSort(8)
        s2 = z3.BitVecSort(2)

        def bv(x):
            return z3.BitVecVal(x, s)

        def bv2(x):
            return z3.BitVecVal(x, s2)

        x = z3.Var(0, s)
        y = z3.Var(1, s)
        types = [primitives.TYPES['int4']] * 2
        e1 = z3.Extract(3, 2, x) == bv2(3)
        e2 = z3.And(
            z3.Extract(3, 2, x) == bv2(3),
            z3.Extract(7, 6, x) == bv2(2))
        e3 = z3.And(
            z3.Extract(3, 2, x) == bv2(3),
            z3.Extract(7, 6, x) == bv2(2), y == bv(4))
        e4 = z3.And(
            z3.Extract(5, 4, x) == bv2(1),
            z3.Not(
                z3.And(
                    z3.Extract(3, 2, x) == bv2(3),
                    z3.Extract(7, 6, x) == bv2(2), y == bv(4))))
        e5 = z3.And(
            True, z3.Not(z3.Extract(5, 4, x) == bv2(1)),
            z3.Not(
                z3.And(
                    z3.Extract(3, 2, x) == bv2(3),
                    z3.Extract(7, 6, x) == bv2(2), y == bv(4))))

        r1 = [z3r.Cube({0: z3r.Masked(0xc, 0xc)}, 1)]
        r2 = [z3r.Cube({0: z3r.Masked(0x8c, 0xcc)}, 1)]
        r3 = [z3r.Cube({0: z3r.Masked(0x8c, 0xcc), 1: 4}, 1)]
        r4 = [
            z3r.Doc(z3r.Cube({0: z3r.Masked(0x10, 0x30)}, 1),
                    [z3r.Cube({
                        0: z3r.Masked(0x8c, 0xcc),
                        1: 4
                    }, 1)])
        ]
        r5 = [
            z3r.Doc(z3r.Cube({}, 1), [
                z3r.Cube({0: z3r.Masked(0x10, 0x30)}, 1),
                z3r.Cube({
                    0: z3r.Masked(0x8c, 0xcc),
                    1: 4
                }, 1)
            ])
        ]
        for (r, e) in [(r1, e1), (r2, e2), (r3, e3), (r4, e4), (r5, e5)]:
            self.assertEqual(r, z3r.z3_to_array(e, types))
Exemplo n.º 7
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
Exemplo n.º 8
0
def sorts(name):
    if name.startswith('bv[') and name.endswith(']'):
        width = int(name[3:-1])
        return z3.BitVecSort(width)
    if name.startswith('strbv[') and name.endswith(']'):
        width = int(name[6:-1])
        return z3.BitVecSort(width)
    if name == 'int':
        return z3.IntSort()
    if name == 'strlit':
        return z3.StringSort()
    return None
Exemplo n.º 9
0
 def __init__(self, name, param_type, return_type):
     self.name = name
     self.param_type = param_type
     self.return_type = return_type
     key_sorts = []
     for t in param_type:
         key_sorts.append(z3.BitVecSort(t * 8))
     val_sort = None
     if val_sort == 'bool':
         val_sort = z3.BoolSort()
     else:
         val_sort = z3.BitVecSort(return_type * 8)
     self.uf = z3.Function(fresh_name(self.name), *key_sorts, val_sort)
Exemplo n.º 10
0
Arquivo: smt.py Projeto: 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]
Exemplo n.º 11
0
def _ty_sort(ty):
    'Translate a Type expression to a Z3 Sort'

    if isinstance(ty, IntType):
        return z3.BitVecSort(ty.width)

    return {
        PtrType: z3.BitVecSort(64),
        HalfType: z3.FloatHalf(),
        SingleType: z3.Float32(),
        DoubleType: z3.Float64(),
        FP128Type: z3.Float128(),
        X86FP80Type: z3.FPSort(15, 64),
    }[type(ty)]
Exemplo n.º 12
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
Exemplo n.º 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
Exemplo n.º 14
0
def wall2():
    global p
    #setup the key to expand
    logger.info("setting up sym args")
    key = claripy.BVS('key', 8 * 16)
    keyarr = [key.get_byte(i) for i in range(16)]
    #Make sure angr only uses 1 solver
    s = p.factory.blank_state(remove_options={angr.options.COMPOSITE_SOLVER})
    s.add_constraints(*[k != '\0' for k in keyarr])

    logger.info("starting symbolic execution on aes")
    aes_addr = p.loader.find_symbol('malicious_aes_test').rebased_addr
    aes = p.factory.callable(aes_addr, base_state=s)
    #when calling the function, use the python list so angr makes a pointer
    r = aes(keyarr)
    s = aes.result_state
    s.add_constraints(r == 3)

    #now we are going to use the tuples generated by Te4_lookup
    # we will build a z3 function then use a symbolic index
    # this is much faster than state.memory.load with a symbolic addr
    z3_table = z3.Function("Te4", z3.BitVecSort(8), z3.BitVecSort(8))
    #there is only one solver because we specified no composite solver option
    z3_solver = s.solver._solver._get_solver()
    #extract the Te4 table from program memory and turn it into a z3 func
    Te4 = p.loader.find_symbol("Te4").rebased_addr
    for i in range(256):
        z3_solver.add(z3_table(i) == s.mem[Te4 + i * 4].uint8_t.concrete)
    #for each tuple saved in Te4_lookup, convert to z3 bv then
    # assert that the index and result are related via the z3 function
    for e in s.globals['table_lookups']:
        idx, res = map(claripy.backends.z3.convert, e)
        z3_solver.add(z3_table(idx) == res)
    #ensure the problem is sat
    logger.info("Checking satisfiability")
    query = z3_solver.check()
    logger.info(query)
    assert (query == z3.sat)
    logger.info("Getting model")
    m = z3_solver.model()
    #make our function's input a z3 bv
    z3key = claripy.backends.z3.convert(key)

    def long_to_str(l):
        return hex(l)[2:].replace('L', '').decode('hex')

    resolved_key = long_to_str(m[z3key].as_long())
    logger.info("KEY: %s", repr(resolved_key))
    # KEY: 'ACHIEVEMENTAWARD'
    return [resolved_key]
Exemplo n.º 15
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
Exemplo n.º 16
0
 def __init__(self, name, z3_args, parent_const=None):
     self.p4_attrs = {}
     self.name = name
     self.z3_type = z3.BitVecSort(32)
     for idx, enum_name in enumerate(z3_args):
         self.p4_attrs[enum_name] = z3.BitVecVal(idx, 32)
     self.z3_args = z3_args
Exemplo n.º 17
0
def _populate_enums():
    module = sys.modules[__name__]
    ctx = libirpy.newctx()
    import hv6py.kernel.impl as hv6
    hv6._init_metadata(ctx)
    for k, v in ctx.metadata.items():
        if isinstance(v, tuple) and v[0] == 'DICompositeType':
            if v[1].get('tag') == 'DW_TAG_enumeration_type':
                name = v[1].get('name')
                size = v[1].get('size')
                elements = v[1].get('elements')

                if name is None or size is None or elements is None:
                    continue

                setattr(module, name + '_t', z3.BitVecSort(size))
                enum = {}

                for element in ctx.metadata.get(elements):
                    element = ctx.metadata.get(element)
                    assert element[0] == 'DIEnumerator'
                    element_name = element[1].get('name')
                    element_value = element[1].get('value')
                    enum[element_name] = z3.BitVecVal(element_value, size)

                setattr(module, name, type(name, (), enum))
Exemplo n.º 18
0
 def __init__(self, name, fields):
     self.locals = {}
     self.name = name
     self.z3_type = z3.BitVecSort(32)
     for idx, enum_name in enumerate(fields):
         self.locals[enum_name] = z3.BitVecVal(idx, 32)
     self.fields = fields
Exemplo n.º 19
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
 def test_translate(self):
     fp = z3.Fixedpoint()
     atom1 = ast.Atom('p', [
         ast.NumConstant(2, 'int4'),
         ast.NumConstant(3, 'int4'),
         ast.Variable('X', 'int4')
     ])
     atom2 = ast.Atom('p', [
         ast.NumConstant(2, 'int4'),
         ast.NumConstant(3, 'int4'),
         ast.Variable('Y', 'int4')
     ])
     int4 = z3.BitVecSort(4)
     p = z3.Function('p', int4, int4, int4, z3.BoolSort())
     a0 = z3.BitVecVal(2, int4)
     a1 = z3.BitVecVal(3, int4)
     a2 = z3.Const('X', int4)
     a3 = z3.Const('Y', int4)
     args1 = [a0, a1, a2]
     args2 = [a0, a1, a3]
     project = projection.Projection([], None)
     project.grounded = {'p': (0, 1)}
     project.items = {'p': {}}
     project.relations = {'p': p}
     result = project.translate(fp, atom1, args1)
     self.assertIn((0, 1), project.items['p'])
     self.assertIn((a0, a1), project.items['p'][(0, 1)])
     p0 = project.items['p'][(0, 1)][(a0, a1)]
     self.assertIs(True, z3.is_true(z3.simplify(p0(a2) == result)))
     result2 = project.translate(fp, atom2, args2)
     self.assertIs(True, z3.is_true(z3.simplify(p0(a3) == result2)))
Exemplo n.º 21
0
def do_F2I(op, stack, state):
    prev_type = state.esil["type"]
    state.esil["type"] = FLOAT

    val, = pop_values(stack, state)
    stack.append(z3.fpToUBV(FPM, val, z3.BitVecSort(SIZE)))

    state.esil["type"] = prev_type
Exemplo n.º 22
0
 def test_z3_to_array_fails(self):
     s = z3.BitVecSort(4)
     x = z3.Const('x', s)
     types = [primitives.TYPES['int4']]
     self.assertRaises(obase.Z3NotWellFormed,
                       lambda: z3r.z3_to_array(x, types))
     self.assertRaises(obase.Z3NotWellFormed,
                       lambda: z3r.z3_to_array(z3.Or(x > 2, x < 1), types))
Exemplo n.º 23
0
 def z3BitVecSort(self, width):
     """Return the z3 BitVecSort for the given width."""
     try:
         bvsort = self._z3BitVecSorts[width]
     except KeyError:
         bvsort = z3.BitVecSort(width)
         self._z3BitVecSorts[width] = bvsort
     return bvsort
Exemplo n.º 24
0
 def _fresh_ref(typ, tup, depth, name=None):
     if typ.is_pointer() and depth != 0:
         d[tup] = None
     if typ.is_int() or (typ.is_pointer() and depth != 0):
         args = [z3.BitVecSort(64)] * depth + [z3.BitVecSort(typ.size())]
         if name is None:
             name = ref._name
         else:
             name = ref._name + "->" + name
         d[tup] = z3.Function(util.fresh_name(name), *args)
     elif typ.is_struct():
         for i in range(len(typ.fields())):
             _fresh_ref(typ.field(i), tup + (i, ), depth, typ.field_name(i))
     elif typ.is_array() or typ.is_pointer():
         _fresh_ref(typ.deref(), tup, depth + 1)
     else:
         assert False, "unhandled case"
Exemplo n.º 25
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)
Exemplo n.º 26
0
def createConstantArray(awidth, dwidth, mem_values):
    asize = z3.BitVecSort(awidth)
    arr = z3.K(asize, z3.BitVecVal(mem_values[-1], dwidth))

    for [a, d] in mem_values[:-1]:
        az3 = z3.BitVecVal(a, awidth)
        dz3 = z3.BitVecVal(d, dwidth)
        arr = z3.Update(arr, az3, dz3)
    return arr
Exemplo n.º 27
0
    def __init__(self, domain: int, value_range: int, value: int):
        """Initializes an array with a default value.

        :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)
        :param value: The default value to use for this array
        """
        self.domain = z3.BitVecSort(domain)
        self.value = z3.BitVecVal(value, value_range)
        self.raw = z3.K(self.domain, self.value)
Exemplo n.º 28
0
 def _type_to_z3(self, tp):
     if tp.is_bool_type():
         return z3.BoolSort()
     elif tp.is_real_type():
         return z3.RealSort()
     elif tp.is_int_type():
         return z3.IntSort()
     else:
         assert tp.is_bv_type() , "Unsupported type '%s'" % tp
         return z3.BitVecSort(tp.width)
Exemplo n.º 29
0
    def __init__(self, name, key_type, val_type):
        self.name = name
        self.key_type = key_type
        self.val_type = val_type

        key_sorts = []
        for t in key_type:
            key_sorts.append(z3.BitVecSort(t * 8))
        self.ufs = []
        uf_name_base = fresh_name(self.name)
        cnt = 0
        contains_uf = z3.Function(uf_name_base + '!contains', *key_sorts, z3.BoolSort())
        self.contains = lambda *keys, old_f=contains_uf: old_f(*keys)
        for t in val_type:
            val_sort = z3.BitVecSort(t * 8)
            uf = z3.Function(uf_name_base + '!' + str(cnt), *key_sorts, val_sort)
            lambda_f = lambda *keys, old_f=uf: old_f(*keys)
            self.ufs.append(lambda_f)
            cnt += 1
Exemplo n.º 30
0
    def __init__(self, name=None):
        # each instance of the element will get a unique name upon creation
        self.se = z3
        self.unique_name = None
        if name is not None:
            self.unique_name = name
        else:
            self.unique_name = utils.fresh_name(self.name())
        self.state = {}
        self.packet_format = None

        cls = self.__class__
        if self.helper_funcs is not None and not hasattr(cls, '_ele_helpers'):
            for entry in self.helper_funcs:
                t = entry[1]
                if t == 'deter':
                    key_sorts = []
                    for kt in entry[2]:
                        key_sorts.append(z3.BitVecSort(kt * 8))
                    fs = []
                    cnt = 0
                    num_val = len(entry[3])
                    func_name = cls.__name__ + "!" + entry[0]
                    for vt in entry[3]:
                        v_sort = z3.BitVecSort(vt * 8)
                        f = z3.Function(func_name + "!" + str(cnt), *key_sorts,
                                        v_sort)
                        fs.append(f)
                        cnt += 1

                    def helper_func(*params):
                        result = []
                        if 'as_sexpr' not in dir(params[0]):
                            for i in range(num_val):
                                result.append(fs[i](*params))
                        else:
                            for i in range(num_val):
                                result.append(SpecAst(func_name, i, *params))
                        return tuple(result)

                    setattr(cls, entry[0], helper_func)
            setattr(cls, '_ele_helpers', True)