示例#1
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
示例#2
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)

    #return z3.simplify(result)
    return result
示例#3
0
def make_bool(z3_var):
    if z3.is_int(z3_var):
        # Use > 0 to convert int to bool as per BooleanNodes.h
        # in the SKETCH code base.
        return z3_var > 0
    else:
        return z3_var
示例#4
0
def _is_literal(z3ast):
    if z3.is_int(z3ast):
        return z3.is_int_value(z3ast)
    if z3.is_bool(z3ast):
        return z3.is_true(z3ast) or z3.is_false(z3ast)
    if z3ast.sort_kind() == z3.Z3_UNINTERPRETED_SORT:
        return z3.is_const(z3ast) and '!' in str(z3ast)
    raise NotImplementedError('Don\'t know how to literal-check %s' % z3ast)
示例#5
0
    def _binop_dunder_operation(self,
                                op: str,
                                op_callback,
                                reflected=False,
                                other: nodes.Const = None):
        other_defaults = other.defaults if isinstance(other, Z3Proxy) else {}
        left = self.value
        right = utilities.make_z3_const(utilities.strip_constant_node(other))
        extras = []
        if op in ("&", ">>", "<<"):
            # cast left and right to BitVector for bit operation.
            left, right = z3.Int2BV(left, 64), z3.Int2BV(right, 64)
        elif op in ("/", "//"):
            # special handling divide, due to we have "//" operation in py2 protocol, and
            # it's incompatible with z3
            if op == "//":
                # convert result to floor.
                MANAGER.logger.warning(
                    "Z3",
                    "Floor division (//) is not supported and will cast to (/), for node: {}",
                    repr(self))
            extras.append(right != 0)
            op_callback = lambda x, y: x / y

        elif op == "%":
            # casting left and right to int before doing modulo
            if not z3.is_int(left):
                left = z3.ToInt(left)
            if not z3.is_int(right):
                right = z3.ToInt(right)
            extras.append(right != 0)
        try:
            if not reflected:
                result = op_callback(left, right)
            else:
                result = op_callback(right, left)
            res = inference.InferenceResult(Z3Proxy.init_expr(
                result, {
                    **self.defaults,
                    **other_defaults
                }),
                                            status=True)
            res.z3_assumptions |= set(extras)
            return res
        except (z3.Z3Exception, TypeError):
            return inference.InferenceResult.load_result(nodes.Uninferable())
示例#6
0
def _is_literal(z3ast):
    if z3.is_int(z3ast):
        return z3.is_int_value(z3ast)
    if z3.is_bool(z3ast):
        return z3.is_true(z3ast) or z3.is_false(z3ast)
    if z3ast.sort_kind() == z3.Z3_UNINTERPRETED_SORT:
        return z3.is_const(z3ast) and '!' in str(z3ast)
    raise NotImplementedError('Don\'t know how to literal-check %s' % z3ast)
示例#7
0
 def get_z3_value(self, value):
     if z3.is_string(value):
         return value.as_string()[1:-1].replace('\\x00', '?')
     elif z3.is_int(value):
         return value.as_long()
     elif value is None:
         return ''  # TODO adhere to type
     else:
         raise ValueError('Got unknown Z3 type')
示例#8
0
def coerceTypesIfPossible(var, other_var):
    if z3.is_or(other_var) and not z3.is_bool(var):
        other_var = transformNonBooleanLazyEvaluations(other_var)
    if z3.is_or(var) and not z3.is_bool(other_var):
        var = transformNonBooleanLazyEvaluations(var)

    if z3.is_and(other_var) and not z3.is_bool(var):
        other_var = transformNonBooleanLazyEvaluations(other_var)
    if z3.is_and(var) and not z3.is_bool(other_var):
        var = transformNonBooleanLazyEvaluations(var)
    if var.decl().kind() == z3.Z3_OP_UNINTERPRETED:
        if z3.is_bool(other_var) and not z3.is_bool(var):
            infered_types[str(var)] = 'boolean'
            return z3.Bool(str(var)), other_var
        if z3.is_string(other_var) and not z3.is_string(var):
            if other_var.as_string() == '':
                # we probably dont want to coerce in this specific case as this is merely a non empty check
                if z3.is_bool(var):
                    return var, z3.BoolVal(False)
                if z3.is_int(var):
                    return var, z3.IntVal(0)
            else:
                infered_types[str(var)] = 'string'
                return z3.String(str(var)), other_var
        if z3.is_int(other_var) and not z3.is_int(var):
            infered_types[str(var)] = 'number'
            return z3.Int(str(var)), other_var
    elif var.decl().kind() == z3.Z3_OP_UNINTERPRETED:
        if z3.is_bool(var):
            infered_types[str(var)] = 'boolean'
        if z3.is_string(var):
            infered_types[str(var)] = 'string'
        if z3.is_int(var):
            infered_types[str(var)] = 'number'
    else:
        # this means that it is non-interpreted and we need to coerce other var to the type of var
        if z3.is_string(var) and z3.is_int_value(other_var):
            other_var = z3.StringVal(str(other_var))
        if z3.is_arith(var) and z3.is_string(other_var):
            other_var = z3.IntVal(int(other_var.as_string()))

    return var, other_var
示例#9
0
def string_slice(x, args):
    if len(args) == 2:
        start = args[0]
        end = args[1]
    else:
        start = args[0]
        end = lenOfZ3(x)

    if type(start) != int:
        start = createZ3ExpressionFromConstraint(start, {})
    if type(end) != int and not z3.is_int(end):
        end = createZ3ExpressionFromConstraint(end, {})

    if type(start) == int and start < 0:
        GLOBAL_CONSTRAINTS.append(z3.Length(x) > -start)
        start = end + start

    if (z3.is_int(start) or type(start) == int) and (z3.is_int(start) or type(start) == int):
        return z3.SubString(x, start, end)
    else:
        raise NotSupportedException('')
示例#10
0
 def __k_bool__(self):
     if z3.is_int(self.value) or z3.is_real(self.value) or z3.is_bv(
             self.value):
         yield inference.InferenceResult(Z3Proxy.init_expr(
             self.value != 0, self.defaults),
                                         status=True)
     elif z3.is_string(self.value):
         yield inference.InferenceResult(Z3Proxy.init_expr(
             self.value != z3.StringVal(""), self.defaults),
                                         status=True)
     else:
         yield inference.InferenceResult(self, status=True)
示例#11
0
def prepare(val):
    if z3.is_bv(val):
        #print(val)
        szdiff = SIZE - val.size()
        #print(szdiff, val.size())
        if szdiff > 0:
            return z3.ZeroExt(szdiff, val)
        else:
            return val
    elif z3.is_int(val):
        return z3.Int2BV(val, SIZE)
    else:
        return z3.BitVecVal(val, SIZE)
示例#12
0
def createZ3ForBool(var):
    if z3.is_int(var):
        return var != z3.IntVal(0)
    elif z3.is_string(var):
        return var != z3.StringVal('')
    elif z3.is_array(var):
        return z3.BoolVal(True)
    elif z3.is_bool(var):
        return var
    elif var is None:
        # this should be the case when we have a JSON value that is just inside a conditional etc
        return None
    elif z3.is_seq(var):
        # not string but still something ref-like we only found cases where this was string comparisons using <, >, etc.
        return var
    else:
        raise Exception('unhandled type in uninterpreted if')
示例#13
0
def AssignementsToString(val, model):
    if type(val) == z3.z3.ArrayRef:
        vals = []
        # Just print out the first 5 values of array, we do not really know how
        # many elements need to be in the array due to z3 handling arrays as functions
        for i in range(3):
            vals.append(AssignementsToString(model.eval(val[i]), model))
        return vals
    if z3.is_string(val):
        return val.as_string()
    if z3.is_int(val):
        return int(str(val))
    if z3.is_bool(val):
        if str(val) == 'False':
            return False
        return True

    raise Exception('solved assignement type is neither int nor string, what to do?')
示例#14
0
    def val_to_register_bv(self, reg: Dict, val):
        new_val = val

        if isinstance(val, int):
            new_val = z3.BitVecVal(val, reg["size"])

        elif z3.is_int(val):
            new_val = z3.Int2BV(val, reg["size"])

        elif z3.is_bv(val):
            if val.size() > reg["size"]:
                new_val = z3.Extract(reg["size"] - 1, 0, val)
            elif val.size() < reg["size"]:
                new_val = z3.ZeroExt(reg["size"] - val.size(), val)

        else:
            raise ESILArgumentException("%s %s" % (reg, val))

        return new_val
示例#15
0
    def check_value(self, val):
        assert val is not None, f"Setting a port's value to None is not allowed"

        # check that we only assign correct values to the ports
        if isinstance(self.domain, list):
            return val in self.domain
        elif self.domain is Types.INTEGER:
            return isinstance(val, int) or z3.is_int_value(val) or z3.is_int(val)
        elif self.domain is Types.REAL:  # z3 types
            return (isinstance(val, numbers.Number) and not isinstance(val, bool)) or z3.is_real(val)
        elif self.domain is Types.INT: # TODO: check also for these types
            return isinstance(val, int)
        elif self.domain is Types.FLOAT: # TODO: check also for these types
            return (isinstance(val, numbers.Number) and not isinstance(val, bool))
        elif self.domain is Types.STRING: # TODO: check also for these types
            return isinstance(val, str)
        elif self.domain is Types.BOOL: # TODO: check also for these types
            return isinstance(val, bool)
        else:
            return False
示例#16
0
    def val_to_register_bv(self, reg: Dict, val):
        new_val = val

        if type(val) == int:
            new_val = z3.BitVecVal(val, reg["size"])

        elif z3.is_int(val):
            new_val = z3.Int2BV(val, reg["size"])

        elif z3.is_bv(val):
            if val.size() > reg["size"]:
                new_val = z3.Extract(reg["size"] - 1, 0, val)
            elif val.size() < reg["size"]:
                new_val = z3.ZeroExt(reg["size"] - val.size(), val)
            else:
                new_reg = val

        else:
            raise ESILArgumentException

        return new_val
示例#17
0
def _gen(expr_z3, symbolTable, cache, result):

    ###Leaf: var
    if _is_variable(expr_z3):
        if DEBUG: print "-- Branch _is_variable with ", expr_z3
        symVar = expr_z3.decl().name()

        symVar = rename_var(symVar)

        if z3.is_int(expr_z3): symType = Sort.Int
        elif z3.is_fp(expr_z3):
            if expr_z3.sort() == z3.Float64():
                symType = Sort.Float64
            elif expr_z3.sort() == z3.Float32():
                symType = Sort.Float32
            else:
                raise NotImplementedError("Unexpected sort.", expr_z3.sort())
        elif z3.is_real(expr_z3):
            symType = Sort.Float
            warnings.warn(
                "****WARNING****: Real variable '%s' treated as floating point"
                % symVar)
        else:
            raise NotImplementedError("Unexpected type for %s" % symbolName)
        if (symVar in symbolTable.keys()):
            assert symType == symbolTable[symVar]
        else:
            symbolTable[symVar] = symType

        if expr_z3.sort() == z3.Float32():
            symVar = "TR32(%s)" % symVar  # do the same ting for verify !!!!!!!!

        return symVar

    ###Leaf: val
    if _is_value(expr_z3):
        if DEBUG: print "-- Branch _is_value"
        if z3.is_fp(expr_z3) or z3.is_real(expr_z3):
            if DEBUG: print "---- Sub-Branch FP or Real"
            if isinstance(expr_z3, z3.FPNumRef):
                if DEBUG: print "------- Sub-Sub-Branch _is_FPNumRef"
                try:
                    str_ret = str(sympy.Float(str(expr_z3), 17))

                except ValueError:
                    if expr_z3.isInf() and expr_z3.decl().kind(
                    ) == z3.Z3_OP_FPA_PLUS_INF:
                        str_ret = "INFINITY"
                    elif expr_z3.isInf() and expr_z3.decl().kind(
                    ) == z3.Z3_OP_FPA_MINUS_INF:
                        str_ret = "- INFINITY"
                    elif expr_z3.isNaN():
                        str_ret = "NAN"
                    else:
                        offset = 127 if expr_z3.sort() == z3.Float32(
                        ) else 1023
                        #Z3 new version needs the offset to be taken into consideration
                        expr_z3_exponent = expr_z3.exponent_as_long() - offset

                        str_ret = str(
                            sympy.Float((-1)**float(expr_z3.sign()) *
                                        float(str(expr_z3.significand())) *
                                        2**(expr_z3_exponent), 17))

            else:
                if DEBUG:
                    print "------- Sub-Sub-Branch other than FPNumRef, probably FPRef"
                str_ret = str(sympy.Float(str((expr_z3)), 17))
        elif z3.is_int(expr_z3):
            if DEBUG: print "---- Sub-Branch Integer"
            str_ret = str(sympy.Integer(str(expr_z3)))
        elif _is_true(expr_z3):

            str_ret = "0"
        elif _is_false(expr_z3):
            str_ret = "1"
        else:
            raise NotImplementedError(
                "[XSat: Coral Benchmarking] type not considered ")

        if expr_z3.sort() == z3.Float32():
            str_ret = str_ret + "f"

        return str_ret

    #if (expr_z3 in cache): return cache[expr_z3]

    #cache will be a set of defined IDs
    #if (var_name(expr_z3) in cache): return cache[expr_z3]

    if (expr_z3.get_id() in cache): return var_name(expr_z3)

    cache.add(expr_z3.get_id())
    #cache[expr_z3]=var_name(expr_z3)

    sort_z3 = expr_z3.decl().kind()

    expr_type = 'double'
    if expr_z3.sort() == z3.FPSort(8, 24): expr_type = 'float'

    ###
    if sort_z3 == z3.Z3_OP_FPA_LE:
        if DEBUG: print "-- Branch _is_le"
        lhs = _gen(expr_z3.arg(0), symbolTable, cache, result)
        rhs = _gen(expr_z3.arg(1), symbolTable, cache, result)
        toAppend= "double %s = DLE(%s,%s); " \
                  %( var_name(expr_z3), \
                     lhs,\
                     rhs,\
                  )
        result.append(toAppend)
        return var_name(expr_z3)

    #########!!!!!!!!!!!! need to do something
    if sort_z3 == z3.Z3_OP_FPA_TO_FP:
        if DEBUG: print "-- Branch _is_fpFP"
        assert expr_z3.num_args() == 2
        if not (_is_RNE(expr_z3.arg(0))):
            warnings.warn(
                "WARNING!!! I expect the first argument of fpFP is RNE, but it is ",
                expr_z3.arg(0))

        x = _gen(expr_z3.arg(1), symbolTable, cache, result)
        if expr_z3.sort() == z3.FPSort(8, 24):
            x = "TR32(%s)" % x
        #else if expr_z3.sort()==z3.FPSort(8,24):
        #    x = "TR(%s)"  %x

        toAppend= "%s %s = %s; " \
                  %( expr_type, var_name(expr_z3), \
                     x,\
                  )
        result.append(toAppend)
        return var_name(expr_z3)

    if sort_z3 == z3.Z3_OP_FPA_LT:
        if DEBUG: print "-- Branch _is_lt"
        lhs = _gen(expr_z3.arg(0), symbolTable, cache, result)
        rhs = _gen(expr_z3.arg(1), symbolTable, cache, result)
        toAppend= "double %s = DLT(%s,%s);" \
                  %( var_name(expr_z3), \
                     lhs,\
                     rhs,\
                  )
        result.append(toAppend)
        return var_name(expr_z3)

    if _is_eq(expr_z3):
        if DEBUG: print "-- Branch _is_eq"
        lhs = _gen(expr_z3.arg(0), symbolTable, cache, result)
        rhs = _gen(expr_z3.arg(1), symbolTable, cache, result)
        toAppend= "double %s = DEQ(%s,%s);" \
                  %( var_name(expr_z3), \
                        lhs,\
                     rhs,\
                  )
        result.append(toAppend)
        return var_name(expr_z3)

    if _is_fpMul(expr_z3):
        if DEBUG: print "-- Branch _is_fpMul"
        if not _is_RNE(expr_z3.arg(0)):
            warnings.warn(
                "WARNING!!! arg(0) is not RNE but is treated as RNE. arg(0) = ",
                expr_z3.arg(0))
        assert expr_z3.num_args() == 3
        lhs = _gen(expr_z3.arg(1), symbolTable, cache, result)
        rhs = _gen(expr_z3.arg(2), symbolTable, cache, result)
        toAppend= "%s %s = %s*%s; " \
                  %( expr_type, var_name(expr_z3), \
                        lhs,\
                     rhs,\

                  )
        result.append(toAppend)
        return var_name(expr_z3)

    if _is_fpDiv(expr_z3):
        if DEBUG: print "-- Branch _is_fpDiv"
        if not _is_RNE(expr_z3.arg(0)):
            warnings.warn(
                "WARNING!!! arg(0) is not RNE but is treated as RNE. arg(0) = ",
                expr_z3.arg(0))
        assert expr_z3.num_args() == 3
        lhs = _gen(expr_z3.arg(1), symbolTable, cache, result)
        rhs = _gen(expr_z3.arg(2), symbolTable, cache, result)
        toAppend= "%s %s = %s/%s; " \
                  %(expr_type,  var_name(expr_z3), \
                        lhs,\
                     rhs,\
                  )
        result.append(toAppend)
        return var_name(expr_z3)

    if _is_fpAdd(expr_z3):
        if DEBUG: print "-- Branch _is_fpAdd"
        if not _is_RNE(expr_z3.arg(0)):
            warnings.warn(
                "WARNING!!! arg(0) is not RNE but is treated as RNE. arg(0) = ",
                expr_z3.arg(0))
        assert expr_z3.num_args() == 3
        lhs = _gen(expr_z3.arg(1), symbolTable, cache, result)
        rhs = _gen(expr_z3.arg(2), symbolTable, cache, result)
        toAppend= "%s %s = %s+%s;" \
                  %( expr_type, var_name(expr_z3), \
                        lhs,\
                     rhs,\
                  )
        result.append(toAppend)
        return var_name(expr_z3)

    if z3.is_and(expr_z3):
        if DEBUG: print "-- Branch _is_and"
        ##TODO Not sure if symbolTable will be treated in a multi-threaded way
        toAppendExpr = _gen(expr_z3.arg(0), symbolTable, cache, result)
        for i in range(1, expr_z3.num_args()):
            toAppendExpr = 'BAND( %s,%s )' % (
                toAppendExpr, _gen(expr_z3.arg(i), symbolTable, cache, result))

        toAppend= "double %s = %s; " \
                  %( var_name(expr_z3), \
                     toAppendExpr,\
                  )
        result.append(toAppend)
        return var_name(expr_z3)

    if z3.is_not(expr_z3):
        if DEBUG: print "-- Branch _is_not"
        assert expr_z3.num_args() == 1
        if not (expr_z3.arg(0).num_args() == 2):
            warnings.warn(
                "WARNING!!! arg(0) is not RNE but is treated as RNE. arg(0) = ",
                expr_z3.arg(0))
        op1 = _gen(expr_z3.arg(0).arg(0), symbolTable, cache, result)
        op2 = _gen(expr_z3.arg(0).arg(1), symbolTable, cache, result)
        if _is_ge(expr_z3.arg(0)):
            a = "DLT(%s,%s)" % (op1, op2)
        elif _is_gt(expr_z3.arg(0)):
            a = "DLE(%s,%s)" % (op1, op2)
        elif _is_le(expr_z3.arg(0)):
            a = "DGT(%s,%s)" % (op1, op2)
        elif _is_lt(expr_z3.arg(0)):
            a = "DGE(%s,%s)" % (op1, op2)
        elif _is_eq(expr_z3.arg(0)):
            a = "DNE(%s,%s)" % (op1, op2)
        elif _is_distinct(expr_z3.arg(0)):
            a = "DEQ(%s,%s)" % (op1, op2)
        else:
            raise NotImplementedError(
                "Not implemented case 004 for expr_z3  =  %s. 'Not(or... )' is not handled yet"
                % expr_z3)
        toAppend= "%s %s = %s; " \
                  %( expr_type, var_name(expr_z3), \
                     a,\
                  )
        result.append(toAppend)
        return var_name(expr_z3)

    if _is_fpNeg(expr_z3):
        if DEBUG: print "-- Branch _is_fpNeg"
        assert expr_z3.num_args() == 1
        op1 = _gen(expr_z3.arg(0), symbolTable, cache, result)
        toAppend = "%s %s =  - %s ;" \
                  %(expr_type, var_name(expr_z3), \
                     op1,\
                  )
        result.append(toAppend)
        return var_name(expr_z3)

    raise NotImplementedError(
        "Not implemented case 002 for expr_z3  =  %s, kind(%s)" %
        (expr_z3, expr_z3.decl().kind()))
示例#18
0
def walk_block(node, prev_g=None, cond=True):
    g = z3.Goal()
    g.add(cond)
    if prev_g is not None:
        for e in prev_g:
            if isinstance(e, z3.Goal):
                g.add(e.as_expr())
            else:
                g.add(e)

    if isinstance(node, pycp.c_ast.Compound):
        if node.block_items is not None:
            for e in node.block_items:
                g_next = walk_block(e, g)
                g = g_next
    elif isinstance(node, pycp.c_ast.Decl):
        if "int" in node.type.type.names:
            vars[node.name] = z3.Int(node.name)
        if "float" in node.type.type.names:
            vars[node.name] = z3.Real(node.name)
    elif isinstance(node, pycp.c_ast.FuncCall):
        if node.name.name == "__ASSUME":
            for e_exp in node.args.exprs:
                g.add(gen_smt_expr(e_exp))
        elif node.name.name == "__ASSERT":
            assertions = z3.Goal()
            for e_exp in node.args.exprs:
                assertions.add(gen_smt_expr(e_exp))
            print("solving..")
            print("SP:", g.as_expr())
            print("assert:", assertions)

            seen = set()

            def bv_length(e):
                li = [-1]
                if e in seen:
                    return -1
                if (z3.is_bv(e) and
                        z3.is_const(e) and
                        e.decl().kind() == z3.Z3_OP_UNINTERPRETED):
                    li.append(e.size())
                seen.add(e)
                if z3.is_app(e):
                    for ch in e.children():
                        li.append(bv_length(ch))
                elif z3.is_quantifier(e):
                    for ch in e.body().children():
                        li.append(bv_length(ch))
                return max(li)

            t = z3.Tactic('nla2bv')
            s = z3.Then(t, 'default').solver()
            fml = z3.And(g.as_expr(), z3.Not(assertions.as_expr()))
            print("solving using bitvector underapproximation..")
            s.add(fml)
            status = s.check()

            if status == z3.unknown:
                print("returned 'unknown'! trying again with bigger bit length..")
                print("getting highest bit length used in formula..")
                bv_l = bv_length(t(fml).as_expr())
                print("highest bit length used:", bv_l)

                while True:
                    bv_l += 1
                    print("trying with bit length:", bv_l)
                    s = z3.Then(z3.With('nla2bv', nla2bv_bv_size=bv_l),
                                'default').solver()
                    s.add(fml)
                    status = s.check()

                    if status != z3.unknown or bv_l >= 64:
                        break

            if status == z3.sat:
                model = s.model()
                print("program is unsafe.\nlisting an unsafe assignments..")
                for e in vars:
                    print(e, ':', model[vars[e]])
            elif status == z3.unsat:
                print("program is safe.")
            elif status == z3.unknown:
                print("unknown")

            s.reset()
        else:
            print("found a func call")
    elif isinstance(node, pycp.c_ast.Assignment):
        rexp = gen_smt_expr(node.rvalue)
        if z3.is_int(vars[node.lvalue.name]):
            hand_ = z3.Int('__hand__')
        elif z3.is_real(vars[node.lvalue.name]):
            hand_ = z3.Real('__hand__')
        if node.op == "=":
            g.add(hand_ == rexp)
        elif node.op == "+=":
            g.add(hand_ == (vars[node.lvalue.name] + rexp))
        elif node.op == "-=":
            g.add(hand_ == (vars[node.lvalue.name] - rexp))
        elif node.op == "*=":
            g.add(hand_ == (vars[node.lvalue.name] * rexp))
        elif node.op == "%=":
            g.add(hand_ == (vars[node.lvalue.name] % rexp))
        g_ = z3.Goal()
        g_.add(z3.Exists(vars[node.lvalue.name], g.as_expr()))
        g_ = t_qe_(g_)
        g = z3.Goal()
        g.add(z3.substitute(g_.as_expr(), (hand_, vars[node.lvalue.name])))
        # g = g.simplify()
    elif isinstance(node, pycp.c_ast.If):
        cond_exp = gen_smt_expr(node.cond)
        if node.iftrue is not None:
            true_expr = walk_block(node.iftrue, g, cond_exp).as_expr()
        else:
            true_expr = z3.And(cond_exp, g.as_expr())
        if node.iffalse is not None:
            false_expr = walk_block(
                node.iffalse, g, z3.Not(cond_exp)).as_expr()
        else:
            false_expr = z3.And(z3.Not(cond_exp), g.as_expr())
        g = z3.Goal()
        g.add(z3.Or(true_expr, false_expr))
        g = t(g)  # g.simplify()
    else:
        return prev_g
    # print(g.as_expr(), "\n")
    return g
    def _parseSmt1String(self, string):
        #self._logger.setVerbose(True)
        stack = list()
        functionSymbols = '&|~<=*+-'
        try:
            string = string.replace('\n', '').split('(')
            idx = 0
            for pos, elem in enumerate(string):
                self._logger.writeToLog('{} - reading :{}:'.format(pos, elem))
                if elem == '':
                    continue

                elemL = elem.split()
                # ALL lines should start with '('
                if elemL[0] in functionSymbols:
                    stack.append(elemL[0])
                elif elemL[0] == 'var':
                    varName = elemL[2].replace(')', '')
                    if elemL[1] == 'bool':
                        formula = z3.Bool(varName)
                        stack.append(self._abstraction(formula))
                    elif elemL[1] == 'real':
                        formula = z3.Real(varName)
                        stack.append(formula)
                    elif elemL[1] == 'int':
                        formula = z3.Int(varName)
                        stack.append(formula)
                    else:
                        raise Exception(
                            'Unknown Variable format: {}'.format(elemL))
                elif elemL[0] == 'const':
                    const = elemL[2].replace(')', '')
                    if elemL[1] == 'real':
                        stack.append(z3.RealVal(const))
                    elif elemL[1] == 'int':
                        stack.append(z3.IntVal(const))
                    else:
                        raise Exception(
                            'Unknown Constant format: {}'.format(elemL))
                else:
                    raise Exception('Unknown format : {}'.format(elemL))

                closedBrackets = elem.count(')') - 1
                self._logger.writeToLog(
                    "{} - new element in stack: {}\t,cB {}".format(
                        pos, stack[-1], closedBrackets))

                if closedBrackets < 1:
                    continue

                while closedBrackets > 0:
                    self._logger.writeToLog('{} - stack: {},{}'.format(
                        pos, stack, closedBrackets))
                    tmpPredi = []
                    pred = None
                    while True:
                        pred = stack.pop()
                        #if isinstance(pred,Predicate) or isinstance(pred,z3.BoolRef) or str(pred).replace('.','',1).isdigit():
                        #if z3.is_rational_value(pred) or z3.is_int_value(pred) or z3.is_int(pred) or z3.is_real(pred) or z3.is_bool(pred):
                        if isinstance(pred, float) or isinstance(
                                pred, int) or z3.is_int(pred) or z3.is_real(
                                    pred) or z3.is_bool(pred):
                            tmpPredi.append(pred)
                        else:
                            if len(tmpPredi) == 1:
                                tmpPredi = tmpPredi[0]
                            else:
                                tmpPredi = tmpPredi[::-1]
                            break
                    self._logger.writeToLog('{} - {} is applied to {}'.format(
                        pos, pred, tmpPredi))
                    newElem = self._mapFunctionSymbol(pred)(tmpPredi)
                    # newElemSimplified = z3.simplify(newElem)
                    stack.append(newElem)
                    self._logger.writeToLog(
                        "{} - new element in stack: {}\t,cB {}".format(
                            pos, stack[-1], closedBrackets))
                    closedBrackets -= 1
                self._logger.writeToLog('{} - finished :{}:'.format(
                    pos, stack))
        except Exception as e:
            self._logger.writeToLog(
                "Some Error : {}\n\t Occured parsing formula: {}".format(
                    e, string))
            raise e

        if len(stack) != 1:
            raise Exception("Parsing Error, stack != 1")
        return self._recusiveSimplification(stack[0])
示例#20
0
def check_sort(z3_var):
    assert (z3.is_bool(z3_var) or z3.is_int(z3_var)),\
        str(z3_var) + ' has unsupported type ' + str(type(z3_var))
示例#21
0
 def _eval_int(expr: z3.ExprRef) -> str:  # TODO: this should return int
     assert z3.is_int(expr), expr
     ans = z3model.eval(expr, model_completion=True)
     assert z3.is_int_value(ans), (expr, ans)
     return str(ans.as_long())
示例#22
0
def solveConstrains(constraints, types, shouldPrint=True):
    if type(types) == dict:
        addTypesFromTaintAnalysis('event', types['event'])
    else:
        for [iden, typo] in types:
            if type(iden) == str:
                infered_types[iden] = typo
    logging.debug(infered_types)
    c = True
    for constraint in constraints:
        cc = createZ3ForIf(constraint, types)
        logging.debug(cc)
        if z3.is_int(cc):
            cc = cc != 0
        elif z3.is_string(cc):
            cc = cc != z3.StringVal('')
        c = z3.And(c, cc)
    for cc in GLOBAL_CONSTRAINTS:
        logging.debug(cc)

        c = z3.And(c, cc)

    for type_info in infered_types:
        if infered_types[type_info] == '':
            continue
        cc = z3.String('type:' + type_info) == z3.StringVal(infered_types[type_info])
        logging.debug(cc)
        c = z3.And(c, cc)

    for identifier in MAKE_UNSOLVABLE:
        cc = z3.String(identifier) == z3.StringVal('')
        logging.debug(cc)

        c = z3.And(c, cc)

    # solver = z3.SolverFor('QF_LIA')
    solver = z3.Solver()
    solver.add(c)
    r = solver.check()
    if r == z3.unsat:
        if shouldPrint:
            eprint("no solution")
        return 'unsat'
    elif r == z3.unknown:
        if shouldPrint:
            eprint("failed to solve")

        return 'unsat'
        try:
            eprint(solver.model())
        except Exception:
            return
    else:
        model = solver.model()
        assignement = dict()
        types = dict()
        for decl in model.decls():
            if str(decl) == 'event':
                continue
            if str(decl)[:5] == 'type:':
                types[str(decl)[5:]] = AssignementsToString(model.get_interp(decl), model)
            else:
                assignement[str(decl)] = AssignementsToString(model.get_interp(decl), model)
        for identifier in GLOBAL_IDENTIFIER:
            if identifier not in assignement:
                if identifier == 'event':
                    continue
                logging.debug('Adding empty shizzle')
                assignement[identifier] = ''
        logging.debug(GLOBAL_IDENTIFIER)
        if shouldPrint:
            print(json.dumps({'assignements': assignement, 'types': types}))
        return {'assignements': assignement, 'types': types}