Exemple #1
0
def totalAgreement(inputOutputPair, gene, aVars, rVars, expressionValues,
                   counter):

    inputName0 = inputOutputPair[0]
    inputName1 = inputOutputPair[1]
    inputName2 = inputOutputPair[2]
    outputName = inputOutputPair[3]
    input0 = expressionValues.loc[inputName0, :]
    input1 = expressionValues.loc[inputName1, :]
    input2 = expressionValues.loc[inputName2, :]
    input = [
        modeCalc([input0[i], input1[i], input2[i]]) for i in range(len(input0))
    ]
    output = expressionValues.loc[outputName, :]
    #counter += 1
    score = makeEnforcedVar("counter_%i" % counter)
    (encoding, match) = circuitEvaluatesTo(gene, aVars, rVars, input, output,
                                           counter)

    return (z3.And(
        encoding,
        z3.If(match, score == z3.BitVecVal(1, 32),
              score == z3.BitVecVal(0, 32))), score)
Exemple #2
0
def start_path_group(memory_dump, start_ip, avoid=None):
    """
    Parse a memory dump, construct a base state, and return a PathGroup.
    """
    mem = parse_mc_memory_dump(memory_dump)
    cpu = CPU()
    cpu.registers[Register.R0] = z3.BitVecVal(start_ip, 16)
    path = Path()
    inp = IO(IOKind.INPUT, [])
    out = IO(IOKind.OUTPUT, [])

    entry_state = State(cpu, mem, path, inp, out, False)
    pg = PathGroup([entry_state], avoid=avoid)
    return pg
    def declare_global_constant(self,
                                ctx,
                                name,
                                global_type,
                                value=None,
                                value_type=None):
        ctx['globals'][name] = dt.fresh_ptr(ctx, name, global_type)

        if value_type.is_array() and value_type.deref().is_int():
            inner_size = value_type.deref().size()
            for n, i in enumerate(util.parse_constant_array(value)):
                ctx['globals'][name].getelementptr(
                    ctx, util.i64(0),
                    util.i64(n)).write(ctx, z3.BitVecVal(i, inner_size))
    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
Exemple #5
0
 def value(self):
     return simplify(
         z3.Concat(
             self.ppn,
             z3.BitVecVal(0, 2),
             resize(self.d, 1),
             resize(self.a, 1),
             resize(self.g, 1),
             resize(self.u, 1),
             resize(self.x, 1),
             resize(self.w, 1),
             resize(self.r, 1),
             resize(self.v, 1),
         ))
Exemple #6
0
 def update_storages(self, sstore_data):
     for address, index, value in sstore_data:
         address = int(address[2:], 16)
         assert address in self.root_wstate.address_to_account
         if index > 100:
             if index in self.log_sha_to_sym_sha:
                 store_index = self.log_sha_to_sym_sha[index]
             else:
                 log_shas = list(self.log_sha_to_sym_sha.keys())
                 diffs = [abs(l - index) for l in log_shas]
                 min_index = diffs.index(min(diffs))
                 diff = diffs[min_index]
                 if diff < 10:
                     relative_index = log_shas[min_index]
                     store_index = z3.simplify(self.log_sha_to_sym_sha[relative_index] + z3.BitVecVal(diff, 256))
                     self.log_sha_to_sym_sha[index] = store_index
                 else:
                     store_index = z3.BitVecVal(index, 256)
         else:
             store_index = z3.BitVecVal(index, 256)
         store_value = self.log_sha_to_sym_sha.get(value, z3.BitVecVal(value, 256))
         account = self.root_wstate.address_to_account[address]
         account.storage.store(store_index, store_value)
Exemple #7
0
def check_interp(interp, constraints, bits=32, valbits=8):
    """Checks that a list of @constraints (addr, value) (as python ints)
    match a z3 FuncInterp (@interp).
    """
    constraints = dict((addr,
                        z3.BitVecVal(val, valbits))
                       for addr, val in constraints)
    l = interp.as_list()
    for entry in l:
        if not isinstance(entry, list) or len(entry) < 2:
            continue
        addr, value = entry[0], entry[1]
        if addr.as_long() in constraints:
            assert equiv(value, constraints[addr.as_long()])
Exemple #8
0
def sys_reclaim_vector(old, vector):
    pid = old.vectors[vector].owner
    cond = z3.And(
        is_pid_valid(pid),
        old.procs[pid].state == dt.proc_state.PROC_ZOMBIE,
        old.procs[pid].nr_intremaps() == 0,
    )

    new = old.copy()

    new.vectors[vector].owner = z3.BitVecVal(0, dt.pid_t)
    new.procs[pid].nr_vectors[vector] -= 1

    return cond, util.If(cond, new, old)
Exemple #9
0
def z3_cast(val, to_type):
    # FIXME: Unify to_type properly
    # some checks to guarantee that the inputs are usable
    if isinstance(val, (z3.BoolSortRef, z3.BoolRef)):
        # Convert boolean variables to a bit vector representation
        # TODO: Streamline bools and their evaluation
        val = z3.If(val, z3.BitVecVal(1, 1), z3.BitVecVal(0, 1))

    if isinstance(to_type, (z3.BoolSortRef, z3.BoolRef)):
        # casting to a bool is simple, just check if the value is equal to 1
        # this works for bitvectors and integers, we convert any bools before
        # if val is not a single bit vector, this will (intentionally) fail
        return val == z3.BitVecVal(1, 1)
    # from here on we assume we are working with integer or bitvector types
    if isinstance(to_type, (z3.BitVecSortRef, z3.BitVecRef)):
        # It can happen that we get a bitvector type as target, get its size.
        to_type_size = to_type.size()
    elif not isinstance(to_type, int) and to_type == z3.IntSort():
        return val.as_long()
    else:
        to_type_size = to_type

    if isinstance(val, int):
        # It can happen that we get an int, cast it to a bit vector.
        return z3.BitVecVal(val, to_type_size)

    # preprocessing done, the actual casting starts here
    val_size = val.size()
    if val_size < to_type_size:
        # the target value is larger, extend with zeros
        return z3.ZeroExt(to_type_size - val_size, val)
    elif val_size > to_type_size:
        # the target value is smaller, truncate everything on the right
        return z3.Extract(to_type_size - 1, 0, val)
    else:
        # nothing to do
        return val
Exemple #10
0
def free_page_table_page(old, frm, index, to, from_type, to_type):
    cond = z3.And(
        # The frm pn has the correct type and owned by current
        is_pn_valid(frm),
        old.pages[frm].type == from_type,
        old.pages[frm].owner == old.current,

        # Index is a valid page index
        z3.ULT(index, 512),

        # The to pn has the correct type and owned by current
        is_pn_valid(to),
        old.pages[to].type == to_type,
        old.pages[to].owner == old.current,

        # index does have the P bit in the from page
        old.pages[frm].data(index) & dt.PTE_P != 0,

        # The current pgtable entry matches to...
        z3.Extract(63, 40, z3.UDiv(old.pages_ptr_to_int,
                                   util.i64(dt.PAGE_SIZE)) + to) == z3.BitVecVal(0, 24),
        z3.Extract(39, 0, z3.UDiv(old.pages_ptr_to_int, util.i64(
            dt.PAGE_SIZE)) + to) == z3.Extract(51, 12, old.pages[frm].data(index)),
    )

    new = old.copy()

    new.pages[frm].data[index] = util.i64(0)

    new.pages[to].owner = z3.BitVecVal(0, dt.pid_t)
    new.pages[to].type = dt.page_type.PAGE_TYPE_FREE

    new.procs[old.current].nr_pages[to] -= 1

    new.flush_tlb(old.current)

    return cond, util.If(cond, new, old)
Exemple #11
0
    def __eq__(self, other: Union[int, "BitVec"]) -> Bool:  # type: ignore
        """Create an equality expression.

        :param other: The int or BitVec to compare to this BitVecFunc
        :return: The resulting Bool
        """

        if not isinstance(other, BitVec):
            other = BitVec(z3.BitVecVal(other, self.size()))

        return _comparison_helper(self,
                                  other,
                                  operator.eq,
                                  default_value=False,
                                  inputs_equal=True)
Exemple #12
0
def If(a: Union[Bool, bool], b: Union[BitVec, int], c: Union[BitVec,
                                                             int]) -> BitVec:
    """Create an if-then-else expression.

    :param a:
    :param b:
    :param c:
    :return:
    """
    # TODO: Handle BitVecFunc

    if not isinstance(a, Bool):
        a = Bool(z3.BoolVal(a))
    if not isinstance(b, BitVec):
        b = BitVec(z3.BitVecVal(b, 256))
    if not isinstance(c, BitVec):
        c = BitVec(z3.BitVecVal(c, 256))
    union = a.annotations.union(b.annotations).union(c.annotations)

    bvf = []  # type: List[BitVecFunc]
    if isinstance(a, BitVecFunc):
        bvf += [a]
    if isinstance(b, BitVecFunc):
        bvf += [b]
    if isinstance(c, BitVecFunc):
        bvf += [c]
    if bvf:
        raw = z3.If(a.raw, b.raw, c.raw)
        nested_functions = [
            nf for func in bvf for nf in func.nested_functions
        ] + bvf
        return BitVecFunc(raw,
                          func_name="Hybrid",
                          nested_functions=nested_functions)

    return BitVec(z3.If(a.raw, b.raw, c.raw), union)
def opcode_get_memory(memory, offset, length=32):
    parts = []
    if not is_z3_express(length):
        for i in range(format_to_int(length)):
            index = opcode_add(offset, i)
            parts.append(memory[index])

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

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

    return z3.simplify(z3.Concat(parts))
Exemple #14
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
Exemple #15
0
 def to_z3(self, val, strict=False):
     if val in self.map:
         return self.map[val]
     if val not in self.domain and val is not None:
         if strict:
             raise exception.PolicyRuntimeException(
                 "Z3 Finite type: {} is not a value of {}".format(
                     val, self.name))
         else:
             val = '__OTHER__'
     code = len(self.map)
     bvect = z3.BitVecVal(code, self.type_instance)
     self.map[val] = bvect
     self.back[code] = val
     return bvect
def _to_smt_constant_expression(expr_object, smt_context_object):
    val_obj = expr_object.value_object
    constant_type = val_obj.value_type
    if (constant_type.type_code == exprtypes.TypeCodes.boolean_type):
        return z3.BoolVal(val_obj.value_object, smt_context_object.ctx())
    elif (constant_type.type_code == exprtypes.TypeCodes.integer_type):
        return z3.IntVal(val_obj.value_object, smt_context_object.ctx())
    elif (constant_type.type_code == exprtypes.TypeCodes.bit_vector_type):
        int_value = val_obj.value_object.value
        return z3.BitVecVal(int_value, constant_type.size,
                            smt_context_object.ctx())
    elif (constant_type.type_code == exprtypes.TypeCodes.string_type):
        return z3.StringVal(val_obj.value_object, smt_context_object.ctx())
    else:
        raise basetypes.UnhandledCaseError('Odd type code: %s' % constant_type.type_code)
def opcode_init_call_data(calldata, init_data):
    if init_data[:2] == '0x':
        init_data = init_data[2:]

    length = len(init_data) / 2
    low = 0
    high = low + 2

    for i in range(length):
        data = int(init_data[low:high], 16)
        calldata = z3.Store(calldata, i, z3.BitVecVal(data, 8))
        low += 2
        high = low + 2

    return z3.simplify(calldata)
Exemple #18
0
def register_define(context, n, s, f, bit_is_set):
    """Register and define one comparison to constant

    :param context: z3 context to create predicate and rules
    :param n: the constant
    :param s: the size of domain
    :param f: the predicate implementing the comparison
    :param bit_is_set: when we check a bit, add a rule if set or not depending
        on the truth of this arg. This is the way we handle < and > in a single
        function.
    """
    context.register_relation(f)
    sort = f.domain(0)
    var = z3.Const('X', sort)
    glob_mask = (1 << s) - 1
    for p in range(s):
        bit = 1 << p
        if (n & bit != 0) == bit_is_set:
            mask = glob_mask ^ (bit - 1)
            prefix = (n & mask) ^ bit
            z3_prefix = z3.BitVecVal(prefix, sort)
            z3_mask = z3.BitVecVal(mask, sort)
            equation = z3_prefix == (var & z3_mask)
            context.rule(z3.ForAll([var], z3.Implies(equation, f(var))))
Exemple #19
0
def calculate(solver, xs):
    MOD_BASE = z3.BitVecVal(36, 8)

    solver.add(((xs[0] + xs[1]) % MOD_BASE) == 14)
    solver.add(((xs[2] + xs[3]) % MOD_BASE) == 24)
    solver.add(((xs[2] - xs[0]) % MOD_BASE) == 6)
    solver.add(((xs[1] + xs[3] + xs[5]) % MOD_BASE) == 4)
    solver.add(((xs[2] + xs[4] + xs[6]) % MOD_BASE) == 13)
    solver.add(((xs[3] + xs[4] + xs[5]) % MOD_BASE) == 22)
    solver.add(((xs[6] + xs[8] + xs[10]) % MOD_BASE) == 31)
    solver.add(((xs[1] + xs[4] + xs[7]) % MOD_BASE) == 7)
    solver.add(((xs[9] + xs[12] + xs[15]) % MOD_BASE) == 20)
    solver.add(((xs[13] + xs[14] + xs[15]) % MOD_BASE) == 12)
    solver.add(((xs[8] + xs[9] + xs[10]) % MOD_BASE) == 27)
    solver.add(((xs[7] + xs[12] + xs[13]) % MOD_BASE) == 23)
class TestBoolType(base.TestCase):
    """Z3 Boolean values"""
    bool_false = z3.BitVecVal(0, 1)
    bool_true = z3.BitVecVal(1, 1)

    def setUp(self):
        self.type = primitives.BoolType()
        super(TestBoolType, self).setUp()

    def test_marshal(self):
        self.assertEqual('True', self.type.marshall(True))
        self.assertEqual('False', self.type.marshall(False))

    def test_unmarshal(self):
        self.assertEqual(True, self.type.unmarshall('True'))
        self.assertEqual(False, self.type.unmarshall('False'))

    def test_to_z3(self):
        self.assertEqual(TestBoolType.bool_true, self.type.to_z3(True))
        self.assertEqual(TestBoolType.bool_false, self.type.to_z3(False))

    def test_from_z3(self):
        self.assertEqual(True, TestBoolType.bool_true)
        self.assertEqual(False, TestBoolType.bool_false)
Exemple #21
0
    def getOperands(self, ops, concat=True):

        rops = []
        for op in ops:
            if (op.isVar()):
                if (op.size > 1):
                    rops.append(
                        z3.Concat(
                            map(lambda b: z3.BitVec(b, 8), op.get_bytes())))
                else:
                    rops.append(z3.BitVec(op.get_bytes()[0], 8))
            else:
                rops.append(z3.BitVecVal(op.getValue(), 8 * op.size))

        return rops
Exemple #22
0
    def __new_constant__(self, constant, code: int):
        """
		:param constant: bool | int | float
		:param code:
		:return:
		"""
        if isinstance(constant, bool):
            return z3.BoolVal(constant)
        elif isinstance(constant, int):
            if code == self.__s_code__:
                return z3.BitVecVal(constant, self.longLength)
            else:
                return z3.IntVal(constant)
        else:
            return z3.RealVal(constant)
Exemple #23
0
def sv32(options, asid, ppn):
    return VMMode(
        options,
        mode=z3.BitVecVal(1, 1),
        asid=asid,
        ppn=ppn,
        pa_size=34,
        page_size=4096,
        pte_size=4,
        levels=2,
        vpn_bits=[(21, 12), (31, 22)],
        ppn_bits=[(19, 10), (31, 20)],
        f_satp=satp32,
        f_pte=pte32,
    )
Exemple #24
0
def sv48(options, asid, ppn):
    return VMMode(
        options,
        mode=z3.BitVecVal(9, 4),
        asid=asid,
        ppn=ppn,
        pa_size=56,
        page_size=4096,
        pte_size=8,
        levels=3,
        vpn_bits=[(20, 12), (29, 21), (38, 30), (47, 39)],
        ppn_bits=[(18, 10), (27, 19), (36, 28), (53, 37)],
        f_satp=satp64(9),
        f_pte=pte64,
    )
Exemple #25
0
def bare64(options):
    return VMMode(
        options,
        mode=z3.BitVecVal(0, 4),
        asid=0,
        ppn=0,
        pa_size=34,
        page_size=None,
        pte_size=None,
        levels=None,
        vpn_bits=[],
        ppn_bits=[],
        f_satp=satp64,
        f_pte=None,
    )
Exemple #26
0
def spec_lemma_nr_fds_refcnt(kernelstate):
    conj = []

    pid = util.FreshBitVec('pid', dt.pid_t)
    fd = util.FreshBitVec('fd', dt.fd_t)

    # unused procs do not have any fds.
    # valid(pid) & state(pid)== PROC_UNUSED ==> pid.nr_fds == 0
    conj.append(
        z3.ForAll(
            [pid],
            z3.Implies(
                is_pid_valid(pid),
                z3.Implies(
                    kernelstate.procs[pid].state == dt.proc_state.PROC_UNUSED,
                    kernelstate.procs[pid].nr_fds() == z3.BitVecVal(
                        0, dt.size_t)))))

    # unused procs do not have any opened files
    # valid(pid) & valid(fd) & state(pid) == PROC_UNUSED ==> !valid(openedfile(pid, fd))
    conj.append(
        z3.ForAll(
            [pid, fd],
            z3.Implies(
                z3.And(is_pid_valid(pid), is_fd_valid(fd)),
                z3.Implies(
                    kernelstate.procs[pid].state == dt.proc_state.PROC_UNUSED,
                    z3.Not(is_fn_valid(kernelstate.procs[pid].ofile(fd)))))))

    # a procs have opened a file, the state of this procs must not be UNUSED
    # valid(pid) & valid(fd) & valid(fn)  ==> state(pid) != PROC_UNUSED
    conj.append(
        z3.ForAll(
            [pid, fd],
            z3.Implies(
                z3.And(is_pid_valid(pid), is_fd_valid(fd),
                       is_fn_valid(kernelstate.procs[pid].ofile(fd))),
                kernelstate.procs[pid].state != dt.proc_state.PROC_UNUSED)))

    # Correctness definition for `permutation` based refcount
    kernelstate.procs.nr_fds.check(
        conj,
        is_owner_valid=is_pid_valid,
        is_owned_valid=is_fd_valid,
        max_refs=dt.NOFILE,
        ownedby=lambda pid, fd: is_fn_valid(kernelstate.procs[pid].ofile(fd)))

    return z3.And(*conj)
Exemple #27
0
    def _get_register(self, reg):
        """Get the current value of the specified register"""

        reg = canonical_register(reg)
        if reg == canonical_register("zero"):
            return resize(0, self._options.xlen)
        try:
            r = self._registers[reg]
            return r
        except KeyError:
            if self._options.arbitrary_initial_values:
                init = z3.BitVec(f"_{self.name}_{reg}_init",
                                 self._options.xlen)
            else:
                init = z3.BitVecVal(0, self._options.xlen)
            return self._registers.setdefault(reg, init)
Exemple #28
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
Exemple #29
0
 def srem(self,
          ctx,
          return_type,
          a,
          atype,
          b,
          btype,
          nuw=False,
          nsw=False,
          exact=False):
     assert atype == return_type
     assert atype == btype
     assert not nuw and not nsw and not exact
     assert util.path_condition_implies(
         ctx, b != z3.BitVecVal(0, btype.size())), "srem by zero"
     return z3.SRem(a, b)
Exemple #30
0
    def blank_state(self, addr: Address = 0) -> ESILState:
        """
        Create an ESILState with everything (except PC) symbolic

        :param addr:     Name of function or address to begin execution
        """

        addr = self.r2api.get_address(addr)

        self.state_manager = ESILStateManager([], lazy=self.lazy)
        options = self.options.copy()
        options["sym"] = True
        state = self.state_manager.entry_state(self.r2api, **options)
        pc_size = state.registers["PC"].size()
        state.registers["PC"] = z3.BitVecVal(addr, pc_size)
        return state