예제 #1
0
파일: search.py 프로젝트: shanfu67/rekall
    def render_output_analysis(self, renderer):
        """Render analysis of the expression's return type and its members."""
        output_type = infer_type.infer_type(self.query, self)

        renderer.section("Type Analysis", width=140)
        renderer.table_header([
            dict(name="Name", cname="name", type="TreeNode", max_depth=2,
                 width=60),
            dict(name="Type", cname="type", width=40)
        ])

        renderer.table_row(self.query.source,
                           repr(output_type),
                           depth=1)

        try:
            for member in structured.getmembers(output_type):
                subq = "(%s)[%r]" % (self.query.source, member)
                subtype = infer_type.infer_type(q.Query(subq), self)
                if isinstance(subtype, type):
                    subtype = subtype.__name__
                else:
                    subtype = repr(subtype)

                renderer.table_row(subq, subtype, depth=2)
        except (NotImplementedError, TypeError, AttributeError):
            pass
예제 #2
0
    def testResolve(self):
        self.assertIsa(
            infer_type.infer_type(
                q.Query("Process.pid"),
                mocks.MockRootType),
            number.INumber)

        self.assertIsa(
            infer_type.infer_type(
                q.Query("Process.parent.pid"),
                mocks.MockRootType),
            number.INumber)
예제 #3
0
    def testSelect(self):
        self.assertIsa(
            infer_type.infer_type(
                q.Query("Process['pid']"),
                mocks.MockRootType),
            number.INumber)

        self.assertEqual(
            infer_type.infer_type(
                q.Query("Process[var_name]"),
                mocks.MockRootType),
            protocol.AnyType)
예제 #4
0
    def testVariadicExpression(self):
        self.assertIsa(
            infer_type.infer_type(
                q.Query("5 + 5"),
                mocks.MockRootType),
            number.INumber)

        self.assertIsa(
            infer_type.infer_type(
                q.Query("10 * (1 - 4) / 5"),
                mocks.MockRootType),
            number.INumber)
예제 #5
0
    def testMap(self):
        self.assertIsa(
            infer_type.infer_type(
                q.Query("Process.parent.pid + 10"),
                mocks.MockRootType),
            number.INumber)

        # Should be the same using shorthand syntax.
        self.assertIsa(
            infer_type.infer_type(
                q.Query("Process.parent.pid - 1"),
                mocks.MockRootType),
            number.INumber)
예제 #6
0
 def testCount(self):
     """Count is pretty simple."""
     self.assertIsa(
         infer_type.infer_type(
             q.Query(("apply", ("var", "count"), ("repeat", 1, 2, 3))),
             mocks.MockRootType),
         number.INumber)
예제 #7
0
파일: validate.py 프로젝트: Onager/dotty
def validate(expr, scope):
    lhs_type = infer_type.infer_type(expr.lhs, scope)
    if not (lhs_type is protocol.AnyType
            or protocol.isa(lhs_type, expr.type_signature[0])):
        raise errors.EfilterTypeError(root=expr.lhs,
                                      expected=expr.type_signature[0],
                                      actual=lhs_type)

    rhs_type = infer_type.infer_type(expr.rhs, scope)
    if not (lhs_type is protocol.AnyType
            or protocol.isa(rhs_type, expr.type_signature[1])):
        raise errors.EfilterTypeError(root=expr.rhs,
                                      expected=expr.type_signature[1],
                                      actual=rhs_type)

    return True
예제 #8
0
파일: search.py 프로젝트: shuowen/rekall
    def render(self, renderer):
        # Do we have a query?
        if not self.query:
            return self.render_error(renderer)

        # Figure out what the header should look like.
        # Can we infer the type?
        try:
            t = infer_type.infer_type(self.query, self)
        except Exception:
            t = None

        # Get the data we're rendering.
        try:
            rows = self.collect() or []
        except errors.EfilterError as error:
            self.query_error = error
            return self.render_error(renderer)

        # If we know the header, great!
        if isinstance(t, plugin.TypedProfileCommand):
            renderer.table_header(t.table_header)
            return self._render_plugin_output(renderer, t.table_header,
                                              *rows)

        # Maybe we cached the header when we ran the plugin?
        if isinstance(t, plugin.Command):
            wrapper = self._cached_plugin_wrappers.get(t.name)
            # If we land here there's two options: either the query already
            # forced the wrapper to apply (either by explicitly using it as a
            # function, or by doing something non-lazy; or the wrapper hasn't
            # been called yet. The latter can only be the case if the wrapper is
            # being used as a variable, not a function, so we need to
            # materialize it with no arguments. If it already has data for a
            # call with no args then this won't do anything.
            wrapper.materialize()

            if wrapper:
                renderer.table_header(wrapper.columns)
                return self._render_plugin_output(renderer,
                                                  wrapper.columns,
                                                  *rows)

        # Try to guess the header based on structure of the first row.
        if not rows:
            renderer.table_header([("No Results", "no_results", "20")])
            return

        rows = iter(rows)
        first_row = next(rows)
        if isinstance(first_row, dict):
            renderer.table_header(
                [dict(name=unicode(k), cname=unicode(k))
                 for k in first_row.iterkeys()])

            return self._render_dicts(renderer, first_row, *rows)

        # Sigh. Give up, and render whatever you got, I guess.
        renderer.table_header([dict(name="Result", cname="result")])
        return self._render_whatever_i_guess(renderer, first_row, *rows)
예제 #9
0
파일: search.py 프로젝트: shanfu67/rekall
    def _render_node(self, query, node, renderer, depth=1):
        """Render an AST node and recurse."""
        t = infer_type.infer_type(node, self)

        try:
            name = "(%s) <%s>" % (t.__name__, type(node).__name__)
        except AttributeError:
            name = "(%r) <%s>" % (t, type(node).__name__)

        renderer.table_row(
            name,
            utils.AttributedString(
                str(query),
                [dict(start=node.start, end=node.end, fg="RED", bold=True)]
            ),
            depth=depth
        )

        for child in node.children:
            if isinstance(child, ast.Expression):
                self._render_node(node=child, renderer=renderer, query=query,
                                  depth=depth + 1)
            else:
                renderer.table_row(
                    "(%s) <leaf: %r>" % (type(child).__name__, child),
                    None,
                    depth=depth + 1
                )
예제 #10
0
파일: api.py 프로젝트: kleopatra999/dotty
def infer(query, replacements=None, root_type=None):
    """Determine the type of the query's output without actually running it.

    Arguments:
        query: A query object or string with the query.
        replacements: Built-time parameters to the query, either as dict or as
            an array (for positional interpolation).
        root_type: The types of variables to be supplied to the query inference.

    Returns:
        The type of the query's output, if it can be determined. If undecidable,
        returns efilter.protocol.AnyType.

        NOTE: The inference returns the type of a row in the results, not of the
        actual Python object returned by 'apply'. For example, if a query
        returns multiple rows, each one of which is an integer, the type of the
        output is considered to be int, not a collection of rows.

    Examples:
        infer("5 + 5") # -> INumber

        infer("SELECT * FROM people WHERE age > 10") # -> AnyType

        # If root_type implements the IStructured reflection API:
        infer("SELECT * FROM people WHERE age > 10", root_type=...) # -> dict
    """
    query = q.Query(query, params=replacements)
    return infer_type.infer_type(query, root_type)
예제 #11
0
파일: validate.py 프로젝트: Onager/dotty
def validate(expr, scope):
    t = infer_type.infer_type(expr.value, scope)
    if not protocol.isa(t, boolean.IBoolean):
        raise errors.EfilterTypeError(root=expr,
                                      actual=t,
                                      expected=boolean.IBoolean)

    return True
예제 #12
0
파일: validate.py 프로젝트: Onager/dotty
def validate(expr, scope):
    for subexpr in expr.children:
        validate(subexpr, scope)

        t = infer_type.infer_type(subexpr, scope)
        if not (t is protocol.AnyType
                or protocol.isa(t, expr.type_signature)):
            raise errors.EfilterTypeError(root=subexpr,
                                          expected=expr.type_signature,
                                          actual=t)

    return True
예제 #13
0
파일: api.py 프로젝트: Onager/dotty
def infer(query, replacements=None, root_type=None,
          libs=("stdcore", "stdmath")):
    """Determine the type of the query's output without actually running it.

    Arguments:
        query: A query object or string with the query.
        replacements: Built-time parameters to the query, either as dict or as
            an array (for positional interpolation).
        root_type: The types of variables to be supplied to the query inference.
        libs: What standard libraries should be taken into account for the
            inference.

    Returns:
        The type of the query's output, if it can be determined. If undecidable,
        returns efilter.protocol.AnyType.

        NOTE: The inference returns the type of a row in the results, not of the
        actual Python object returned by 'apply'. For example, if a query
        returns multiple rows, each one of which is an integer, the type of the
        output is considered to be int, not a collection of rows.

    Examples:
        infer("5 + 5") # -> INumber

        infer("SELECT * FROM people WHERE age > 10") # -> AnyType

        # If root_type implements the IStructured reflection API:
        infer("SELECT * FROM people WHERE age > 10", root_type=...) # -> dict
    """
    # Always make the scope stack start with stdcore.
    if root_type:
        type_scope = scope.ScopeStack(std_core.MODULE, root_type)
    else:
        type_scope = scope.ScopeStack(std_core.MODULE)

    stdcore_included = False
    for lib in libs:
        if lib == "stdcore":
            stdcore_included = True
            continue

        module = std_core.LibraryModule.ALL_MODULES.get(lib)
        if not module:
            raise TypeError("No standard library module %r." % lib)

        type_scope = scope.ScopeStack(module, type_scope)

    if not stdcore_included:
        raise TypeError("'stdcore' must always be included.")

    query = q.Query(query, params=replacements)
    return infer_type.infer_type(query, type_scope)
예제 #14
0
파일: validate.py 프로젝트: Onager/dotty
def validate(expr, scope):
    # Make sure there's an ELSE block.
    if expr.default() is None:
        raise errors.EfilterLogicError(
            root=expr,
            message="Else blocks are required in EFILTER.")

    # Make sure conditions evaluate to IBoolean.
    for condition, _ in expr.conditions():
        t = infer_type.infer_type(condition, scope)
        if not protocol.isa(t, boolean.IBoolean):
            raise errors.EfilterTypeError(root=expr, actual=t,
                                          expected=boolean.IBoolean)
예제 #15
0
파일: search.py 프로젝트: 453483289/rekall
    def render(self, renderer):
        # Do we have a query?
        if not self.query:
            return self.render_error(renderer)

        # Figure out what the header should look like.
        # Can we infer the type?
        try:
            t = infer_type.infer_type(self.query, self)
        except Exception:
            t = None

        # Get the data we're rendering.
        try:
            rows = self.collect() or []
        except errors.EfilterError as error:
            self.query_error = error
            return self.render_error(renderer)

        # If we know the header, great!
        if isinstance(t, plugin.TypedProfileCommand):
            renderer.table_header(t.table_header)
            return self._render_plugin_output(renderer, t.table_header,
                                              *rows)

        # Maybe we cached the header when we ran the plugin?
        if isinstance(t, plugin.Command):
            wrapper = self._cached_plugin_wrappers.get(t.name)
            if wrapper:
                renderer.table_header(wrapper.columns)
                return self._render_plugin_output(renderer,
                                                  wrapper.columns,
                                                  *rows)

        # Try to guess the header based on structure of the first row.
        if not rows:
            renderer.table_header([("No Results", "no_results", "20")])
            return

        rows = iter(rows)
        first_row = next(rows)
        if isinstance(first_row, dict):
            renderer.table_header(
                [dict(name=unicode(k), cname=unicode(k))
                 for k in first_row.iterkeys()])

            return self._render_dicts(renderer, first_row, *rows)

        # Sigh. Give up, and render whatever you got, I guess.
        renderer.table_header([dict(name="Result", cname="result")])
        return self._render_whatever_i_guess(renderer, first_row, *rows)
예제 #16
0
파일: search.py 프로젝트: atwong589/rekall
    def render(self, renderer):
        # Figure out what the header should look like.
        # Can we infer the type?
        try:
            t = infer_type.infer_type(self.query, self)
        except Exception:
            t = None

        rows = self.collect() or []

        # If we know the header, great!
        if isinstance(t, plugin.TypedProfileCommand):
            renderer.table_header(t.table_header)
            return self._render_plugin_output(renderer, t.table_header,
                                              *rows)

        # Maybe we cached the header when we ran the plugin?
        if isinstance(t, plugin.Command):
            header = self._cached_plugin_renderers.get(t.name)
            if header:
                renderer.table_header(header.columns)
                return self._render_plugin_output(renderer,
                                                  header.columns, *rows)

        # Try to guess the header based on structure of the first row.
        if not rows:
            renderer.table_header([("No Results", "no_results", "20")])
            return

        rows = iter(rows)
        first_row = next(rows)
        if isinstance(first_row, dict):
            renderer.table_header(
                [dict(name=k, cname=k) for k in first_row.iterkeys()])

            return self._render_dicts(renderer, first_row, *rows)

        # Sigh. Give up, and render whatever you got, I guess.
        renderer.table_header([dict(name="Result", cname="result")])
        return self._render_whatever_i_guess(renderer, first_row, *rows)
예제 #17
0
파일: infer_type.py 프로젝트: rlugojr/dotty
 def testRepeat(self):
     self.assertIsa(infer_type.infer_type(q.Query(("repeat", 1, 2, 3)), mocks.MockRootType), number.INumber)
예제 #18
0
파일: infer_type.py 프로젝트: rlugojr/dotty
 def testApply(self):
     self.assertIsa(infer_type.infer_type(q.Query("MockFunction(5, 10)"), mocks.MockRootType), number.INumber)
예제 #19
0
파일: infer_type.py 프로젝트: rlugojr/dotty
 def testEach(self):
     self.assertIsa(
         infer_type.infer_type(q.Query("any Process.children where (name == 'init')"), mocks.MockRootType),
         boolean.IBoolean,
     )
예제 #20
0
파일: infer_type.py 프로젝트: rlugojr/dotty
 def testAny(self):
     self.assertIsa(
         infer_type.infer_type(q.Query("any pslist where (parent.name == 'init')"), mocks.MockRootType),
         boolean.IBoolean,
     )
예제 #21
0
 def testApply(self):
     self.assertIsa(
         infer_type.infer_type(q.Query("MockFunction(5, 10)"),
                               mocks.MockRootType), number.INumber)
예제 #22
0
파일: search.py 프로젝트: shanfu67/rekall
    def render(self, renderer):
        # Do we have a query?
        if not self.query:
            return self.render_error(renderer)

        # Figure out what the header should look like.
        # Can we infer the type?
        try:
            t = infer_type.infer_type(self.query, self)
        except Exception:
            t = None

        # Get the data we're rendering.
        try:
            rows = self.collect() or []
        except errors.EfilterError as error:
            self.query_error = error
            return self.render_error(renderer)

        # If the output type is a TypeProfileCommand subclass then we can just
        # interrogate its header.
        if getattr(t, "table_header", None):
            renderer.table_header(t.table_header)
            return self._render_plugin_output(renderer, t.table_header,
                                              *rows)

        # If the output type is a regular plugin then we must've run it at some
        # point and should be able to retrieve a cached copy of the wrapper,
        # which will have preserved the output columns.
        if isinstance(t, plugin.Command):
            cached_wrapper = self._cached_command_wrappers.get(t.name)
            if not cached_wrapper:
                raise RuntimeError("Command of type %r is the output of an "
                                   "EFILTER query but no such command was "
                                   "executed." % (t,))

            if not cached_wrapper._applied_args:
                cached_wrapper.apply((), {})

            renderer.table_header(cached_wrapper.columns)
            return self._render_plugin_output(renderer, cached_wrapper.columns,
                                              *rows)

        # If we got no rows in the output the just say so.
        rows = iter(rows)
        try:
            first_row = next(rows)
        except StopIteration:
            renderer.table_header([("No Results", "no_results", "20")])
            return

        # As last ditch, try to guess the header based on the data in the
        # first row.
        if isinstance(first_row, dict):
            # Maybe we have a plugin with matching columns in its output?
            columns = self._find_matching_header(first_row.keys())
            if columns:
                renderer.table_header(columns)
                return self._render_plugin_output(renderer,
                                                  columns,
                                                  first_row,
                                                  *rows)

            renderer.table_header(
                [dict(name=unicode(k), cname=unicode(k))
                 for k in first_row.iterkeys()])

            return self._render_dicts(renderer, first_row, *rows)

        # Sigh. Give up, and render whatever you got, I guess.
        renderer.table_header([dict(name="Result", cname="result")])
        return self._render_whatever_i_guess(renderer, first_row, *rows)
예제 #23
0
파일: infer_type.py 프로젝트: rlugojr/dotty
 def testEquivalence(self):
     self.assertIsa(infer_type.infer_type(q.Query("Process.name == 'init'"), mocks.MockRootType), boolean.IBoolean)
예제 #24
0
파일: infer_type.py 프로젝트: rlugojr/dotty
 def testVar(self):
     self.assertIsa(infer_type.infer_type(q.Query("foo"), mocks.MockRootType), protocol.AnyType)
예제 #25
0
파일: infer_type.py 프로젝트: rlugojr/dotty
 def testLiteral(self):
     self.assertIsa(infer_type.infer_type(q.Query("42"), mocks.MockRootType), number.INumber)
예제 #26
0
 def testEach(self):
     self.assertIsa(
         infer_type.infer_type(
             q.Query("any Process.children where (name == 'init')"),
             mocks.MockRootType), boolean.IBoolean)
예제 #27
0
 def testFilter(self):
     self.assertIsa(
         infer_type.infer_type(
             q.Query("select * from pslist where (parent.pid == 10)"),
             mocks.MockRootType), mocks.Process)
예제 #28
0
파일: infer_type.py 프로젝트: rlugojr/dotty
 def testFilter(self):
     self.assertIsa(
         infer_type.infer_type(q.Query("select * from pslist where (parent.pid == 10)"), mocks.MockRootType),
         mocks.Process,
     )
예제 #29
0
파일: search.py 프로젝트: samghub/rekall
    def render(self, renderer):
        # Do we have a query?
        if not self.query:
            return self.render_error(renderer)

        # Figure out what the header should look like.
        # Can we infer the type?

        # For example for select statements the type will be
        # associative.IAssociative because they return a dict like result.
        try:
            t = infer_type.infer_type(self.query, self)
        except Exception:
            t = None

        if isinstance(t, CommandWrapper):
            raise RuntimeError(
                "%r is a plugin and must be called as a function. Try '%s()'"
                " instead of '%s'"
                % (t.plugin_cls, t.plugin_cls.name, t.plugin_cls.name))

        # Get the data we're rendering.
        try:
            rows = self.collect() or []
        except errors.EfilterError as error:
            self.query_error = error
            return self.render_error(renderer)

        # If the query returns the output of a plugin then we have to render
        # the same columns as the plugin. If the plugin declares its columns
        # then that's easy. Otherwise we have to try and get the columns from
        # cache.
        # e.g. select * from pslist()
        if isinstance(t, plugin.Command):
            output_header = getattr(t, "table_header", None)
            if output_header is None:
                raise plugin.PluginError(
                    "Query is using plugin %s which is not typed." % t.name)

            renderer.table_header(output_header)
            return self._render_plugin_output(renderer, output_header, rows)

        # For queries which name a list of columns we need to get the first row
        # to know which columns will be output. Surely efilter can provide this
        # from the AST?  This seems like a hack because if the first row the
        # plugin produces does not include all the columns we will miss them.
        # If is also buggy because if the plugin does not produce any rows we
        # can not know if the query is correct or not. For example "select XXXX
        # from plugin()" can not raise an unknown column XXXX if the plugin does
        # not produce at least one row.
        remaining_rows = iter(rows)
        try:
            first_row = next(remaining_rows)
        except StopIteration:
            renderer.format("No results.")
            return

        all_rows = itertools.chain((first_row,), remaining_rows)

        # If we have some output but don't know what it is we can try to use
        # dict keys as columns.
        if isinstance(first_row, row_tuple.RowTuple):
            columns = [dict(name=x)
                       for x in structured.getmembers(first_row)]
            renderer.table_header(columns, auto_widths=True)
            return self._render_plugin_output(renderer, columns, all_rows)

        # Sigh. Give up, and render whatever you got, I guess.
        renderer.table_header([dict(name="Result", cname="result")])
        return self._render_whatever_i_guess(renderer, all_rows)
예제 #30
0
파일: infer_type.py 프로젝트: rlugojr/dotty
 def testComplement(self):
     self.assertIsa(infer_type.infer_type(q.Query("not Process.name"), mocks.MockRootType), boolean.IBoolean)
예제 #31
0
 def testRepeat(self):
     self.assertIsa(
         infer_type.infer_type(q.Query(("repeat", 1, 2, 3)),
                               mocks.MockRootType), number.INumber)
예제 #32
0
파일: infer_type.py 프로젝트: rlugojr/dotty
 def testIsInstance(self):
     self.assertIsa(infer_type.infer_type(q.Query("proc isa Process"), mocks.MockRootType), boolean.IBoolean)
예제 #33
0
파일: infer_type.py 프로젝트: rlugojr/dotty
 def testVar(self):
     self.assertIsa(infer_type.infer_type(q.Query("Process.pid"), mocks.MockRootType), int)
예제 #34
0
파일: infer_type.py 프로젝트: rlugojr/dotty
 def testBinaryExpression(self):
     self.assertIsa(infer_type.infer_type(q.Query("'foo' in ('bar', 'foo')"), mocks.MockRootType), boolean.IBoolean)