Exemple #1
0
    def write(self, addr, data):
        if isinstance(addr, int):
            return self.write_con(addr, data)
        elif z3.is_bv_value(addr):
            return self.write_con(addr.as_long(), data)

        addr = z3.simplify(addr)
        if z3.is_bv_value(addr):
            return self.write_con(addr.as_long(), data)

        addrs = self.eval_max(addr, self.max_eval)

        if addrs == []:
            raise ESILUnsatException("Unsat symbolic address")
        elif len(addrs) == 1:
            # should I add this constraint? no?
            return self.write_con(addrs[0].as_long(), data)

        # constrain it to be one of these
        self.solver.add(z3.Or(*[addr == a for a in addrs]))

        data = self.data_to_bv(data)
        length = data.size() // 8

        for address in addrs:
            addrint = address.as_long()
            val = self.pack_bv(self.cond_read(addrint, length))
            self.write_con(addrint, z3.If(addr == address, data, val))
Exemple #2
0
    def check_addr(self, bv, mode="r", length=None, data=None):

        if isinstance(bv, int):
            return
        elif z3.is_bv_value(bv):
            return

        bv = z3.simplify(bv)
        if z3.is_bv_value(bv):
            return 

        elif z3.is_bv(bv):

            mode_to_event = {
                "r": ESILSolveEvent.SymRead,
                "w": ESILSolveEvent.SymWrite,
                "x": ESILSolveEvent.SymExec,
                "f": ESILSolveEvent.SymFree
            }
            event = mode_to_event[mode]
            if event in self.events:
                # normalize everything to be bvs
                if isinstance(length, int):
                    length = BV(length, self.bits)

                if isinstance(data, list):
                    data = self.memory.pack_bv(data)

                ctx = EventContext(bv, length, data)
                for hook in self.events[event]:
                    hook(self, ctx)
Exemple #3
0
    def read_bv(self, addr, length):
        if isinstance(addr, int):
            return self.pack_bv(self.cond_read(addr, length))
        elif z3.is_bv_value(addr):
            return self.pack_bv(self.cond_read(addr.as_long(), length))

        addr = z3.simplify(addr)
        if z3.is_bv_value(addr):
            return self.pack_bv(self.cond_read(addr.as_long(), length))

        addrs = self.eval_max(addr, self.max_eval)

        if addrs == []:
            raise ESILUnsatException("Unsat symbolic address")
        elif len(addrs) == 1:
            # should I add this constraint? no?
            return self.pack_bv(self.cond_read(addrs[0].as_long(), length))

        # constrain it to be one of these
        self.solver.add(z3.Or(*[addr == a for a in addrs]))

        result = None
        for address in addrs:
            val = self.pack_bv(self.cond_read(address.as_long(), length))

            if result == None:
                result = val
            else:
                result = z3.If(addr == address, val, result)

        return z3.simplify(result)
    def get_lazy_pcs(self, pc):
        arg1 = z3.simplify(pc.arg(1))
        arg2 = z3.simplify(pc.arg(2))

        if z3.is_bv_value(arg1) and z3.is_bv_value(arg2):
            return [arg1.as_long(), arg2.as_long()]
        else:
            return []
Exemple #5
0
    def read(self, addr, length):
        if isinstance(addr, int):
            return self.cond_read(addr, length)
        elif z3.is_bv_value(addr):
            return self.cond_read(addr.as_long(), length)

        addr = z3.simplify(addr)
        if z3.is_bv_value(addr):
            return self.cond_read(addr.as_long(), length)

        data = self.read_bv(addr, length)
        return self.unpack_bv(data, int(data.size() / 8))
Exemple #6
0
 def add_engine_object(self, elem):
     if z3.is_bv_value(elem):
         self._engine_objects[MUZ] = elem
     elif isinstance(elem, str):
         self._engine_objects[KANREN_LOGPY] = elem
     else:
         raise Exception(f"unsupported Constant object {type(elem)}")
Exemple #7
0
def do_PICK(op, stack, state):
    n, = pop_values(stack, state)
    if z3.is_bv_value(n):
        n = n.as_long()
    
    # esil from pcode is 1, not 0 indexed for PICK
    stack.append(stack[-n])
Exemple #8
0
def prepare(val, signext=False, size=SIZE) -> z3.BitVecRef:
    if z3.is_bv(val):
        szdiff = size - val.size()

        if szdiff > 0:
            if signext:
                result = z3.SignExt(szdiff, val)
            else:
                result = z3.ZeroExt(szdiff, val)
        elif szdiff < 0:
            result = z3.Extract(size - 1, 0, val)
        else:
            result = val
    elif type(val) == int:
        result = z3.BitVecVal(val, size)
    elif z3.is_int(val):
        result = z3.Int2BV(val, size)
    elif z3.is_fp(val):
        # changing up this logic to align with r2ghidra impl
        result = z3.fpToIEEEBV(val)
        #result = val
    else:
        result = z3.BitVecVal(val, size)

    if not z3.is_bv_value(result):
        return z3.simplify(result)
    else:
        return result
Exemple #9
0
    def compare(self, s1, s2, length=None):
        max_len = self.max_len
        if length != None:
            length = z3.simplify(length)
            if z3.is_bv_value(length):
                max_len = length.as_long()

        else:  # no len use null
            len1, last1 = self.search(s1, [BZERO])
            len2, last2 = self.search(s2, [BZERO])

            max_len = min(last1, last2) + 1
            length = z3.If(len1 < len2, len1, len2) + 1

        ret_val = ZERO
        for i in range(max_len):
            c1 = z3.ZeroExt(24, self.read_bv(s1 + i, 1))
            c2 = z3.ZeroExt(24, self.read_bv(s2 + i, 1))
            new_ind = z3.BitVecVal(i, SIZE)
            over_len = self.solver.check(length > new_ind) == z3.unsat

            if not over_len:
                this_val = z3.If(c1 == c2, ZERO, z3.If(c1 < c2, NEGONE, ONE))
                new_val = z3.If(ret_val == ZERO, this_val, ret_val)
                ret_val = z3.If(length > new_ind, new_val, ret_val)
            else:
                break

        return z3.simplify(ret_val)
Exemple #10
0
    def bv_to_int(self, bv):

        bv = z3.simplify(bv)
        if z3.is_bv_value(bv):
            return bv.as_long()

        # this is terrible and temporary
        elif z3.is_bv(bv):
            print("symbolic addr: %s" % bv)
            self.hit_symbolic_addr = True
            sat = self.solver.check()
            if sat == z3.sat:
                model = self.solver.model()

                try:
                    val = model.eval(bv, model_completion=True).as_long()
                    #print(val)
                    '''if self.multi_concretize:
                        self.solver.push()
                        self.solver.add(bv != val)
                        vals = solver.EvalMax(self.solver, bv)
                        if len(vals) > 0:
                            self.concrete_addrs.append({"bv": bv, "values": vals})
                        self.solver.pop()'''

                    self.solver.add(bv == val)
                    return val
                except:
                    # idk man i need a default value in case
                    # there are no constraints on the addr
                    self.solver.add(bv == self.default_addr)
                    return self.default_addr

            else:
                raise ESILUnsatException("no sat symbolic address found")
Exemple #11
0
def prepare(val, signext=False, size=SIZE) -> z3.BitVecRef:
    if z3.is_bv(val):
        szdiff = size-val.size()
        if szdiff == 0:
            result = val
        elif szdiff > 0:
            if signext:
                result = z3.SignExt(szdiff, val)
            else:
                result = z3.ZeroExt(szdiff, val)
        elif szdiff < 0:
            result = z3.Extract(size-1, 0, val)

    elif isinstance(val, int):
        result = z3.BitVecVal(val, size)
    elif z3.is_int(val):
        result = z3.Int2BV(val, size)
    elif z3.is_fp(val):
        result = z3.fpToIEEEBV(val)
    else:
        result = z3.BitVecVal(val, size)

    if not z3.is_bv_value(result):
        return z3.simplify(result)
    else:
        return result
Exemple #12
0
def collect_numerals(z3term):
    if z3.is_int_value(z3term) or z3.is_bv_value(z3term):
        yield z3term
    elif z3.is_app_of(z3term, z3.Z3_OP_ITE):
        for z in collect_numerals(z3term.arg(1)):
            yield z
        for z in collect_numerals(z3term.arg(2)):
            yield z
Exemple #13
0
 def pp_app(self, a, d, xs):
     if z3.is_int_value(a):
         return self.pp_int(a)
     elif z3.is_rational_value(a):
         return self.pp_rational(a)
     elif z3.is_algebraic_value(a):
         return self.pp_algebraic(a)
     elif z3.is_bv_value(a):
         return self.pp_bv(a)
     elif z3.is_finite_domain_value(a):
         return self.pp_fd(a)
     elif z3.is_fprm_value(a):
         return self.pp_fprm_value(a)
     elif z3.is_fp_value(a):
         return self.pp_fp_value(a)
     elif z3.is_fp(a):
         return self.pp_fp(a, d, xs)
     elif z3.is_string_value(a):
         return self.pp_string(a)
     elif z3.is_const(a):
         return self.pp_const(a)
     else:
         f = a.decl()
         k = f.kind()
         if k == Z3_OP_POWER:
             return self.pp_power(a, d, xs)
         elif k == Z3_OP_DISTINCT:
             return self.pp_distinct(a, d, xs)
         elif k == Z3_OP_SELECT:
             return self.pp_select(a, d, xs)
         elif k == Z3_OP_SIGN_EXT or k == Z3_OP_ZERO_EXT or k == Z3_OP_REPEAT:
             return self.pp_unary_param(a, d, xs)
         elif k == Z3_OP_EXTRACT:
             return self.pp_extract(a, d, xs)
         elif k == Z3_OP_RE_LOOP:
             return self.pp_loop(a, d, xs)
         elif k == Z3_OP_DT_IS:
             return self.pp_is(a, d, xs)
         elif k == Z3_OP_ARRAY_MAP:
             return self.pp_map(a, d, xs)
         elif k == Z3_OP_CONST_ARRAY:
             return self.pp_K(a, d, xs)
         elif k == Z3_OP_PB_AT_MOST:
             return self.pp_atmost(a, d, f, xs)
         elif k == Z3_OP_PB_LE:
             return self.pp_pbcmp(a, d, f, xs)
         elif k == Z3_OP_PB_GE:
             return self.pp_pbcmp(a, d, f, xs)
         elif k == Z3_OP_PB_EQ:
             return self.pp_pbcmp(a, d, f, xs)
         elif z3.is_pattern(a):
             return self.pp_pattern(a, d, xs)
         elif self.is_infix(k):
             return self.pp_infix(a, d, xs)
         elif self.is_unary(k):
             return self.pp_unary(a, d, xs)
         else:
             return self.pp_prefix(a, d, xs)
Exemple #14
0
def do_U2D(op, stack, state):
    val, = pop_values(stack, state)

    if z3.is_bv_value(val):
        fp = z3.FPVal(val.as_long(), FSIZE)
    else:
        fp = z3.fpUnsignedToFP(FPM, val, FSIZE)

    stack.append(fp)
Exemple #15
0
    def addr_to_int(self, bv):

        if z3.is_bv_value(bv):
            return bv.as_long()

        bv = z3.simplify(bv)
        if z3.is_bv_value(bv):
            return bv.as_long()
        else:  # should be only for free() now
            if self.solver.check() == z3.sat:
                model = self.solver.model()
                val = model.eval(bv, model_completion=True)
                self.solver.add(bv == val)
                return val.as_long()

            else:
                raise ESILUnsatException(
                    f"no sat symbolic address found for: {bv}")
Exemple #16
0
 def pp_app(self, a, d, xs):
     if z3.is_int_value(a):
         return self.pp_int(a)
     elif z3.is_rational_value(a):
         return self.pp_rational(a)
     elif z3.is_algebraic_value(a):
         return self.pp_algebraic(a)        
     elif z3.is_bv_value(a):
         return self.pp_bv(a)
     elif z3.is_finite_domain_value(a):
         return self.pp_fd(a)
     elif z3.is_fprm_value(a):
         return self.pp_fprm_value(a)
     elif z3.is_fp_value(a):
         return self.pp_fp_value(a)
     elif z3.is_fp(a):
         return self.pp_fp(a, d, xs)
     elif z3.is_string_value(a):
         return self.pp_string(a)
     elif z3.is_const(a):
         return self.pp_const(a)
     else:
         f = a.decl()
         k = f.kind()
         if k == Z3_OP_POWER:
             return self.pp_power(a, d, xs)
         elif k == Z3_OP_DISTINCT:
             return self.pp_distinct(a, d, xs)
         elif k == Z3_OP_SELECT:
             return self.pp_select(a, d, xs)
         elif k == Z3_OP_SIGN_EXT or k == Z3_OP_ZERO_EXT or k == Z3_OP_REPEAT:
             return self.pp_unary_param(a, d, xs)
         elif k == Z3_OP_EXTRACT:
             return self.pp_extract(a, d, xs)
         elif k == Z3_OP_DT_IS:
             return self.pp_is(a, d, xs)
         elif k == Z3_OP_ARRAY_MAP:
             return self.pp_map(a, d, xs)
         elif k == Z3_OP_CONST_ARRAY:
             return self.pp_K(a, d, xs)
         elif k == Z3_OP_PB_AT_MOST:
             return self.pp_atmost(a, d, f, xs)
         elif k == Z3_OP_PB_LE:
             return self.pp_pbcmp(a, d, f, xs)
         elif k == Z3_OP_PB_GE:
             return self.pp_pbcmp(a, d, f, xs)
         elif k == Z3_OP_PB_EQ:
             return self.pp_pbcmp(a, d, f, xs)
         elif z3.is_pattern(a):
             return self.pp_pattern(a, d, xs)
         elif self.is_infix(k):
             return self.pp_infix(a, d, xs)
         elif self.is_unary(k):
             return self.pp_unary(a, d, xs)
         else:
             return self.pp_prefix(a, d, xs)
Exemple #17
0
    def search(self, addr, needle, length=None, reverse=False):
        max_len = self.max_len
        n = len(needle)

        if n == 0:
            return ZERO

        if length != None:
            nbv = z3.BitVecVal(n - 1, SIZE)
            length = z3.simplify(length - nbv)
            if z3.is_bv_value(length):
                max_len = length.as_long()

        else:
            length = z3.BitVecVal(max_len - n + 1, SIZE)

        ret_ind = self.error  # hmm idk
        ind_con = z3.BoolVal(False)

        rargs = (0, max_len, 1)
        if reverse:
            rargs = (max_len, 0, -1)

        for i in range(*rargs):
            cs = self.read(addr + i, n)
            found = all([(self.solver.check(cs[k] != needle[k]) == z3.unsat)
                         for k in range(n)])  # oof

            not_found = any([
                (self.solver.check(cs[k] == needle[k]) == z3.unsat)
                for k in range(n)
            ])

            new_ind = z3.BitVecVal(i, SIZE)
            over_len = self.solver.check(length > new_ind) == z3.unsat

            if not over_len:
                if found:
                    ind_con = z3.And(length > new_ind, z3.Not(ind_con))
                    ret_ind = z3.If(ind_con, new_ind, ret_ind)
                    return z3.simplify(ret_ind), i

                elif not not_found:
                    new_cons = [cs[k] == needle[k] for k in range(n)]
                    new_cons.append(length > new_ind)
                    new_con = z3.And(*new_cons)

                    ind_con = z3.And(new_con, z3.Not(ind_con))
                    ret_ind = z3.If(ind_con, new_ind, ret_ind)
            else:
                if not reverse:
                    return z3.simplify(ret_ind), i

        return z3.simplify(ret_ind), max_len
Exemple #18
0
def do_I2F(op, stack, state):
    val, = pop_values(stack, state)

    if z3.is_bv_value(val):
        fp = z3.FPVal(val.as_long(), FSIZE)
    else:
        fp = z3.FP("fp%d" % float_data["count"], FSIZE)
        state.solver.add(z3.fpToUBV(FPM, fp, z3.BitVecSort(SIZE)) == val)
        float_data["count"] += 1

    stack.append(fp)
Exemple #19
0
    def cond_read(self, addr, length):
        if isinstance(length, int):
            return self.read_con(addr, length)
        elif z3.is_bv_value(length):
            return self.read_con(addr, length.as_long())

        length = z3.simplify(length)
        if z3.is_bv_value(length):
            return self.read_con(addr, length.as_long())
        else:
            data = []
            for i in range(self.max_len):
                sc = self.read_con_bv(addr + i, 1)
                new_len = z3.BitVecVal(i, SIZE)
                over_len = self.solver.check(length > new_len) == z3.unsat

                if not over_len:
                    data.append(sc)
                else:
                    break

            return data
Exemple #20
0
def read(state, fd, addr, length):
    fd = state.evalcon(fd).as_long()
    #length = state.evalcon(length).as_long()
    length = z3.simplify(length)

    if z3.is_bv_value(length):
        rlen = length.as_long()
    else:
        rlen = len(state.mem_read(addr, length))  # hax

    data = state.fs.read(fd, rlen)
    dlen = BV(len(data))
    state.mem_copy(addr, data, length)
    return z3.If(dlen < length, dlen, length)
Exemple #21
0
    def rec(e):
        if isinstance(e, z3.QuantifierRef):
            for n in range(e.num_vars()):
                mkvar(e.var_name(n), e.var_sort(n))
        elif z3.is_algebraic_value(e) or \
             z3.is_bv_value(e) or \
             z3.is_int_value(e) or \
             z3.is_rational_value(e):
            pass
        elif z3.is_const(e):
            mkvar(str(e), e.sort())

        for sub in e.children():
            rec(sub)
Exemple #22
0
    def do_if(self, state):
        val, = esilops.pop_values(state.stack, state)
        val = z3.simplify(val)

        zero = 0
        if z3.is_bv_value(val):
            val = val.as_long()
                
        elif z3.is_bv(val):
            zero = z3.BitVecVal(0, val.size())

        if state.condition == None:
            if type(val) == int:
                return val != zero
            else:
                return self.eq(val != zero)
        else:
            return z3.And(self.eq(val != zero), state.condition)
Exemple #23
0
    def copy(self, dst, data, length):
        length = z3.simplify(length)
        if z3.is_bv_value(length):
            self.write(dst, data[:length.as_long()])
        else:
            new_data = []
            for i in range(len(data)):
                sc = data[i]
                dc = self.read_bv(dst + i, 1)
                new_len = z3.BitVecVal(i, SIZE)
                over_len = self.solver.check(length > new_len) == z3.unsat

                if not over_len:
                    new_data.append(z3.If(length > new_len, sc, dc))
                else:
                    break

            self.write(dst, new_data)
    def bv_to_int(self, bv):

        bv = z3.simplify(bv)
        if z3.is_bv_value(bv):
            return bv.as_long()

        # this is terrible and temporary
        elif z3.is_bv(bv):
            #print("symbolic addr: %s" % bv)
            self.hit_symbolic_addr = True
            if self.solver.check() == z3.sat:
                model = self.solver.model()

                val = model.eval(bv, model_completion=True)
                self.solver.add(bv == val)
                return val.as_long()

            else:
                raise ESILUnsatException("no sat symbolic address found")
Exemple #25
0
    def memcopy(self, dst, src, length):
        length = z3.simplify(length)
        if z3.is_bv_value(length):
            data = self.read(src, length.as_long())
            self.write(dst, data)
        else:
            data = []
            for i in range(self.max_len):
                sc = self.read_bv(src + i, 1)
                dc = self.read_bv(dst + i, 1)
                new_len = z3.BitVecVal(i, SIZE)
                over_len = self.solver.check(length > new_len) == z3.unsat

                if not over_len:
                    data.append(z3.If(length > new_len, sc, dc))
                else:
                    break

            self.write(dst, data)
Exemple #26
0
    def add(self, state: ESILState):
        """
        Add state to the manager

        :param state:     The state to be added 
        """

        pc = state.registers["PC"]
        if z3.is_bv_value(pc):
            if pc.as_long() in self.avoid:
                self.inactive.add(state)
            else:
                self.active.add(state)

        elif self.lazy or state.is_sat():
            self.active.add(state)

        else:
            self.unsat.add(state)
Exemple #27
0
 def overlay(self, chunk, base_off, chunk_off, length):
     slen = z3.simplify(length)
     if z3.is_bv_value(slen):
         for i in range(slen.as_long()):
             if isinstance(chunk, Memory):
                 sel = chunk.select(chunk_off + i)
             else:
                 sel = z3.Select(chunk, chunk_off + i)
             self._mem = z3.Store(self._mem, base_off + i, sel)
     else:
         if self._idx is None:
             self._idx = z3.BitVec('idx', 256)
         if isinstance(chunk, Memory):
             chunk_val = chunk.select(self._idx - base_off + chunk_off)
         else:
             chunk_val = z3.Select(chunk, self._idx - base_off + chunk_off)
         self._mem = z3.If(
             z3.And(self._idx >= base_off, self._idx < base_off + length),
             z3.Store(state.MemoryEmpty, self._idx, chunk_val), self._mem)
Exemple #28
0
 def pp_app(self, a, d, xs):
     if z3.is_int_value(a):
         return self.pp_int(a)
     elif z3.is_rational_value(a):
         return self.pp_rational(a)
     elif z3.is_algebraic_value(a):
         return self.pp_algebraic(a)
     elif z3.is_bv_value(a):
         return self.pp_bv(a)
     elif z3.is_fprm_value(a):
         return self.pp_fprm_value(a)
     elif z3.is_fp_value(a):
         return self.pp_fp_value(a)
     elif z3.is_fp(a):
         return self.pp_fp(a, d, xs)
     elif z3.is_const(a):
         return self.pp_const(a)
     else:
         f = a.decl()
         k = f.kind()
         if k == Z3_OP_POWER:
             return self.pp_power(a, d, xs)
         elif k == Z3_OP_DISTINCT:
             return self.pp_distinct(a, d, xs)
         elif k == Z3_OP_SELECT:
             return self.pp_select(a, d, xs)
         elif k == Z3_OP_SIGN_EXT or k == Z3_OP_ZERO_EXT or k == Z3_OP_REPEAT:
             return self.pp_unary_param(a, d, xs)
         elif k == Z3_OP_EXTRACT:
             return self.pp_extract(a, d, xs)
         elif k == Z3_OP_ARRAY_MAP:
             return self.pp_map(a, d, xs)
         elif k == Z3_OP_CONST_ARRAY:
             return self.pp_K(a, d, xs)
         elif z3.is_pattern(a):
             return self.pp_pattern(a, d, xs)
         elif self.is_infix(k):
             return self.pp_infix(a, d, xs)
         elif self.is_unary(k):
             return self.pp_unary(a, d, xs)
         else:
             return self.pp_prefix(a, d, xs)
Exemple #29
0
def atoi_helper(state, addr, size=SIZE):  # still sucks
    string, length = state.symbolic_string(addr)

    if z3.is_bv_value(string):
        cstr = state.evaluate_string(string)
        return BV(int(cstr), size)
    else:
        length = state.evalcon(length).as_long()  # unfortunate

        result = BV(0, size)
        is_neg = z3.BoolVal(False)
        m = BV(ord("-"), 8)
        for i in range(length):
            d = state.mem_read_bv(addr + i, 1)
            is_neg = z3.If(d == m, z3.BoolVal(True), is_neg)
            c = z3.If(d == m, BV(0, size), z3.ZeroExt(size - 8, d - BV_0))
            result = result + (c * BV(10**(length - (i + 1)), size))

        result = z3.If(is_neg, -result, result)
        return result
Exemple #30
0
def memset(state, dst, ch, num):
    c = z3.Extract(7, 0, ch)  # TODO big endian

    length = z3.simplify(num)
    if z3.is_bv_value(length):
        state.mem_write(dst, [c] * length.as_long())
    else:
        data = []
        for i in range(state.max_len):
            dc = state.read_bv(dst + i, 1)
            new_len = BV(i, SIZE)
            over_len = state.solver.check(length > new_len) == z3.unsat

            if not over_len:
                data.append(z3.If(length > new_len, c, dc))
            else:
                break

        state.mem_write(dst, data)

    return dst
Exemple #31
0
 def pp_app(self, a, d, xs):
     if z3.is_int_value(a):
         return self.pp_int(a)
     elif z3.is_rational_value(a):
         rat = self.pp_rational(a)
         return rat
     elif z3.is_algebraic_value(a):
         return self.pp_algebraic(a)
     elif z3.is_bv_value(a):
         return self.pp_bv(a)
     elif z3.is_const(a):
         return self.pp_const(a)
     else:
         f = a.decl()
         k = f.kind()
         if k == Z3_OP_POWER:
             return self.pp_power(a, d, xs)
         elif k == Z3_OP_DISTINCT:
             return self.pp_distinct(a, d, xs)
         elif k == Z3_OP_SELECT:
             return self.pp_select(a, d, xs)
         elif k == Z3_OP_SIGN_EXT or k == Z3_OP_ZERO_EXT or k == Z3_OP_REPEAT:
             return self.pp_unary_param(a, d, xs)
         elif k == Z3_OP_EXTRACT:
             return self.pp_extract(a, d, xs)
         elif k == Z3_OP_ARRAY_MAP:
             return self.pp_map(a, d, xs)
         elif k == Z3_OP_CONST_ARRAY:
             return self.pp_K(a, d, xs)
         elif z3.is_pattern(a):
             return self.pp_pattern(a, d, xs)
         elif self.is_infix(k):
             return self.pp_infix(a, d, xs)
         elif self.is_unary(k):
             return self.pp_unary(a, d, xs)
         else:
             return self.pp_prefix(a, d, xs)
Exemple #32
0
    def alloc(self, length=0x80):
        """ 
        The dumbest memory allocation function
        known to human or alien life

        >>> state.memory.alloc(0x100)
        0x02000100
        """

        if not self.heap_init:
            self.init_heap()

        needs = 0
        if type(length) == int:
            needs = int(length / self.heap_bin) + 1
        elif z3.is_bv_value(length):
            needs = int(length.as_long() / self.heap_bin) + 1
        else:
            more = True
            while more:
                needs += 1
                cur = z3.BitVecVal(needs * self.heap_bin, SIZE)
                more = (self.solver.check(length > cur) == z3.sat)

        slot = 0
        avail = False
        while not avail:
            unused = [(slot + i) not in self.heap for i in range(needs)]
            avail = all(unused)
            if not avail:
                slot += unused[::-1].index(False) + 1
            else:
                new_slots = [(slot + i, slot) for i in range(needs)]
                self.heap.update(dict(new_slots))

        addr = self.heap_start + slot * self.heap_bin
        return addr
Exemple #33
0
    def _back_single_term(self, expr, args, model=None):
        assert z3.is_expr(expr)

        if z3.is_quantifier(expr):
            raise NotImplementedError(
                "Quantified back conversion is currently not supported")

        assert not len(args) > 2 or \
            (z3.is_and(expr) or z3.is_or(expr) or
             z3.is_add(expr) or z3.is_mul(expr) or
             (len(args) == 3 and (z3.is_ite(expr) or z3.is_array_store(expr)))),\
            "Unexpected n-ary term: %s" % expr

        res = None
        try:
            decl = z3.Z3_get_app_decl(expr.ctx_ref(), expr.as_ast())
            kind = z3.Z3_get_decl_kind(expr.ctx.ref(), decl)
            # Try to get the back-conversion function for the given Kind
            fun = self._back_fun[kind]
            return fun(args, expr)
        except KeyError as ex:
            pass

        if z3.is_const(expr):
            # Const or Symbol
            if z3.is_rational_value(expr):
                n = expr.numerator_as_long()
                d = expr.denominator_as_long()
                f = Fraction(n, d)
                return self.mgr.Real(f)
            elif z3.is_int_value(expr):
                n = expr.as_long()
                return self.mgr.Int(n)
            elif z3.is_bv_value(expr):
                n = expr.as_long()
                w = expr.size()
                return self.mgr.BV(n, w)
            elif z3.is_as_array(expr):
                if model is None:
                    raise NotImplementedError("As-array expressions cannot be" \
                                              " handled as they are not " \
                                              "self-contained")
                else:
                    interp_decl = z3.get_as_array_func(expr)
                    interp = model[interp_decl]
                    default = self.back(interp.else_value(), model=model)
                    assign = {}
                    for i in xrange(interp.num_entries()):
                        e = interp.entry(i)
                        assert e.num_args() == 1
                        idx = self.back(e.arg_value(0), model=model)
                        val = self.back(e.value(), model=model)
                        assign[idx] = val
                    arr_type = self._z3_to_type(expr.sort())
                    return self.mgr.Array(arr_type.index_type, default, assign)
            elif z3.is_algebraic_value(expr):
                # Algebraic value
                return self.mgr._Algebraic(Numeral(expr))
            else:
                # it must be a symbol
                try:
                    return self.mgr.get_symbol(str(expr))
                except UndefinedSymbolError:
                    import warnings
                    symb_type = self._z3_to_type(expr.sort())
                    warnings.warn("Defining new symbol: %s" % str(expr))
                    return self.mgr.FreshSymbol(symb_type,
                                                template="__z3_%d")
        elif z3.is_function(expr):
            # This needs to be after we try to convert regular Symbols
            fsymbol = self.mgr.get_symbol(expr.decl().name())
            return self.mgr.Function(fsymbol, args)

        # If we reach this point, we did not manage to translate the expression
        raise ConvertExpressionError(message=("Unsupported expression: %s" %
                                              (str(expr))),
                                     expression=expr)
Exemple #34
0
def collect_numerals(z3term):
    if z3.is_int_value(z3term) or z3.is_bv_value(z3term):
        yield z3term
    elif z3.is_app_of(z3term, z3.Z3_OP_ITE):
        yield collect_numerals(z3term.arg(1))
        yield collect_numerals(z3term.arg(2))
Exemple #35
0
    def _back_single_term(self, expr, args):
        assert z3.is_expr(expr)

        if z3.is_quantifier(expr):
            raise NotImplementedError(
                "Quantified back conversion is currently not supported")

        res = None
        if z3.is_and(expr):
            res = self.mgr.And(args)
        elif z3.is_or(expr):
            res = self.mgr.Or(args)
        elif z3.is_add(expr):
            res = self.mgr.Plus(args)
        elif z3.is_div(expr):
            res = self.mgr.Div(args[0], args[1])
        elif z3.is_eq(expr):
            if self._get_type(args[0]).is_bool_type():
                res = self.mgr.Iff(args[0], args[1])
            else:
                res = self.mgr.Equals(args[0], args[1])
        elif z3.is_iff(expr):
            res = self.mgr.Iff(args[0], args[1])
        elif z3.is_xor(expr):
            res = self.mgr.Xor(args[0], args[1])
        elif z3.is_false(expr):
            res = self.mgr.FALSE()
        elif z3.is_true(expr):
            res = self.mgr.TRUE()
        elif z3.is_gt(expr):
            res = self.mgr.GT(args[0], args[1])
        elif z3.is_ge(expr):
            res = self.mgr.GE(args[0], args[1])
        elif z3.is_lt(expr):
            res = self.mgr.LT(args[0], args[1])
        elif z3.is_le(expr):
            res = self.mgr.LE(args[0], args[1])
        elif z3.is_mul(expr):
            res = self.mgr.Times(args[0], args[1])
        elif z3.is_uminus(expr):
            tp = self._get_type(args[0])
            if tp.is_real_type():
                minus_one = self.mgr.Real(-1)
            else:
                assert tp.is_int_type()
                minus_one = self.mgr.Int(-1)
            res = self.mgr.Times(args[0], minus_one)
        elif z3.is_sub(expr):
            res = self.mgr.Minus(args[0], args[1])
        elif z3.is_not(expr):
            res = self.mgr.Not(args[0])
        elif z3.is_implies(expr):
            res = self.mgr.Implies(args[0], args[1])
        elif z3.is_quantifier(expr):
            raise NotImplementedError
        elif z3.is_const(expr):
            if z3.is_rational_value(expr):
                n = expr.numerator_as_long()
                d = expr.denominator_as_long()
                f = Fraction(n, d)
                res = self.mgr.Real(f)
            elif z3.is_int_value(expr):
                n = expr.as_long()
                res = self.mgr.Int(n)
            elif z3.is_bv_value(expr):
                n = expr.as_long()
                w = expr.size()
                res = self.mgr.BV(n, w)
            else:
                # it must be a symbol
                res = self.mgr.get_symbol(str(expr))
        elif z3.is_ite(expr):
            res = self.mgr.Ite(args[0], args[1], args[2])
        elif z3.is_function(expr):
            res = self.mgr.Function(self.mgr.get_symbol(expr.decl().name()), args)
        elif z3.is_to_real(expr):
            res = self.mgr.ToReal(args[0])
        elif z3.is_bv_and(expr):
            res = self.mgr.BVAnd(args[0], args[1])
        elif z3.is_bv_or(expr):
            res = self.mgr.BVOr(args[0], args[1])
        elif z3.is_bv_xor(expr):
            res = self.mgr.BVXor(args[0], args[1])
        elif z3.is_bv_not(expr):
            res = self.mgr.BVNot(args[0])
        elif z3.is_bv_neg(expr):
            res = self.mgr.BVNeg(args[0])
        elif z3.is_bv_concat(expr):
            res = self.mgr.BVConcat(args[0], args[1])
        elif z3.is_bv_ult(expr):
            res = self.mgr.BVULT(args[0], args[1])
        elif z3.is_bv_uleq(expr):
            res = self.mgr.BVULE(args[0], args[1])
        elif z3.is_bv_slt(expr):
            res = self.mgr.BVSLT(args[0], args[1])
        elif z3.is_bv_sleq(expr):
            res = self.mgr.BVSLE(args[0], args[1])
        elif z3.is_bv_ugt(expr):
            res = self.mgr.BVUGT(args[0], args[1])
        elif z3.is_bv_ugeq(expr):
            res = self.mgr.BVUGE(args[0], args[1])
        elif z3.is_bv_sgt(expr):
            res = self.mgr.BVSGT(args[0], args[1])
        elif z3.is_bv_sgeq(expr):
            res = self.mgr.BVSGE(args[0], args[1])
        elif z3.is_bv_extract(expr):
            end = z3.get_payload(expr, 0)
            start = z3.get_payload(expr, 1)
            res = self.mgr.BVExtract(args[0], start, end)
        elif z3.is_bv_add(expr):
            res = self.mgr.BVAdd(args[0], args[1])
        elif z3.is_bv_mul(expr):
            res = self.mgr.BVMul(args[0], args[1])
        elif z3.is_bv_udiv(expr):
            res = self.mgr.BVUDiv(args[0], args[1])
        elif z3.is_bv_sdiv(expr):
            res = self.mgr.BVSDiv(args[0], args[1])
        elif z3.is_bv_urem(expr):
            res = self.mgr.BVURem(args[0], args[1])
        elif z3.is_bv_srem(expr):
            res = self.mgr.BVSRem(args[0], args[1])
        elif z3.is_bv_lshl(expr):
            res = self.mgr.BVLShl(args[0], args[1])
        elif z3.is_bv_lshr(expr):
            res = self.mgr.BVLShr(args[0], args[1])
        elif z3.is_bv_ashr(expr):
            res = self.mgr.BVAShr(args[0], args[1])
        elif z3.is_bv_sub(expr):
            res = self.mgr.BVSub(args[0], args[1])
        elif z3.is_bv_rol(expr):
            amount = z3.get_payload(expr, 0)
            res = self.mgr.BVRol(args[0], amount)
        elif z3.is_bv_ror(expr):
            amount = z3.get_payload(expr, 0)
            res = self.mgr.BVRor(args[0], amount)
        elif z3.is_bv_ext_rol(expr):
            amount = args[1].bv_unsigned_value()
            res = self.mgr.BVRol(args[0], amount)
        elif z3.is_bv_ext_ror(expr):
            amount = args[1].bv_unsigned_value()
            res = self.mgr.BVRor(args[0], amount)
        elif z3.is_bv_sext(expr):
            amount = z3.get_payload(expr, 0)
            res = self.mgr.BVSExt(args[0], amount)
        elif z3.is_bv_zext(expr):
            amount = z3.get_payload(expr, 0)
            res = self.mgr.BVZExt(args[0], amount)

        if res is None:
            raise ConvertExpressionError(message=("Unsupported expression: %s" %
                                                   str(expr)),
                                         expression=expr)
        return res
Exemple #36
0
    def _back_single_term(self, expr, args, model=None):
        assert z3.is_expr(expr)

        if z3.is_quantifier(expr):
            raise NotImplementedError(
                "Quantified back conversion is currently not supported")

        res = None
        if z3.is_and(expr):
            res = self.mgr.And(args)
        elif z3.is_or(expr):
            res = self.mgr.Or(args)
        elif z3.is_add(expr):
            res = self.mgr.Plus(args)
        elif z3.is_div(expr):
            res = self.mgr.Div(args[0], args[1])
        elif z3.is_eq(expr):
            if self._get_type(args[0]).is_bool_type():
                res = self.mgr.Iff(args[0], args[1])
            else:
                res = self.mgr.Equals(args[0], args[1])
        elif z3.is_iff(expr):
            res = self.mgr.Iff(args[0], args[1])
        elif z3.is_xor(expr):
            res = self.mgr.Xor(args[0], args[1])
        elif z3.is_false(expr):
            res = self.mgr.FALSE()
        elif z3.is_true(expr):
            res = self.mgr.TRUE()
        elif z3.is_gt(expr):
            res = self.mgr.GT(args[0], args[1])
        elif z3.is_ge(expr):
            res = self.mgr.GE(args[0], args[1])
        elif z3.is_lt(expr):
            res = self.mgr.LT(args[0], args[1])
        elif z3.is_le(expr):
            res = self.mgr.LE(args[0], args[1])
        elif z3.is_mul(expr):
            res = self.mgr.Times(args[0], args[1])
        elif z3.is_uminus(expr):
            tp = self._get_type(args[0])
            if tp.is_real_type():
                minus_one = self.mgr.Real(-1)
            else:
                assert tp.is_int_type()
                minus_one = self.mgr.Int(-1)
            res = self.mgr.Times(args[0], minus_one)
        elif z3.is_sub(expr):
            res = self.mgr.Minus(args[0], args[1])
        elif z3.is_not(expr):
            res = self.mgr.Not(args[0])
        elif z3.is_implies(expr):
            res = self.mgr.Implies(args[0], args[1])
        elif z3.is_quantifier(expr):
            raise NotImplementedError
        elif z3.is_const(expr):
            if z3.is_rational_value(expr):
                n = expr.numerator_as_long()
                d = expr.denominator_as_long()
                f = Fraction(n, d)
                res = self.mgr.Real(f)
            elif z3.is_int_value(expr):
                n = expr.as_long()
                res = self.mgr.Int(n)
            elif z3.is_bv_value(expr):
                n = expr.as_long()
                w = expr.size()
                res = self.mgr.BV(n, w)
            elif z3.is_as_array(expr):
                if model is None:
                    raise NotImplementedError("As-array expressions cannot be" \
                                              " handled as they are not " \
                                              "self-contained")
                else:
                    interp_decl = z3.get_as_array_func(expr)
                    interp = model[interp_decl]
                    default = self.back(interp.else_value(), model=model)
                    assign = {}
                    for i in xrange(interp.num_entries()):
                        e = interp.entry(i)
                        assert e.num_args() == 1
                        idx = self.back(e.arg_value(0), model=model)
                        val = self.back(e.value(), model=model)
                        assign[idx] = val
                    arr_type = self._z3_to_type(expr.sort())
                    res = self.mgr.Array(arr_type.index_type, default, assign)
            elif z3.is_algebraic_value(expr):
                # Algebraic value
                return self.mgr._Algebraic(Numeral(expr))
            else:
                # it must be a symbol
                res = self.mgr.get_symbol(str(expr))
        elif z3.is_ite(expr):
            res = self.mgr.Ite(args[0], args[1], args[2])
        elif z3.is_function(expr):
            res = self.mgr.Function(self.mgr.get_symbol(expr.decl().name()), args)
        elif z3.is_to_real(expr):
            res = self.mgr.ToReal(args[0])
        elif z3.is_bv_and(expr):
            res = self.mgr.BVAnd(args[0], args[1])
        elif z3.is_bv_or(expr):
            res = self.mgr.BVOr(args[0], args[1])
        elif z3.is_bv_xor(expr):
            res = self.mgr.BVXor(args[0], args[1])
        elif z3.is_bv_not(expr):
            res = self.mgr.BVNot(args[0])
        elif z3.is_bv_neg(expr):
            res = self.mgr.BVNeg(args[0])
        elif z3.is_bv_concat(expr):
            res = self.mgr.BVConcat(args[0], args[1])
        elif z3.is_bv_ult(expr):
            res = self.mgr.BVULT(args[0], args[1])
        elif z3.is_bv_uleq(expr):
            res = self.mgr.BVULE(args[0], args[1])
        elif z3.is_bv_slt(expr):
            res = self.mgr.BVSLT(args[0], args[1])
        elif z3.is_bv_sleq(expr):
            res = self.mgr.BVSLE(args[0], args[1])
        elif z3.is_bv_ugt(expr):
            res = self.mgr.BVUGT(args[0], args[1])
        elif z3.is_bv_ugeq(expr):
            res = self.mgr.BVUGE(args[0], args[1])
        elif z3.is_bv_sgt(expr):
            res = self.mgr.BVSGT(args[0], args[1])
        elif z3.is_bv_sgeq(expr):
            res = self.mgr.BVSGE(args[0], args[1])
        elif z3.is_bv_extract(expr):
            end = z3.get_payload(expr, 0)
            start = z3.get_payload(expr, 1)
            res = self.mgr.BVExtract(args[0], start, end)
        elif z3.is_bv_add(expr):
            res = self.mgr.BVAdd(args[0], args[1])
        elif z3.is_bv_mul(expr):
            res = self.mgr.BVMul(args[0], args[1])
        elif z3.is_bv_udiv(expr):
            res = self.mgr.BVUDiv(args[0], args[1])
        elif z3.is_bv_sdiv(expr):
            res = self.mgr.BVSDiv(args[0], args[1])
        elif z3.is_bv_urem(expr):
            res = self.mgr.BVURem(args[0], args[1])
        elif z3.is_bv_srem(expr):
            res = self.mgr.BVSRem(args[0], args[1])
        elif z3.is_bv_lshl(expr):
            res = self.mgr.BVLShl(args[0], args[1])
        elif z3.is_bv_lshr(expr):
            res = self.mgr.BVLShr(args[0], args[1])
        elif z3.is_bv_ashr(expr):
            res = self.mgr.BVAShr(args[0], args[1])
        elif z3.is_bv_sub(expr):
            res = self.mgr.BVSub(args[0], args[1])
        elif z3.is_bv_rol(expr):
            amount = z3.get_payload(expr, 0)
            res = self.mgr.BVRol(args[0], amount)
        elif z3.is_bv_ror(expr):
            amount = z3.get_payload(expr, 0)
            res = self.mgr.BVRor(args[0], amount)
        elif z3.is_bv_ext_rol(expr):
            amount = args[1].bv_unsigned_value()
            res = self.mgr.BVRol(args[0], amount)
        elif z3.is_bv_ext_ror(expr):
            amount = args[1].bv_unsigned_value()
            res = self.mgr.BVRor(args[0], amount)
        elif z3.is_bv_sext(expr):
            amount = z3.get_payload(expr, 0)
            res = self.mgr.BVSExt(args[0], amount)
        elif z3.is_bv_zext(expr):
            amount = z3.get_payload(expr, 0)
            res = self.mgr.BVZExt(args[0], amount)
        elif z3.is_array_select(expr):
            res = self.mgr.Select(args[0], args[1])
        elif z3.is_array_store(expr):
            res = self.mgr.Store(args[0], args[1], args[2])
        elif z3.is_const_array(expr):
            arr_ty = self._z3_to_type(expr.sort())
            k = args[0]
            res = self.mgr.Array(arr_ty.index_type, k)
        elif z3.is_power(expr):
            res = self.mgr.Pow(args[0], args[1])
        if res is None:
            raise ConvertExpressionError(message=("Unsupported expression: %s" %
                                                   str(expr)),
                                         expression=expr)
        return res