Beispiel #1
0
    def _z3_sort(self, json_type, typeargs=[], typeargnames={}):
        # print "Looking up type %s (%s, %s): %s" % (json_type['name'], typeargs, typeargnames, json_type)

        ## Hard-coded Z3 correspondence for some types
        if json_type['name'] == 'nat':
            return z3.IntSort()

        if json_type['name'] == 'string':
            return z3.StringSort()

        if json_type['name'] == 'gmap':
            return z3.ArraySort(self._z3_sort(json_type['args'][0]),
                                self._z3_sort(json_type['args'][1]))

        if json_type['what'] == 'type:var':
            t = typeargnames[json_type['name']]
            return self._z3_sort(t)

        if json_type['what'] == 'type:glob':
            if json_type['name'] == 'buf':
                return z3.SeqSort(z3.BitVecSort(8))

            return self.z3_sort(json_type['name'], [
                self._type_var_lookup(typeargnames, x)
                for x in json_type['args']
            ])

        if str(json_type) in self.json_to_sort:
            return self.json_to_sort[str(json_type)]

        if json_type['name'] == 'list':
            return z3.SeqSort(self._z3_sort(typeargs[0]))

        datatype = z3.Datatype(str(json_type['name']))
        typeargnames = {}
        for i in range(0, len(typeargs)):
            typeargname = json_type['argnames'][i]
            typeargnames[typeargname] = typeargs[i]
        for c in json_type['constructors']:
            cname = str(c['name'])
            datatype.declare(
                cname,
                *[(cname + '_%d' % idx, self._z3_sort(argtype, [],
                                                      typeargnames))
                  for (idx, argtype) in enumerate(c['argtypes'])])

        t = datatype.create()
        self.json_to_sort[str(json_type)] = t
        return t
def type_to_smt_sort(t: Type):
    if t in _TYPE_TO_SMT_SORT:
        return _TYPE_TO_SMT_SORT[t]
    origin = getattr(t, '__origin__', None)
    if origin in (List, Sequence, Container):
        item_type = t.__args__[0]
        return z3.SeqSort(type_to_smt_sort(item_type))
    elif origin in (Dict, Mapping):
        key_type, val_type = t.__args__
        return z3.ArraySort(type_to_smt_sort(key_type),
                            type_to_smt_sort(val_type))
    return None
def smt_var(typ: Type, name: str):
    z3type = type_to_smt_sort(typ)
    if z3type is None:
        if getattr(typ, '__origin__', None) is Tuple:
            if len(typ.__args__) == 2 and typ.__args__[1] == ...:
                z3type = z3.SeqSort(type_to_smt_sort(typ.__args__[0]))
            else:
                return tuple(
                    smt_var(t, name + str(idx))
                    for (idx, t) in enumerate(typ.__args__))
    var = z3.Const(name, z3type)
    if isinstance(z3type, z3.SeqSortRef):
        var = SymbolicSeq(var)
    return var
Beispiel #4
0
    def setupProblem(self):
        self.stackvars = {}
        self.Qf = z3.Function("final", z3.SeqSort(z3.IntSort()), z3.BoolSort())
        self.d = z3.Function("delta", z3.SeqSort(z3.IntSort()),
                             z3.StringSort(), z3.SeqSort(z3.IntSort()))

        for (w, st, final, has_children) in self.t.iter():

            sv = b"stack" + base64.b16encode(w)
            self.stackvars[w] = Sequence(sv)

            self.s_add_finalstate(w, final)

            if final and has_children:
                self.s_add_nonemptystate(w)

            if len(w):
                self.s_add_transition_to(w)

        self.s.add(self.stackvars[b''] == z3.Unit(z3.IntVal(0)))

        # most useful convention:
        # accept by drained stack, but don't read any more and fail then
        self.s.add(self.Qf(z3.Empty(z3.SeqSort(z3.IntSort()))) == True)
Beispiel #5
0
    def construct_from_z3_model(self, m, d, Qf, alphabet):
        to_check = [0]
        checked = set(to_check)

        print("Extracting tables")

        self.D = dict()
        self.QF = set()
        self.productive = None

        print("m[d]  = %s" % m[d])
        print("m[qf] = %s" % m[Qf])

        symbols = set([0])

        while len(to_check):
            current = to_check.pop()
            conf = z3.Unit(z3.IntVal(current))

            for a in alphabet:  # range(0, 256):
                y = m.evaluate(
                    d(
                        # z3.SubSeq(conf, z3.Length(conf)-1, 1),
                        conf,
                        z3.StringVal(bytes([a]))),
                    model_completion=True)

                def extract_seq_as_list(y):
                    result = List()
                    for c in y.children():
                        if isinstance(c, z3.SeqRef):
                            result += extract_seq_as_list(c)
                        else:
                            result += List([c.as_long()])
                    return result

                rhs = extract_seq_as_list(y)

                for symbol in rhs:
                    symbols.add(symbol)

                Dq = self.D.setdefault(current, dict())
                Dq[a] = rhs

                for i in rhs:
                    if not i in checked:
                        checked.add(i)
                        to_check += [i]

        if m.evaluate(Qf(z3.Empty(z3.SeqSort(z3.IntSort())))):
            self.QF.add(List([]))

        print("(stack/q) symbols encountered: %s" % symbols)

        for symbol in symbols:
            conf = z3.Unit(z3.IntVal(symbol))
            f = m.evaluate(Qf(conf))
            if f:
                self.QF.add(List([symbol]))

        self.symbols = symbols
Beispiel #6
0
sym.register_base_type("positive", lambda args: z3.IntSort())
sym.register_base_type("string", lambda args: z3.StringSort())

# XXX u0 is a u64? and u1 is a u32...
sym.register_base_type("u0", lambda args: z3.BitVecSort(64))
sym.register_base_type("u1", lambda args: z3.BitVecSort(32))
sym.register_base_type(
    "gmap", lambda args: z3.ArraySort(
        sym.z3_sort(args[0]),
        sym.z3_sort({
            'what': 'type:glob',
            'name': 'option',
            'args': [args[1]],
            'mod': m,
        })))
sym.register_base_type("buf", lambda args: z3.SeqSort(z3.BitVecSort(8)))
# sym.register_base_type("list", lambda args: z3.SeqSort(sym.z3_sort(args[0])))
# XXX hack: list is always of inode_state
sym.register_base_type(
    "list", lambda args: z3.SeqSort(
        sym.z3_sort({
            'what': 'type:glob',
            'name': 'inode_state',
            'args': [],
            'mod': m,
        })))
sym.register_base_type("fh", lambda args: z3.StringSort())

### Fix later
sym.register_base_type("fileid", lambda args: z3.BitVecSort(64))
sym.register_base_type("createverf", lambda args: z3.BitVecSort(64))