Example #1
0
File: core.py Project: kr0/PyEuclid
 def construct(self, obj):
     '''
     Takes in a ConstructableObject with preconditions
     and postconditions. Checks that preconditions hold
     in the proof context and if so, asserts the post-conditions.
     '''
     self.solver.push()
     for prereq in obj.prereqs:
         self.solver.add(simplify(prereq, blast_distinct = True))
         prereqCheck = self.solver.check()
         if str(prereqCheck) != 'sat':
             print "ProofCheck >> Construction Failed - Could not meet: " + str(prereq) 
             self.solver.pop()
             return False
         
     if len(obj.prereqs) > 0:
         self.assumptions.extend(obj.prereqs)
         
     for conclusion in obj.conclusions:
         self.solver.add(simplify(conclusion, blast_distinct=True))
         self.conclusions.append(conclusion)
     
     if isinstance(obj, Point):
         self.points[obj.label] = obj
     elif isinstance(obj, Line):
         self.lines[obj.label] = obj
     elif isinstance(obj, Circle):
         self.circles[obj.label] = obj
         
     self.solver.pop()
     self.solver.add(obj.prereqs)
     self.solver.add(obj.conclusions)
     return True
Example #2
0
    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 []
Example #3
0
    def visit_WhileStmt_inv (self, node, *args, **kwargs):
        """" Symbolic execution of while loops with invariants """
        print("node.inv=",node.inv)
        # evaluate invariant before the loop
        inv_pre = self.visit (node.inv, *args, **kwargs)
        print("node.inv_2.0=",inv_pre)
        # fork symbolic state to evaluate the invariant in the pre-condition
        pre_st, loop_st = kwargs['state'].fork ()

        # pre_st.add_pc (z3.Not (inv_pre))
        # if not pre_st.is_empty ():
        pre_st.add_pc (inv_pre)
        if pre_st.is_empty ():
            print ('Invariant not true on loop entry')
            print (node.inv)
            print (pre_st)

        # havoc all variables modified by the loop
        for v in self._defs (node.body):
            loop_st.env [v.name] = z3.FreshInt (v.name)
            # print("v",v,loop_st)

        # evaluate invariant after havoc and assume it
        inv_pre = z3.simplify (self.visit (node.inv, *args, state=loop_st))
        loop_st.add_pc (inv_pre)

        # evaluate loop condition
        cond_val = self.visit (node.cond, *args, state=loop_st);

        # one state enters the loop, one exits
        enter_st, exit_st = loop_st.fork ()

        # if enter loop, loop condition is true
        enter_st.add_pc (cond_val)
        # if exit loop, loop condition is false
        exit_st.add_pc (z3.Not (cond_val))

        # if loop condition can be satisfied, check invariant preserved by loop body
        if not enter_st.is_empty ():
            # do loop body, might produce many new states
            # print("------------",kwargs["state"],enter_st)
            for out in self.visit (node.body, *args, state=enter_st):
                # print("--------------",out)
                # check that invariant holds at the end of each body
                inv_post = z3.simplify (self.visit (node.inv, *args, state=out))
                # inv_post =self.visit (node.inv, *args, state=out)
                out.add_pc (z3.Not (inv_post))
                if not out.is_empty ():
                    print ('Invariant does not hold on loop exit')
                    print( "2",exit_st)
                    # print ('inv:', node.inv)
                    # print ('inv_post', inv_post)
                    # print ('out', out)
                    # print ('pc', z3.And (out.path).sexpr ())

        # if negation of loop condition is satisfied, continue execution after the loop
        if not exit_st.is_empty ():
            yield exit_st
Example #4
0
    def may_write_to(self, z3_index, z3_value, storage, constraint_list, consider_length):
        z3_index = simplify(get_bv(z3_index))
        z3_value = simplify(get_bv(z3_value))

        same_slot = False

        add_constraints = []

        # z3-index directly pointing to this slot
        concret_index = BitVecVal(self.slot_counter, 256)

        # Compare expression equivalence
        if eq(concret_index, z3_index):
            same_slot = True

        # If not structurally equivalent, check if there is an assignment that allows them to be equivalent
        if not same_slot and not are_z3_satisfiable(constraint_list + [z3_index == concret_index]):
            return False, None
        add_constraints.append(simplify(z3_index == self.slot_counter))

        index_str = str(z3_index)
        # Rule out keccak symbolic variable as the function prevents someone from arbitrarily controlling the index

        if len(z3_index.children()) < 2 and index_str.startswith("keccak") \
                or "+" in index_str and index_str[:index_str.index("+")].strip() in keccak_map :
            return False, None # Todo Here I might do something more elaborate if I see that it does actually not solve critical writings

        # Problem because writing to an array has a keccak offset, but if the index can be arbitrarely choosen z3 finds
        # a solution for the controllable symbolic variable to match the index to any slot.
        #sym_ind_name = extract_sym_names(z3_index)
        #if any([name for name in sym_ind_name if name.startswith("keccak")]) and any([name for name in sym_ind_name if not name.startswith("keccak")]):
        #    return False, None

        # If the slot is or may be the same and the slot we currently analyze is the same, we found a possible write
        if self.bitlength == 256:
            return True, add_constraints

        # If not, the slot is still written in its entirety but the observed chunk is loaded and overwritten by itself
        to_bit, from_bit = self.bit_counter + self.bitlength - 1, self.bit_counter
        # to_bit, from_bit = BitVecVal(self.bit_counter + self.bitlength - 1, 256), BitVecVal(self.bit_counter, 256)
        chunk_writing = Extract(to_bit, from_bit, z3_value)

        chunk_content = Extract(to_bit, from_bit,
                                get_bv(get_storage_slot(BitVecVal(self.slot_counter, 256), storage)))

        # if the current content of the observed chunk and the respective chunk of the written value can be different
        # like by a different variable assignment, then we found it
        if are_z3_satisfiable(constraint_list + [Not(chunk_content == chunk_writing)]):
            # It is actually not important to use the constraint that the values are different, overwriting with the same
            # value is still writing. On the other hand it avoids references to storage that later have to be solved with
            # intertransactional analysis although the violation can be triggered in one transaction
            # add_constraints.append(simplify(Not(chunk_content == chunk_writing)))
            return True, add_constraints

        # For the 256-bit chunks the last step should not be necessary, but a compiler could generate some code that
        # overwrites a slot content with itself. This function would have a false positive in that case.

        return False, None
Example #5
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
Example #6
0
def sig_line(foo, prev_v, nxt_v):
    foo_prev = x.maybe_usc_sig_usc_sub_usc_value.val(prev_v[foo[1]])
    foo_nxt = x.maybe_usc_sig_usc_sub_usc_value.val(nxt_v[foo[1]])
    foo_line = ("%20s %5s @ %12s -> %5s @ %12s" %
                (foo[0], str(simplify(x.sig_sub_value.value(foo_prev))),
                 z3numstr(x.sig_sub_value.time(foo_prev)),
                 str(simplify(x.sig_sub_value.value(foo_nxt))),
                 z3numstr(x.sig_sub_value.time(foo_nxt))))
    return (foo_line)
Example #7
0
    def visit_WhileStmt(self, node, *args, **kwargs):
        if node.inv is not None:
            pre_inv = z3.simplify(self.visit(node.inv, *args, **kwargs))
            p_st, loop_st = kwargs['state'].fork()

            p_st.add_pc(z3.Not(pre_inv))
            if not p_st.is_empty():
                print('Invariant is false before entry the loop')
                print(node.inv)
                print(p_st)
            checker = wlang.undef_visitor.UndefVisitor()
            checker.check(node.body)

            for v in checker.get_defs():
                loop_st.env[v.name] = z3.FreshInt(v.name)

            inv_pre = z3.simplify(self.visit(node.inv, *args, state=loop_st))
            loop_st.add_pc(inv_pre)
            #if else
            cond = self.visit(node.cond, *args, state=loop_st)
            st = loop_st.fork()
            st[0].add_pc(cond)
            st[1].add_pc(z3.Not(cond))
            #enter loop
            if not st[0].is_empty():
                result = self.visit(node.body, state=st[0])
                for out in result:
                    inv_post = z3.simplify(
                        self.visit(node.inv, *args, state=out))
                    out.add_pc(z3.Not(inv_post))
                    if not out.is_empty():
                        print('Invariant violation on loop exit')
                        print('inv:', node.inv)
                        print('out', out)
                        print('pc', z3.And(out.path).sexpr())
            if not st[1].is_empty():
                return [st[1]]
            else:
                return []

        todo = [kwargs['state']]
        done = []
        for _ in range(11):
            if not todo: break
            res = []
            for i in todo:
                cond = self.visit(node.cond, state=i)
                st = i.fork()
                st[0].add_pc(cond)
                st[1].add_pc(z3.Not(cond))

                if not st[0].is_empty():
                    res.extend(self.visit(node.body, state=st[0]))
                if not st[1].is_empty(): done.append(st[1])
            todo = res

        return done
Example #8
0
def checkLengthBMC(M, bad, count):

        x = []
        for i in range(count):
                x.append(M.addSuffix(str(i)))

	bad = z3.simplify(z3.And(bad(x[-1])))
	init = z3.simplify(z3.And(M.initialize(x[0])))
	trx = True

        for i in range(count-1):
                temp = M.transition(x[i])
                temp = z3.And(*[xi == xpi for (xi, xpi) in itertools.izip(temp, x[i+1])])
                trx = z3.And(trx, temp)

	S = z3.Solver()
	S.add(init)
        S.add(trx)
        S.add(bad)
	rBMC = (S.check())

        if rBMC == z3.unsat:
                # Compute the interpolant
                formula1 = True
                formula2 = True
                xprime = []
                for i in range(count):
                        xprime.append(M.addSuffix(str(i)+"_prime"))
                formula1 = z3.And(init, trx)
                initprime = z3.simplify(z3.And(M.initialize(xprime[0])))
                trxprime = True

                for i in range(count-1):
                        temp = M.transition(xprime[i])
                        temp = z3.And(*[xi == xpi for (xi, xpi) in itertools.izip(temp, xprime[i+1])])
                        trxprime = z3.And(trxprime, temp)

                formula1 = z3.And(formula1, initprime, trxprime)

                # xval are the exact values that consecutive states of M take
                xval = [[0, 1]]                                                   
                temp = True
                
                for i in range(count-1):
                        xval.append(M.transition(xval[i]))

                for i in range(1, count):
                        temp = z3.And(temp, *[xi == xvi for (xi, xvi) in itertools.izip(x[i], xval[i])])

                formula1 = z3.And(formula1, temp)
                
                Msc = SelfComposedTransitionSystem(M)
                formula2 = z3.simplify(z3.And(Msc.bad_sc(x[count-1]+xprime[count-1])))

                return z3.unsat, x[count-1]+xprime[count-1], formula1
                
        return rBMC, None, None
Example #9
0
    def jumpi_(self, global_state):
        state = global_state.mstate
        disassembly = global_state.environment.code
        states = []

        op0, condition = state.stack.pop(), state.stack.pop()

        try:
            jump_addr = util.get_concrete_int(op0)
        # FIXME: to broad exception handler
        except:
            logging.debug("Skipping JUMPI to invalid destination.")
            return [global_state]

        index = util.get_instruction_index(disassembly.instruction_list,
                                           jump_addr)

        if not index:
            logging.debug("Invalid jump destination: " + str(jump_addr))
            return [global_state]
        instr = disassembly.instruction_list[index]

        # True case
        condi = simplify(condition) if type(
            condition) == BoolRef else condition != 0
        if instr['opcode'] == "JUMPDEST":
            if (type(condi) == bool and condi) or (type(condi) == BoolRef
                                                   and not is_false(condi)):
                new_state = copy(global_state)
                new_state.mstate.pc = index
                new_state.mstate.depth += 1

                new_state.mstate.constraints.append(condi if type(condi) ==
                                                    bool else simplify(condi))

                states.append(new_state)
            else:
                logging.debug("True, Pruned unreachable states. at %s" %
                              (state.pc))

        # False case
        negated = simplify(
            Not(condition)) if type(condition) == BoolRef else condition == 0

        if (type(negated) == bool and negated) or (type(negated) == BoolRef
                                                   and not is_false(negated)):
            new_state = copy(global_state)
            new_state.mstate.depth += 1
            new_state.mstate.constraints.append(negated if type(negated) ==
                                                bool else simplify(negated))
            states.append(new_state)
        else:
            logging.debug("False, Pruned unreachable states. at %s" %
                          (state.pc))

        return states
    def exp_(self, global_state):
        state = global_state.mstate

        base, exponent = util.pop_bitvec(state), util.pop_bitvec(state)
        if (type(base) != BitVecNumRef) or (type(exponent) != BitVecNumRef):
            state.stack.append(BitVec("(" + str(simplify(base)) + ")**(" + str(simplify(exponent)) + ")", 256))
        else:
            state.stack.append(pow(base.as_long(), exponent.as_long(), 2**256))

        return [global_state]
Example #11
0
    def test_candidate(self, synth_func, candidate):
        # candidate = expr_string_to_z3(candidate_word, self.spec, synth_func['inputs'])

        goal = substitute_function_for_expression(self.spec.goal,
                                                  synth_func["decl"],
                                                  synth_func["z3_inputs"],
                                                  candidate)

        while True:
            macro_decl = contains_funcs(goal, self._macros_decls)
            if macro_decl is None:
                break
            macro_name = macro_decl.name()
            macro = self.spec.macros[macro_name]
            macro_def = expr_string_to_z3(macro["definition"], self.spec,
                                          macro["inputs"])
            macro_params = macro["z3_inputs"]
            goal = substitute_function_for_expression(goal, macro_decl,
                                                      macro_params, macro_def)

        if self.universally_quantified:
            counter_example_constraints = [z3.BoolVal(True)]
            for counter_example in self.counter_examples:
                counter_example_constraints.append(
                    z3.simplify(
                        z3.substitute(
                            goal,
                            list(zip(self.spec.z3_variables,
                                     counter_example)))))
            counter_example_constraint = z3.simplify(
                z3.And(*counter_example_constraints))
            if counter_example_constraint.eq(z3.BoolVal(False)):
                return "sat"
            if not counter_example_constraint.eq(z3.BoolVal(True)):
                goal = z3.And(goal, counter_example_constraint)
        else:
            if goal.eq(z3.BoolVal(True)):
                return "unsat"
            if goal.eq(z3.BoolVal(False)):
                return "sat"

        goal = z3.simplify(z3.Not(goal))

        s = z3.Solver()
        s.add(goal)

        validity = str(s.check())
        if validity == "sat":
            counter_example = []
            model = s.model()
            for var in self.spec.z3_variables:
                counter_example.append(model.eval(var))
            self.counter_examples.append(counter_example)

        return validity
Example #12
0
def relationalInduction(M, Msc, bad_sc):
    xs = Msc.variables()
    xsp = Msc.variables('prime')

    bad = z3.simplify(z3.And(bad_sc(xs)))
    init = z3.And(Msc.init(xs))
    check = z3.simplify(z3.And(init, bad))

    S = z3.Solver()
    S.push()
    S.add(check)
    rInit = (S.check())
    S.pop()
    assert (rInit == z3.unsat)

    S.push()
    good_assume = z3.simplify(z3.And(z3.Not(bad_sc(xs))))
    bad_proofob = z3.simplify(z3.And(bad_sc(xsp)))
    trx = z3.simplify(z3.And(Msc.tr(xs, xsp)))
    S.add(good_assume)
    S.add(bad_proofob)
    S.add(trx)
    n = len(xs) // 2
    while S.check() == z3.sat:
        m = S.model()
        xm1 = [m.eval(xsi) for xsi in xs[:n]]
        xm2 = [m.eval(xsi) for xsi in xs[n:]]
        bad1 = lambda xs: [
            z3.And(*[xi == xmi for (xi, xmi) in itertools.izip(xm1, xs)])
        ]
        bad2 = lambda xs: [
            z3.And(*[xi == xmi for (xi, xmi) in itertools.izip(xm2, xs)])
        ]
        print(xm1, xm2)
        (r1, vs1, inv1) = fixedpoint(M, bad1)
        if r1 == z3.unsat:
            sub1 = zip(vs1, xs[:n])
            sub2 = zip(vs1, xs[n:])
            p1 = z3.substitute(inv1, *sub1)
            p2 = z3.substitute(inv1, *sub2)
            S.add(p1)
            S.add(p2)
            print(p1, p2)
            continue
        (r2, vs2, inv2) = fixedpoint(M, bad2)
        if r2 == z3.unsat:
            sub1 = zip(vs2, xs[:n])
            sub2 = zip(vs2, xs[n:])
            p1 = z3.substitute(inv2, *sub1)
            p2 = z3.substitute(inv2, *sub2)
            S.add(p1)
            S.add(p2)
            print(p1, p2)
    S.pop()
Example #13
0
def ast_eq(e1, e2, simplified=False):
    if not simplified:
        e1 = z3.simplify(e1)
        e2 = z3.simplify(e2)
    if e1.sort() != e2.sort():
        return False
    if e1.decl().kind() != e2.decl().kind():
        return False
    if z3.z3util.is_expr_val(e1) and z3.z3util.is_expr_val(e2):
        return e1.as_long() == e2.as_long()
    return all(ast_eq(c1, c2, True) for c1, c2 in zip(e1.children(), e2.children()))
Example #14
0
    def prove(self, hypotheses, conclusion=None, report=None):
        report = self.reportFun(report)

        x_hyps, x_concl = self.analyse_expt(hypotheses, conclusion, report)
        f_hyps, f_concl = self.fun_to_var([x_hyps, x_concl], report)[:]
        hyps = z3.simplify(f_hyps); concl = z3.simplify(f_concl)

        report('to_smt_w_expt.prove:')
        report('  hypotheses = ', hyps)
        report('  conclusion = ', concl)
        return super(to_smt_w_expt, self).prove(hyps, concl)
Example #15
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
Example #16
0
File: SMT.py Project: 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()
Example #17
0
File: SMT.py Project: mayfly74/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()
Example #18
0
    def calldataload_(self, global_state):
        state = global_state.mstate
        environment = global_state.environment
        op0 = state.stack.pop()

        try:
            offset = util.get_concrete_int(simplify(op0))
            b = environment.calldata[offset]
        except AttributeError:
            logging.debug("CALLDATALOAD: Unsupported symbolic index")
            state.stack.append(
                BitVec(
                    "calldata_" +
                    str(environment.active_account.contract_name) + "[" +
                    str(simplify(op0)) + "]", 256))
            return [global_state]
        except IndexError:
            logging.debug("Calldata not set, using symbolic variable instead")
            state.stack.append(
                BitVec(
                    "calldata_" +
                    str(environment.active_account.contract_name) + "[" +
                    str(simplify(op0)) + "]", 256))
            return [global_state]

        if type(b) == int:
            val = b''

            try:
                for i in range(offset, offset + 32):
                    val += environment.calldata[i].to_bytes(1, byteorder='big')

                logging.debug("Final value: " +
                              str(int.from_bytes(val, byteorder='big')))
                state.stack.append(
                    BitVecVal(int.from_bytes(val, byteorder='big'), 256))
            # FIXME: broad exception catch
            except:
                state.stack.append(
                    BitVec(
                        "calldata_" +
                        str(environment.active_account.contract_name) + "[" +
                        str(simplify(op0)) + "]", 256))
        else:
            # symbolic variable
            state.stack.append(
                BitVec(
                    "calldata_" +
                    str(environment.active_account.contract_name) + "[" +
                    str(simplify(op0)) + "]", 256))

        return [global_state]
Example #19
0
    def visit_WhileStmt(self, node, *args, **kwargs):
        if node.inv is not None:
            sim_inv = z3.simplify(self.visit(node.inv, *args, **kwargs))
            init_state = kwargs['state'].fork()
            not_inv_state = init_state[0]
            inv_state = init_state[1]

            # inv fails initiation
            if not_inv_state.addcond_isSolvable(z3.Not(sim_inv)):
                print("inv fails initiation")
            # use Undefined Use Visitor to find all variables that are modified or defined
            for var in self._defs(node.body):
                inv_state.env[var.name] = z3.FreshInt(var.name)
            
            # add inv into pc of inv_state
            inv_state.add_pc(z3.simplify(self.visit(node.inv, *args, state=inv_state)))
            # fork the state based on the condition and process both conditions accordingly
            cond = self.visit(node.cond, *args, state=inv_state)
            inv_states = inv_state.fork()

            #cond is satisfied, enter the loop
            if inv_states[0].addcond_isSolvable(cond):
                final_state = self.visit(node.body, state=inv_states[0])
                for st in final_state:
                    if st.addcond_isSolvable(z3.simplify(self.visit(node.inv, *args, state=st))):
                        print("inv fails invariance")
            if inv_states[1].addcond_isSolvable(z3.Not(cond)):
                return[inv_states[1]]
            else:
                return[]

        done = []
        while_states = [kwargs['state']]

        executed_time = 1

        while(len(while_states) != 0 and executed_time <= 10):
            executed_time += 1
            updated_while_states = []
            for state in while_states:
                cond = self.visit(node.cond, state=state) 
                cond_fork = state.fork()

                # if after adding condition, state is still solvable, visit node.body,
                # and extend returned state-list
                if cond_fork[0].addcond_isSolvable(cond):
                    updated_while_states.extend(self.visit(node.body, state=cond_fork[0]))
                # if after adding not condition, state is still solvable, append the termination state into returning states
                if cond_fork[1].addcond_isSolvable(z3.Not(cond)):
                    done.append(cond_fork[1])
            while_states = updated_while_states
        return done
Example #20
0
def add_dependency_constrains(solver, pkg_dict, order_dict, int_dict):
    # add constrains from package dependencies
    for pkg in pkg_dict:
        ver_dict = pkg_dict[pkg]
        ands = list()
        for ver in ver_dict:
            ind = order_dict[pkg][ver]
            deps = sorted(ver_dict[ver])
            ors = list()
            curr_pkg = None
            or_expr = None
            for dep in deps:
                # convert one pkg dependencies to z3 expr
                # A==1 requires B==2,B==3 -> (B==2 OR B==3)
                dep_pkg, dep_ver = dep.split("#")
                dep_ind = order_dict[dep_pkg][dep_ver]
                if dep_pkg != curr_pkg:
                    if or_expr is not None:
                        ors.append(or_expr)
                    curr_pkg = dep_pkg
                    or_expr = Or()
                expr = Or(int_dict[dep_pkg] == dep_ind)
                or_expr = Or(or_expr, expr)
                or_expr = simplify(or_expr)
            if or_expr is not None:
                ors.append(or_expr)

            # merge all pkg dependencies OR expr for the pkg version
            # A==1 requires B==2,B==3,C==1 -> A==1 AND (B==2 OR B==3) AND C==1
            and_expr = And(int_dict[pkg] == ind)
            for expr in ors:
                and_expr = And(and_expr, expr)
                and_expr = simplify(and_expr)
            ands.append(and_expr)

        # merge all versions dependencies AND expr
        # A==1 requires B==2,B==3,C==1; A==3 requires B==3, C==3
        # -> (A==1 AND (B==2 OR B==3) AND C==1) Or (A==3 AND B==3 AND C==3)
        constrain = Or()
        for expr in ands:
            constrain = Or(constrain, expr)
            constrain = simplify(constrain)
        # situation that the package is unnecessary
        unnecessary_ind = len(order_dict[pkg].keys())
        constrain = Or(constrain, int_dict[pkg] == unnecessary_ind)
        constrain = simplify(constrain)

        # print(constrain)
        solver.add(constrain)
    return solver
Example #21
0
    def get_pred(self):
        if self.is_ninf():
            return copy.deepcopy(self)
        if self.is_pzero():
            return Float('-0',ne=self.ne,ns=self.ns).get_pred()
        bv_str = self.get_bv_str()
        #print(bv_str)
        sign = bv_str[0]
        if sign == '0':
            succ = int(bv_str[1:],2) - 1
            return Float(val=z3.simplify(z3.fpBVToFP(z3.Int2BV(z3.IntVal(succ),num_bits = self.ns + self.ne),z3.FPSort(self.ne,self.ns))),ne=self.ne, ns=self.ns)

        else:
            succ = int(bv_str[1:],2) + 1
            return -Float(val=z3.simplify(z3.fpBVToFP(z3.Int2BV(z3.IntVal(succ),num_bits = self.ns + self.ne),z3.FPSort(self.ne,self.ns))),ne=self.ne, ns=self.ns)
Example #22
0
    def exp_(self, global_state):
        state = global_state.mstate
        # we only implement 2 ** x
        base, exponent = util.pop_bitvec(state), util.pop_bitvec(state)

        if (type(base) != BitVecNumRef) or (type(exponent) != BitVecNumRef):
            state.stack.append(BitVec("(" + str(simplify(base)) + ")^(" + str(simplify(exponent)) + ")", 256))
        elif base.as_long() == 2:
            if exponent.as_long() == 0:
                state.stack.append(BitVecVal(1, 256))
            else:
                state.stack.append(base << (exponent - 1))
        else:
            state.stack.append(base)
        return [global_state]
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))
Example #24
0
    def byte_(self, global_state):
        mstate = global_state.mstate
        op0, op1 = mstate.stack.pop(), mstate.stack.pop()

        try:
            index = util.get_concrete_int(op0)
            offset = (31 - index) * 8
            result = Concat(BitVecVal(0, 248), Extract(offset + 7, offset,
                                                       op1))
        except AttributeError:
            logging.debug("BYTE: Unsupported symbolic byte offset")
            result = BitVec(str(simplify(op1)) + "_" + str(simplify(op0)), 256)

        mstate.stack.append(simplify(result))
        return [global_state]
Example #25
0
def get_arguments_from_stack(n_args, vm, exe, max_args=12):
    args = []

    n_stack_val = len(vm.x86_stack)
        
    if n_stack_val > max_args:
        n_stack_val = max_args
        
    x = max([n_args, n_stack_val])
    for i in xrange(x):
        if vm.x86_stack:
            if i < n_args:
                val = vm.x86_stack.pop()
            else:
                val = vm.x86_stack[n_args - i - 1]
            arg = z3.simplify(val)
            
            if hasattr(arg, 'as_long'):
                ptr_ = check_pointer(arg.as_long(), exe)
                if ptr_:
                    arg = ptr_
                else:
                    arg = '0x%x' % arg.as_long()
            else:
                arg = str(arg)
                name = process_arg_str(arg)#
                if name: arg = name
        else:
            if i >= n_args:break
            arg = '*'
                
        args.append(arg)
    return args
Example #26
0
def get_z3_value(item):

    if (type(item) == int):
        return item

    elif (type(item) == mythril.laser.smt.bitvec.BitVec and not item.symbolic):
        return item.value
    elif (type(item) == z3.BitVecNumRef):
        return item.as_long()

    try:
        return z3.simplify(item).as_long()
    except AttributeError:
        return str(z3.simplify(item))
    except z3.Z3Exception:
        return str(item)
Example #27
0
def symbolic_run(lines, data):
    print('Running symbolically')
    data = list(data)
    sym_data = list(x_vars)
    sym_data[ip] = data[ip]

    conds = []

    states = []

    for i in range(12):
        pc = data[ip]

        if pc >= len(lines): break

        print(lines[pc], sym_data)
        simulate(lines[pc], data)
        try:
            simulate(lines[pc], sym_data)
        except SymbolicExecutionImpossible:
            break

        states.append((tuple(sym_data), tuple(data)))

        if type(sym_data[ip]) != int:
            conds.append( z3.simplify(sym_data[ip] == data[ip]) )
            #print('cond', conds[-1])
            sym_data[ip] = data[ip]

        r = find_shifted(conds, states)
        if r:
            patterns[pc].add(r)
            break

        if data[ip] >= len(lines): break
Example #28
0
def get_vars(f, rs=set()):
    """
    shameless copy of z3util.get_vars,
    but returning select-operations as well.
    E.g.
    >>> x = z3.Array('x', z3.IntSort(), z3.IntSort())
    >>> get_vars(x[5])
    [x[5]]
    whereas
    >>> x = z3.Array('x', z3.IntSort(), z3.IntSort())
    >>> z3util.get_vars(x[5])
    [x]
    """
    if not rs:
        f = z3.simplify(f)

    if f.decl().kind() == z3.Z3_OP_SELECT:
        arr, idx = f.children()
        if z3.is_const(arr):
            if z3.z3util.is_expr_val(idx):
                return rs | {f}
            else:
                return rs | {f, idx}
    if z3.is_const(f):
        if z3.z3util.is_expr_val(f):
            return rs
        else:  # variable
            return rs | {f}

    else:
        for f_ in f.children():
            rs = get_vars(f_, rs)

        return set(rs)
Example #29
0
def get_z3_value_hex(item):

    if (type(item) == int):
        return hex(item)

    elif (type(item) == mythril.laser.smt.bitvec.BitVec and not item.symbolic):
        return hex(item.value)
    elif (type(item) == z3.BitVecNumRef):
        return hex(item.as_long())

    try:
        return hex(z3.simplify(item).as_long())
    except AttributeError:
        return str(z3.simplify(item)).replace("\n", "\n    ")
    except z3.Z3Exception:
        return str(item).replace("\n", "\n    ")
Example #30
0
    def visit_MLIL_SET_VAR_SSA(self, expr):
        dest = create_BitVec(expr.dest, expr.size)

        src = self.visit(expr.src)

        # If this value can never be larger than a byte,
        # then it must be one of the bytes in our swap.
        # Add it to a list to check later.
        if src is not None and not isinstance(src, (int, int)):
            value_range = identify_byte(expr.src, self.function)
            if value_range is not None:
                self.solver.add(
                    Or(src == 0,
                       And(src <= value_range.end, src >= value_range.step)))

                self.byte_vars.add(*expr.src.vars_read)

                if self.byte_values.get(
                    (value_range.end, value_range.step)) is None:
                    self.byte_values[(
                        value_range.end, value_range.step)] = simplify(
                            Extract(
                                int(math.floor(math.log(value_range.end, 2))),
                                int(math.floor(math.log(value_range.step, 2))),
                                src))

        self.visited.add(expr.dest)

        if expr.instr_index in self.to_visit:
            self.to_visit.remove(expr.instr_index)

        if src is not None:
            self.solver.add(dest == src)
Example #31
0
def convertToDimacs(goal, file):
        #f_n = open(Options.DIMACS_FILE, 'w')
        d = DimacsConverter()
        t = Tactic("tseitin-cnf")
        cnf = t(goal)
        #print cnf
        clauses = []
        #print(cnf)
        for i in cnf:
            for j in i:
                variables = []
                #print (j)
                #print j.__class__
                if len(j.children()) == 0:
                    variables.append(str(d.getVarIndex(str(j))))
                for k in j.children():
                    #print k
                    if is_not(k):
                        neg="-"
                        newk = (simplify(Not(k)))
                    else:
                        neg=""
                        newk = k
                    variables.append(neg + str(d.getVarIndex(str(newk))))
                clauses.append(variables)
        
        inv_map = {v:k for k, v in d.vars.items()}
        #print(inv_map)
        f = open(file, 'r')
        for line in f:
            [var, val] = split(line)
            print("\"" + str(inv_map[int(var)])+"\",")
Example #32
0
def getDimacsMap(goal): 
    d = DimacsConverter()
    t = Tactic("tseitin-cnf")
    cnf = t(goal)
    #print cnf
    clauses = []
    #print(cnf)
    for i in cnf:
        for j in i:
            variables = []
            #print (j)
            #print j.__class__
            if len(j.children()) == 0:
                variables.append(str(d.getVarIndex(str(j))))
            for k in j.children():
                #print k
                if is_not(k):
                    neg="-"
                    newk = (simplify(Not(k)))
                else:
                    neg=""
                    newk = k
                variables.append(neg + str(d.getVarIndex(str(newk))))
            clauses.append(variables)
    
    inv_map = {v:k for k, v in d.vars.items()}
    return inv_map
Example #33
0
    def simplify(self, expr):
        if expr._simplified:
            return expr

        if self._enable_simplification_cache:
            try:
                k = self._simplification_cache_key[expr._cache_key]
                #print "HIT WEAK KEY CACHE"
                return k
            except KeyError:
                pass
            try:
                k = self._simplification_cache_val[expr._cache_key]
                #print "HIT WEAK VALUE CACHE"
                return k
            except KeyError:
                pass

            #print "MISS CACHE"

        l.debug("SIMPLIFYING EXPRESSION")

        #print "SIMPLIFYING"

        expr_raw = self.convert(expr)

        #l.debug("... before: %s (%s)", expr_raw, expr_raw.__class__.__name__)

        if isinstance(expr_raw, z3.BoolRef):
            tactics = z3.Then(z3.Tactic("simplify"), z3.Tactic("propagate-ineqs"), z3.Tactic("propagate-values"), z3.Tactic("unit-subsume-simplify"))
            s = tactics(expr_raw).as_expr()
            n = s.decl().name()

            if n == 'true':
                s = True
            elif n == 'false':
                s = False
        elif isinstance(expr_raw, z3.BitVecRef):
            s = z3.simplify(expr_raw)
        else:
            s = expr_raw

        for b in _eager_backends:
            try:
                o = self.wrap(b.convert(s))
                break
            except BackendError:
                continue
        else:
            o = self._abstract(s)

        #print "SIMPLIFIED"
        #l.debug("... after: %s (%s)", s, s.__class__.__name__)

        o._simplified = Base.FULL_SIMPLIFY

        if self._enable_simplification_cache:
            self._simplification_cache_val[expr._cache_key] = o
            self._simplification_cache_key[expr._cache_key] = o
        return o
    def find_if_else_for_node(self, header: MediumLevelILBasicBlock,
                              nodes: list):
        nodes_to_check = list(nodes)

        nodes_to_remove = []

        while nodes_to_check:
            ni = nodes_to_check.pop()

            if not isinstance(ni, MediumLevelILAstCondNode):
                continue

            for nj in nodes_to_check:
                if not isinstance(nj, MediumLevelILAstCondNode):
                    continue

                if ni.start == nj.start:
                    continue

                cni = ni.condition
                cnj = nj.condition

                if is_true(simplify(cni == Not(cnj))):
                    if cni.decl().name() == 'not':
                        self._make_if_else(nj, ni)
                        nodes_to_check.remove(nj)
                        nodes_to_remove.append(ni)
                    else:
                        self._make_if_else(ni, nj)
                        nodes_to_check.remove(nj)
                        nodes_to_remove.append(nj)
                    break

        return nodes_to_remove
Example #35
0
def bitblast (e):
  ctx = e.ctx
  goal = z3.Goal (ctx=ctx)
  goal.add (z3.simplify (e))
  tactic = z3.Tactic ('bit-blast', ctx=ctx)
  res = tactic.apply (goal, blast_full=True)
  assert (len (res) == 1)
  return res [0].as_expr ()
Example #36
0
def z3_flatten_exp (z3exp) :
  return z3.simplify (z3exp, flat=True,
                      # don't care about other options,
                      # which are true by default...
                      algebraic_number_evaluator=False,
                      bit2bool=False,
                      elim_sign_ext=False,
                      hi_div0=False,
                      mul_to_power=False,
                      push_to_real=False)
Example #37
0
def PEPPolicy(PEP, model):
    disjunctions = []
    for or_id in range(NUM_ORS):
        conjunctions = []
        for enum_id in range(NUM_ENUMS):
            enumVar = TEMPLATE_ENUM_VARS[PEP][or_id][enum_id]
            if model[enumVar] is not None:
                synthVal = model[enumVar].as_long()
            else:
                synthVal = -1
            if synthVal >= 0 and synthVal < len(ENUM_INDEX.keys()):                
                if not isinstance(ENUM_INDEX[synthVal], list):
                    boolVar = ENUM_INDEX[synthVal]
                    conjunctions.append(boolVar)
                else:
                    [enumVar, val] = ENUM_INDEX[synthVal]
                    conjunctions.append(enumVar == val)
            elif synthVal >= len(ENUM_INDEX.keys()) and synthVal < 2 * len(ENUM_INDEX.keys()):                
                if not isinstance(ENUM_INDEX[synthVal - len(ENUM_INDEX.keys())], list):
                    boolVar = ENUM_INDEX[synthVal - len(ENUM_INDEX.keys())]
                    conjunctions.append(Not(boolVar))
                else:
                    [enumVar, val] = ENUM_INDEX[synthVal - len(ENUM_INDEX.keys())]
                    conjunctions.append(enumVar != val)
            elif synthVal == 2 * len(ENUM_INDEX.keys()):
                conjunctions.append(True)
            else:
                conjunctions.append(False)
        for num_id in range(NUM_NUMERIC):
            minVar = TEMPLATE_NUMERIC_VARS[PEP][or_id][num_id]['min']
            maxVar = TEMPLATE_NUMERIC_VARS[PEP][or_id][num_id]['max']
            if model[minVar] is not None and model[maxVar] is not None:
                crosscheck = Solver()
                crosscheck.add(model[minVar] <= model[maxVar])
                if crosscheck.check() == sat:
                    conjunctions.append(NUM_VAR >= model[minVar].as_long())
                    conjunctions.append(NUM_VAR <= model[maxVar].as_long())
            elif model[minVar] is not None:
                conjunctions.append(NUM_VAR >= model[minVar].as_long())
            elif model[maxVar] is not None:
                conjunctions.append(NUM_VAR <= model[maxVar].as_long())
        disjunctions.append(simplify(And(conjunctions)))
    return simplify(Or(disjunctions))
Example #38
0
    def simplify(self, expr):
        if expr._simplified:
            return expr

        if self._enable_simplification_cache:
            try:
                k = self._simplification_cache_key[expr._cache_key]
                #print "HIT WEAK KEY CACHE"
                return k
            except KeyError:
                pass
            try:
                k = self._simplification_cache_val[expr._cache_key]
                #print "HIT WEAK VALUE CACHE"
                return k
            except KeyError:
                pass

            #print "MISS CACHE"

        l.debug("SIMPLIFYING EXPRESSION")

        #print "SIMPLIFYING"

        expr_raw = self.convert(expr)

        #l.debug("... before: %s (%s)", expr_raw, expr_raw.__class__.__name__)

        #s = expr_raw
        if isinstance(expr_raw, z3.BoolRef):
            tactics = z3.Then(
                z3.Tactic("simplify", ctx=self._context),
                z3.Tactic("propagate-ineqs", ctx=self._context),
                z3.Tactic("propagate-values", ctx=self._context),
                z3.Tactic("unit-subsume-simplify", ctx=self._context),
                ctx=self._context
            )
            s = tactics(expr_raw).as_expr()
            #n = s.decl().name()
            #if n == 'true':
            #   s = True
            #elif n == 'false':
            #   s = False
        elif isinstance(expr_raw, z3.BitVecRef):
            s = z3.simplify(expr_raw)
        else:
            s = expr_raw

        o = self._abstract(s)
        o._simplified = Base.FULL_SIMPLIFY

        if self._enable_simplification_cache:
            self._simplification_cache_val[expr._cache_key] = o
            self._simplification_cache_key[expr._cache_key] = o
        return o
Example #39
0
 def interpret(self, i, j):
     """ Convert logical indices i and j into a physical index. """
     Bx = i / self.lsize0()
     By = j / self.lsize1()
     p = self.fragment(Bx, By)
     if not self.terminal():
         x = i % self.lsize0()
         y = j % self.lsize1()
         p *= self.elem_size()
         p += self.rest.interpret(x, y)
     return z3.simplify(p)
Example #40
0
def solve_for(inps):
    r1, r2, r3, r4, v11 = [BVV(x, 64) for x in map(int, inps.split(', '))]
    print r1, r2, r3, r4, v11

    for choice1, choice2, choice3 in all_choices():
        v6 = choose_op(r1, r2, choice1)
        v6_1 = choose_op(v6, r3, choice2)
        v6_2 = choose_op(v6_1, r4, choice3)

        if simplify(weird_op(v6_2)) == v11:
            return choice1, choice2, choice3
Example #41
0
	def _pattern(self, pattern, L):
		# we can exit early if we have a variable
		if self._is_var(pattern):
			return True
		constraints = [True]
		f, *args = breakout(pattern)
		# now we'll recurse appropriately
		for i, arg in enumerate(args):
			constraints.append( self._connect(f, i, arg, L) )
			constraints.append( self._pattern(arg, L))
		return simplify(And(constraints))
Example #42
0
File: SMT.py Project: Debug-Orz/SEA
  def getValue(self, op):
    assert(self.m <> None)
    
    if (op |iss| RegOp):
      var = map(lambda b: z3.BitVec(str(b),8), op.getLocations())
      var = map(lambda b: self.m[b], var)
      if (len(var) > 1):
        return z3.simplify(z3.Concat(var)).as_signed_long()
      else:
        return z3.simplify(var[0]).as_signed_long()
    elif (op.isMem()):
      array = z3.Array(op.name, z3.BitVecSort(16), z3.BitVecSort(8))
      f = self.m[array]
      
      #print self.m
      
      es = f.as_list()[:-1]

      var = []
      
      for loc in op.getLocations():
        byte = None
        for entry in es:
          #print entry
          if loc.getIndex() == entry[0].as_signed_long():
            byte = entry[1]#.as_signed_long()
            break
        
        if (byte == None):
          byte = f.else_value()
          
        var.append(byte)
        
      var.reverse()
      
      if (len(var) > 1):  
        return z3.simplify(z3.Concat(var)).as_signed_long()
      else:
        return z3.simplify(var[0]).as_signed_long()
    else:
      assert(0)
Example #43
0
    def prove(self, hypotheses, conclusion=None, report=None):
        report = self.reportFun(report)

        if (conclusion is None):
            conclusion = hypotheses
            hypotheses = True

        x_hyps, x_concl = self.analyse_expt(z3.And(hypotheses,z3.Not(conclusion)), conclusion, report)
        f_hyps, f_concl = self.fun_to_var([x_hyps, x_concl], report)[:]
        if(f_hyps is None):
            hyps = f_hyps
        else:
            hyps = z3.simplify(f_hyps)
        if(f_concl is None):
            concl = f_concl
        else:
            concl = z3.simplify(f_concl)

        report('to_smt_w_expt.prove:')
        report('  hypotheses = ', hyps)
        report('  conclusion = ', concl)
        return super(to_smt_w_expt, self).prove(hyps, concl)
Example #44
0
    def simplify(self, expr):  #pylint:disable=arguments-differ
        if expr._simplified:
            return expr

        if self._enable_simplification_cache:
            try:
                k = self._simplification_cache_key[expr._cache_key]
                #print "HIT WEAK KEY CACHE"
                return k
            except KeyError:
                pass
            try:
                k = self._simplification_cache_val[expr._cache_key]
                #print "HIT WEAK VALUE CACHE"
                return k
            except KeyError:
                pass

            #print "MISS CACHE"

        l.debug("SIMPLIFYING EXPRESSION")

        #print "SIMPLIFYING"

        expr_raw = self.convert(expr)

        #l.debug("... before: %s (%s)", expr_raw, expr_raw.__class__.__name__)

        #s = expr_raw
        if isinstance(expr_raw, z3.BoolRef):
            boolref_tactics = self._boolref_tactics
            s = boolref_tactics(expr_raw).as_expr()
            #n = s.decl().name()
            #if n == 'true':
            #    s = True
            #elif n == 'false':
            #    s = False
        elif isinstance(expr_raw, z3.BitVecRef):
            s = z3.simplify(expr_raw)
        else:
            s = expr_raw

        o = self._abstract(s)
        o._simplified = Base.FULL_SIMPLIFY

        if self._enable_simplification_cache:
            self._simplification_cache_val[expr._cache_key] = o
            self._simplification_cache_key[expr._cache_key] = o
        return o
Example #45
0
    def constraints_for_call(self, call):
        situations = []
        rule = self.rule_for_call(call)
        for priority, z3_meaning in rule.meaning_of(self.history, call):
            situational_exprs = [z3_meaning]
            for unmade_call, unmade_rule in self._call_to_rule.iteritems():
                for unmade_priority, unmade_z3_meaning in unmade_rule.meaning_of(self.history, unmade_call):
                    if self.system.priority_ordering.lt(priority, unmade_priority):
                        if self.explain and self.expected_call == call:
                            print "Adding negation %s (%s) to %s:" % (unmade_rule.name, unmade_call.name, rule.name)
                            print " %s" % z3.simplify(z3.Not(unmade_z3_meaning))
                        situational_exprs.append(z3.Not(unmade_z3_meaning))
            situations.append(z3.And(situational_exprs))

        return z3.Or(situations)
Example #46
0
	def _constrain_eq_vars(self, E, L):
		constraints = []
		for l, r in combinations(L, 2):
			if l.type == "return" and r.type == "return":
				lcomp, rcomp = self.components[l.component], self.components[r.component]
				if lcomp.sexpr != rcomp.sexpr:
					constraints.append( E[(l, r)] == False )
				else:
					local = [True]
					for i in range(len(lcomp.parameters)):
						li, ri = get_ith_input(l.component, i, L), get_ith_input(r.component, i, L)
						local.append( E[(li, ri)] )
					constraints.append( E[(l, r)] == And(local) )
			elif l.type == "parameter" and r.type == "parameter": # type is parameter
				local = [(l.value == r.value)]
				for f, g in permutations([get_output(c, L) for c, _ in self.components.items()], 2):
					local.append( And([l.value == f.value, r.value == g.value, E[(f, g)]]) )
				constraints.append( E[(l, r)] == Or(local) )
		return simplify(And(constraints))
Example #47
0
File: test.py Project: nojero/pod
def test19 () :
    
    x = z3.Int ('x')
    y = z3.Int ('y')
    z = z3.Int ('z')
    s = z3.Solver ()

    cons = z3.Or ([])
    print 'cons', cons
    print 'simplify', z3.simplify (cons)
    s.add (cons)
    s.add (z3.Or (x == y, x == z))

    print 'constraints to solve:', s

    c = s.check ()
    print 'result:', c
    if c == z3.sat :
        m = s.model ()
        print 'model:', m
Example #48
0
 def _is_true(self, e, extra_constraints=(), result=None, solver=None):
     return z3.simplify(e).eq(z3.BoolVal(True, ctx=self._context))
Example #49
0
File: SMT.py Project: mayfly74/SEA
 def add(self, cs):
   for c in cs:
     c = z3.simplify(c)
     #print c
     self.solver.add(c)
Example #50
0
def test1():   
    print "=== Loading Core ==="    
    
    solver = Solver()
    solver.push()
    solver.add(language.axioms)
 
    print "=== Starting tests ==="
    
    
    print ">> Let p q r s t u v be distinct points"
    p, q, r, s, t, u, v = Consts('p q r s t u v', language.PointSort)
    solver.add(simplify(Distinct(p,q,r,s,t,u,v), blast_distinct=True))
    
    
    print ">> Let L M N O be distinct lines"
    K, L, M, N, O = Consts('K L M N O', language.LineSort)
    solver.add(simplify(Distinct(K,L,M,N,O), blast_distinct=True))
    
    
    ## Diagram description 
    assumptions = []
     
    assumptions.append(language.OnLine(p,L))
    assumptions.append(language.OnLine(q,L))
    assumptions.append(language.OnLine(p,N))
    assumptions.append(language.OnLine(s,N))
    assumptions.append(language.OnLine(t,N))
    assumptions.append(language.OnLine(p,M))
    assumptions.append(language.OnLine(r,M))
    assumptions.append(language.OnLine(q,O))
    assumptions.append(language.OnLine(s,O))
    assumptions.append(language.OnLine(r,O))
    assumptions.append(language.OnLine(q,K))
    assumptions.append(language.OnLine(t,K))
    assumptions.append(Not(language.OnLine(r,L)))
    assumptions.append(language.Between(p,s,t))
    assumptions.append(language.Between(q,s,r))
    assumptions.append(language.Between(s,u,t))
    assumptions.append(Not(p == q))
    assumptions.append(language.Between(p,q,v))
  
    
    
    print ">> Assume " + str(assumptions)
    solver.add(assumptions)
    print "      << z3: " + str(solver.check())
     
     
    ## Satisfied 
    solver.push()
    solver.add(True)
    print ">> Hence True"    
    print "      << z3: " + str(solver.check())
    solver.pop()
    
    ## Satisfied  
    solver.push()
    solver.add(Not(language.SameSide(s,t,O)))
    print ">> Hence s and t are on opposite sides of O"
    print "      << z3: " + str(solver.check())
    solver.pop()
    
    ## Satisfied  
    solver.push()
    solver.add(language.SameSide(u,t,M))
    print ">> Hence u and t are on same side of M"
    print "      << z3: " + str(solver.check())
    solver.pop()
    
    ## unsatisfied  
    solver.push()
    solver.add(language.SameSide(p,t,O))
    print ">> Hence p and t are on same side of O"
    print "      << z3: " + str(solver.check())
    solver.pop()
    
    ## unsatisfied  
    solver.push()
    solver.add(language.SameSide(s,t,O))
    print ">> Hence s and t are on same side of O"
    print "      << z3: " + str(solver.check())
    solver.pop()
    
    ## unsatisfied  
    solver.push()
    solver.add(Not(language.SameSide(s,t,M)))
    print ">> Hence s and t are on opposite sides of M"
    print "      << z3: " + str(solver.check())
    solver.pop()
    
    ## unsatisfied  
    solver.push()
    solver.add(Not(language.SameSide(u,t,M)))
    print ">> Hence u and t are on opposite sides of M"
    print "      << z3: " + str(solver.check())
    solver.pop()
    
    ## unsatisfied  
    solver.push()
    solver.add(language.Between(s,p,t))
    print ">> Hence p is between s and t"
    print "      << z3: " + str(solver.check())
    solver.pop()
    
    ## unsatisfied  
    solver.push()
    solver.add(M == N)
    print ">> Hence p is between s and t"
    print "      << z3: " + str(solver.check())
    solver.pop()
    
    ## unsatisfied  
    solver.push()
    solver.add(language.Between(q,s,u))
    print ">> Hence s is between q and u"
    print "      << z3: " + str(solver.check())
    solver.pop()
    
    ## unsatisfied  
    solver.push()
    solver.add(Not( language.Segment(s,u) < language.Segment(s,t)))
    print ">> Hence seg su is less than seg st"
    print "      << z3: " + str(solver.check())
    solver.pop()
    
    ## unsatisfied  
    solver.push()
    solver.add(L==K)
    print ">> Hence L = K"
    print "      << z3: " + str(solver.check())
    solver.pop()
Example #51
0
 def _is_true(self, e, extra_constraints=(), solver=None, model_callback=None):
     return z3.simplify(e).eq(z3.BoolVal(True, ctx=self._context))
 def _simplify(self):
     if self._formula in [True, False]:
         return
     self._formula = z3.simplify(self._formula)
Example #53
0
    def handle(self, cur_addr):
        symb_pc = self.eval_expr(self.ir_arch.IRDst)
        possibilities = possible_values(symb_pc)
        if len(possibilities) == 1:
            assert next(iter(possibilities)).value == cur_addr
        else:
            cur_path_constraint = set() # path_constraint for the concrete path
            for possibility in possibilities:
                path_constraint = set() # Set of ExprAff for the possible path

                # Get constraint associated to the possible path
                memory_to_add = ModularIntervals(symb_pc.size)
                for cons in possibility.constraints:
                    eaff = cons.to_constraint()
                    # eaff.get_r(mem_read=True) is not enough
                    # ExprAff consider a Memory access in dst as a write
                    mem = eaff.dst.get_r(mem_read=True)
                    mem.update(eaff.src.get_r(mem_read=True))
                    for expr in mem:
                        if expr.is_mem():
                            addr_range = expr_range(expr.arg)
                            # At upper bounds, add the size of the memory access
                            # if addr (- [a, b], then @size[addr] reachables
                            # values are in @8[a, b + size[
                            for start, stop in addr_range:
                                stop += (expr.size / 8) - 1
                                full_range = ModularIntervals(symb_pc.size,
                                                              [(start, stop)])
                                memory_to_add.update(full_range)
                    path_constraint.add(eaff)

                if memory_to_add.length > self.MAX_MEMORY_INJECT:
                    # TODO re-croncretize the constraint or z3-try
                    raise RuntimeError("Not implemented: too long memory area")

                # Inject memory
                for start, stop in memory_to_add:
                    for address in xrange(start, stop + 1):
                        expr_mem = ExprMem(ExprInt(address,
                                                   self.ir_arch.pc.size),
                                           8)
                        value = self.eval_expr(expr_mem)
                        if not value.is_int():
                            raise TypeError("Rely on a symbolic memory case, " \
                                            "address 0x%x" % address)
                        path_constraint.add(ExprAff(expr_mem, value))

                if possibility.value == cur_addr:
                    # Add path constraint
                    cur_path_constraint = path_constraint

                elif self.produce_solution:
                    # Looking for a new solution
                    self.cur_solver.push()
                    for cons in path_constraint:
                        trans = self.z3_trans.from_expr(cons)
                        trans = z3.simplify(trans)
                        self.cur_solver.add(trans)

                    result = self.cur_solver.check()
                    if result == z3.sat:
                        model = self.cur_solver.model()
                        self.handle_solution(model, possibility.value)
                    self.cur_solver.pop()

            # Update current solver
            for cons in cur_path_constraint:
                self.cur_solver.add(self.z3_trans.from_expr(cons))
Example #54
0
 def _is_true(self, e):
     return z3.simplify(e).eq(z3.BoolVal(True))
Example #55
0
 def _is_false(self, e):
     return z3.simplify(e).eq(z3.BoolVal(False))
 def sat_expr(self):
     expr = self._sat_expr(self.x, self.regex, 0, self.length)
     return z3.simplify(expr)
Example #57
0
    def smt_solution(self, timeout, neg_points=None):
        neg_points = neg_points or []
        solver = z3.Solver()
        solver.set("timeout", timeout)

        b = self.offset
        z3_b = z3.Int("b")

        if b > 0:
            solver.add(z3_b >= 0)
            solver.add(z3_b <= b)
        elif b < 0:
            solver.add(z3_b <= 0)
            solver.add(z3_b >= b)
        else:
            solver.add(z3_b == 0)

        pos_x = True
        simple = sum(abs(x) for x in self.normal) < 1
        non_trivial = False
        if not simple:
            some_consume = False
            some_produce = False

        diff_sol = z3_b != b
        h1 = b
        h2 = z3_b
        variables = []

        for t_id, val in enumerate(self.normal):
            if not val:
                continue
            z3_val = z3.Int("a" + str(t_id))
            x = z3.Int("x" + str(t_id))
            variables.append(x)
            pos_x = z3.And(pos_x, x >= 0)

            if val > 0:
                solver.add(0 <= z3_val)
                solver.add(z3_val <= val)
            elif val < 0:
                solver.add(z3_val <= 0)
                solver.add(val <= z3_val)
            if not simple:
                some_consume = z3.Or(some_consume, z3_val < 0)
                some_produce = z3.Or(some_produce, z3_val > 0)

            non_trivial = z3.Or(non_trivial, z3_val != 0)
            diff_sol = z3.Or(diff_sol, z3_val != val)
            h1 = h1 + val * x
            h2 = h2 + z3_val * x

        if not simple:
            solver.add(z3.simplify(some_consume))
            solver.add(z3.simplify(some_produce))
        solver.add(z3.simplify(non_trivial))
        solver.add(z3.simplify(diff_sol))
        solver.add(z3.simplify(z3.ForAll(variables, z3.Implies(z3.And(pos_x, h1 <= 0), h2 <= 0))))

        ## non negative point should be a solution
        for np in list(neg_points)[:min(100,len(neg_points))]:
            smt_np = False
            ineq_np = self.offset
            for t_id, val in enumerate(self.normal):
                z3_var = z3.Int("a" + str(t_id))
                ineq_np = ineq_np + z3_var * np[t_id]
            smt_np = z3.simplify(z3.Or(smt_np, ineq_np < 0))
            solver.add(smt_np)

        #import pdb;pdb.set_trace()
        sol = solver.check()
        if sol == z3.unsat or sol == z3.unknown:
            ret = False
            del(solver)
            del(sol)
        else:
            ret = solver.model()
        return ret
Example #58
0
 def simplify(self, expr, **kwargs):
     if(z3.is_expr(expr)): return z3.simplify(expr, **kwargs)
     else: # assume that expr has already been 'simplified' to a constant.
       return expr