Beispiel #1
0
def check_add_overflow(a, b):
    ## integer overflow detection for addition.
    overflow = ast_and(ast_gt(b, ast(0)), ast_gt(a, ast_minus(ast(INT_MAX),
                                                              b)))
    underflow = ast_and(ast_lt(b, ast(0)), ast_lt(a,
                                                  ast_minus(ast(INT_MIN), b)))
    return z3expr(ast_or(overflow, underflow))
Beispiel #2
0
 def __cmp__(self, o):
     res = self.__v.__cmp__(o)
     if concolic_bool(ast_lt(self.__ast, ast(o)), res < 0):
         return -1
     if concolic_bool(ast_gt(self.__ast, ast(o)), res > 0):
         return 1
     return 0
Beispiel #3
0
def concolic_bool(sym, v):
    ## Python claims that 'bool' is not an acceptable base type,
    ## so it seems difficult to subclass bool.  Luckily, bool has
    ## only two possible values, so whenever we get a concolic
    ## bool, add its value to the constraint.
    add_pc(ast_eq(sym, ast(v)))
    return v
Beispiel #4
0
def symbolic_bool(sym):
    pid = os.fork()
    ## even we limit the number of processes running simultaneously,
    ## we still need to fork one process which stays in blocked state
    ## until the semaphore is active... so, memory usage is a shitty issue.
    if pid:  # parent
        solver.add(z3expr(ast_eq(sym, ast(True))))
        r = True
        log("assume (%s)" % str(sym))
    else:  # child
        sem.acquire()
        solver.add(z3expr(ast_eq(sym, ast(False))))
        r = False
        log("assume ¬(%s)" % str(sym))
    if solver.check() != sat:
        log("unreachable")
        sys.exit(0)
    return r
Beispiel #5
0
def check_multiply_overflow(a, b):
    ## integer overflow detection for multiplication.
    overflow = ast_gt(a, ast_div(ast(INT_MAX), b))
    underflow = ast_lt(a, ast_div(ast(INT_MIN), b))
    special1 = ast_and(ast_eq(a, ast(-1)), ast_eq(b, ast(INT_MIN)))
    special2 = ast_and(ast_eq(b, ast(-1)), ast_eq(a, ast(INT_MIN)))
    return z3expr(ast_and(overflow, underflow, special1, special2))
Beispiel #6
0
        def _wrapper(*args):
            arg_names = inspect.getargspec(self.func).args
            num_expected = len(arg_names)

            if num_expected != len(args):
                msg = "{}() takes exactly {} arguments ({} given)"
                raise TypeError(msg.format(self.func.__name__, num_expected, len(args)))

            specs = {name: arg_spec(a, name) for a, name in zip(args, arg_names)}

            if not self.return_ast:
                return kernel(self.func, specs, env=self.env)

            return ast(self.func, specs, env=self.env)
Beispiel #7
0
def generate_ast(raw_ast):
    iterator = iter(raw_ast)

    # find parent map
    c = ""
    while c != "parent_map":
        c = next(iterator)

    # skip parent map
    num_edges = int(next(iterator))
    for i in range(0, num_edges):
        next(iterator)
        next(iterator)

    return ast(iterator)
Beispiel #8
0
 def __rand__(self, o):
     res = value(o) & self.__v
     return concolic_int(ast_bwand(ast(o), self.__ast), res)
Beispiel #9
0
 def __rmod__(self, o):
     if _check_divided_by_zero:
         check_divided_by_zero(self.__ast)
     res = value(o) % self.__v
     return concolic_int(ast_mod(ast(o), self.__ast), res)
Beispiel #10
0
 def __and__(self, o):
     res = self.__v & value(o)
     return concolic_int(ast_bwand(self.__ast, ast(o)), res)
Beispiel #11
0
 def __eq__(self, o):
     if not isinstance(o, int):
         return False
     res = (self.__v == value(o))
     return concolic_bool(ast_eq(self.__ast, ast(o)), res)
Beispiel #12
0
 def __le__(self, o):
     res = self.__v <= o
     return concolic_bool(ast_not(ast_gt(self.__ast, ast(o))), res)
Beispiel #13
0
 def __rlshift__(self, o):
     res = value(o) << self.__v
     return concolic_int(ast_lshift(ast(o), self.__ast), res)
Beispiel #14
0
 def __rrshift__(self, o):
     res = value(o) >> self.__v
     return concolic_int(ast_rshift(ast(o), self.__ast), res)
Beispiel #15
0
 def __rsub__(self, o):
     if _check_overflow:
         check_minus_overflow(ast(o), self.__ast)
     res = value(o) - self.__v
     return concolic_int(ast_minus(ast(o), self.__ast), res)
Beispiel #16
0
def check_divided_by_zero(d):
    return z3expr(ast_eq(d, ast(0)))
Beispiel #17
0
 def __radd__(self, o):
     if _check_overflow:
         check_add_overflow(ast(o), self.__ast)
     res = value(o) + self.__v
     return concolic_int(ast_plus(ast(o), self.__ast), res)
Beispiel #18
0
 def __sub__(self, o):
     if _check_overflow:
         check_minus_overflow(self.__ast, ast(o))
     res = self.__v - value(o)
     return concolic_int(ast_minus(self.__ast, ast(o)), res)
Beispiel #19
0
 def __add__(self, o):
     if _check_overflow:
         check_add_overflow(self.__ast, ast(o))
     res = self.__v + value(o)
     return concolic_int(ast_plus(self.__ast, ast(o)), res)
Beispiel #20
0
 def __ge__(self, o):
     res = self.__v >= o
     return concolic_bool(ast_not(ast_lt(self.__ast, ast(o))), res)
Beispiel #21
0
 def __gt__(self, o):
     res = self.__v > o
     return concolic_bool(ast_gt(self.__ast, ast(o)), res)
Beispiel #22
0
 def __or__(self, o):
     res = self.__v | value(o)
     return concolic_int(ast_bwor(self.__ast, ast(o)), res)
Beispiel #23
0
def show_expanded(tree, expand_macros, **kw):
    expanded_tree = expand_macros(tree)
    new_tree = q(wrap_simple(log, u(unparse_ast(expanded_tree)), ast(expanded_tree)))
    return new_tree
Beispiel #24
0
 def __ror__(self, o):
     res = value(o) | self.__v
     return concolic_int(ast_bwor(ast(o), self.__ast), res)
Beispiel #25
0
"""
Exec Command Pre-processing
===========================
This module defines the :func:`transform_source` and
:func:`transform_ast` functions, which take pre-processes code from
:class:`msg.Exec` instances before `exec`-ing.

Source Transformations (:func:`transform_source`)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
These are transforms that act on the string source of the command, and return
the modified source.  These are generally hack-ish, so if you're adding a
transform, try to do it with an ast transform.

ast (Abstract Syntax Tree) Transformations (:func:`transform_ast`)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
These are transforms that act on the ast, and return the modified ast:
* :func:`displayhook_last` -- if the last node in an in-order traversal
  of the ast is an `Expr`(ession node), add a call to
  :func:`__displayhook__`.
* :class:`DisplayhookAll` -- a subclass of
  :class:`ast.NodeTransformer` that adds the displayhook to all
  :class:`ast.Expr` nodes.
* :class:`AssignhookAll` -- a subclass of
  :class:`ast.NodeTransformer` that prints out assignment statements.

"""
import ast

import astpp
Beispiel #26
0
 def __rshift__(self, o):
     res = self.__v >> value(o)
     return concolic_int(ast_rshift(self.__ast, ast(o)), res)
Beispiel #27
0
 def __rfloordiv__(self, o):
     if _check_divided_by_zero:
         check_divided_by_zero(self.__ast)
     res = value(o) // self.__v
     return concolic_int(ast_div(ast(o), self.__ast), res)
Beispiel #28
0
def flip_pc(pc):
    assert isinstance(pc, ast_eq)
    return ast_eq(pc.a, ast(not pc.b.b))
Beispiel #29
0
 def __mod__(self, o):
     if _check_divided_by_zero:
         check_divided_by_zero(ast(o))
     res = self.__v % value(o)
     return concolic_int(ast_mod(self.__ast, ast(o)), res)
Beispiel #30
0
 def __mul__(self, o):
     if _check_overflow:
         check_multiply_overflow(self.__ast, ast(o))
     res = self.__v * value(o)
     return concolic_int(ast_mul(self.__ast, ast(o)), res)
Beispiel #31
0
 def __lt__(self, o):
     res = self.__v < o
     return concolic_bool(ast_lt(self.__ast, ast(o)), res)
Beispiel #32
0
def log(tree, exact_src, **kw):
    new_tree = q(wrap(log, u(exact_src(tree)), ast(tree)))
    return new_tree
Beispiel #33
0
 def __rmul__(self, o):
     if _check_overflow:
         check_multiply_overflow(ast(o), self.__ast)
     res = value(o) * self.__v
     return concolic_int(ast_mul(ast(o), self.__ast), res)
Beispiel #34
0
def _require_transform(tree, exact_src):
    ret = trace_walk.recurse(copy.deepcopy(tree), exact_src)
    trace_walk.recurse(copy.deepcopy(tree), exact_src)
    new = q(ast(tree) or handle(lambda log: ast(ret)))
    return new
Beispiel #35
0
 def __floordiv__(self, o):
     if _check_divided_by_zero:
         check_divided_by_zero(ast(o))
     res = self.__v // value(o)
     return concolic_int(ast_div(self.__ast, ast(o)), res)