Esempio n. 1
0
    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
Esempio n. 2
0
    def collect_members(self, item, depth):
        if depth > self.plugin_args.max_depth:
            return

        try:
            for member in sorted(structured.getmembers(item)):
                type_instance = structured.resolve(item, member)
                # If it was given as a type, we need an instance here.
                if isinstance(type_instance, type):
                    type_instance = type_instance()

                try:
                    object_type = type_instance.obj_type
                except AttributeError:
                    object_type = type(type_instance).__name__

                yield dict(
                    Field=member,
                    Type=object_type,
                    depth=depth,
                )
                for x in self.collect_members(type_instance, depth + 1):
                    yield x

        except (TypeError, NotImplementedError):
            pass
Esempio n. 3
0
    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
Esempio n. 4
0
    def render(self, renderer):
        # Do we have a query?
        if not self.query:
            return self.render_error(renderer)

        # 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)

        # 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

        except errors.EfilterKeyError as e:
            raise plugin.PluginError(
                "Column %s not found. "
                "Use the describe plugin to list all available "
                "columns. (%s)" % (e.key, e))

        except errors.EfilterError as e:
            raise plugin.PluginError("EFilter Error: %s:" % e)

        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, (dict, 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")])
        return self._render_whatever_i_guess(renderer, all_rows)
Esempio n. 5
0
    def collect_members(self, item, depth):
        if depth > self.plugin_args.max_depth:
            return

        try:
            for member in sorted(structured.getmembers(item)):
                type_instance = structured.resolve(item, member)
                # If it was given as a type, we need an instance here.
                yield dict(
                    Field=member,
                    Type=self._determine_type_name(type_instance),
                    depth=depth,
                )
                for x in self.collect_members(type_instance, depth + 1):
                    yield x

        except (TypeError, NotImplementedError):
            pass
Esempio n. 6
0
    def collect_members(self, item, depth):
        if depth > self.plugin_args.max_depth:
            return

        try:
            for member in sorted(structured.getmembers(item)):
                type_instance = structured.resolve(item, member)
                # If it was given as a type, we need an instance here.
                yield dict(
                    Field=member,
                    Type=self._determine_type_name(type_instance),
                    depth=depth,
                )
                for x in self.collect_members(type_instance, depth + 1):
                    yield x

        except (TypeError, NotImplementedError):
            pass
Esempio n. 7
0
    def __eq__(self, other):
        if isinstance(other, type(self)):
            return self.ordered_dict == other.ordered_dict
        elif isinstance(other, structured.IStructured):
            try:
                other_members = structured.getmembers(other)
            except NotImplementedError:
                return None

            members = sorted(self.ordered_dict.keys())
            if members != sorted(other_members):
                return False

            vals = tuple([self.get(m) for m in members])
            other_vals = tuple([structured.resolve(other, m) for m in members])
            return vals == other_vals
        elif isinstance(other, (tuple, list)):
            return list(self) == list(other)
        else:
            return None
Esempio n. 8
0
    def __eq__(self, other):
        if isinstance(other, type(self)):
            return self.ordered_dict == other.ordered_dict
        elif isinstance(other, structured.IStructured):
            try:
                other_members = structured.getmembers(other)
            except NotImplementedError:
                return None

            members = sorted(self.ordered_dict.keys())
            if members != sorted(other_members):
                return False

            vals = tuple([self.get(m) for m in members])
            other_vals = tuple([structured.resolve(other, m) for m in members])
            return vals == other_vals
        elif isinstance(other, (tuple, list)):
            return list(self) == list(other)
        else:
            return None
Esempio n. 9
0
def convert_to_list(expr, repeated_list):
    if not repeated.isrepeating(repeated_list):
        return [repeated_list]

    result = []
    for element in repeated_list:
        if element is not None:
            # The output from a select is a repeated structured
            # (dict). If it has a single member we just use that,
            # otherwise we raise because the query is probably bad
            # (it should only return a single column).
            if structured.isstructured(element):
                members = structured.getmembers(element)
                if len(members) != 1:
                    raise errors.EfilterTypeError(
                        message="Expecting a single column in subselect - "
                        "got %s columns" % len(members),
                        query=expr.source)

                element = structured.resolve(element, members[0])
            result.append(element)

    return result
Esempio n. 10
0
    def _materialize_repeated_kwarg(self, kwargs):
        """Materialize the result of the args.

        This is a shim between a repeated plugin arg and the efilter
        stream.  We handle the following cases.

        1. EFilter LazyRepetition with unstructured elements (e.g. dicts).

        2. EFilter LazyRepetition with structured elements. These are
           usually returned from a subselect. In the special case
           where the arg name is present in the structure

        """
        result = {}
        for k, v in six.iteritems(kwargs):
            if not repeated.isrepeating(v):
                result[k] = v
            else:
                expanded_value = []
                for item in v:
                    if structured.isstructured(item):
                        members = structured.getmembers(item)
                        if len(members) == 1 or k in members:
                            # A single column in the subquery - just
                            # use that as the arg value.  If the name
                            # emitted is the same as the expected arg
                            # name we also just take that one.
                            expanded_value.append(
                                structured.resolve(item, members[0]))
                            continue

                    expanded_value.append(item)

                result[k] = expanded_value

        return result
Esempio n. 11
0
    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")])
        return self._render_whatever_i_guess(renderer, all_rows)
Esempio n. 12
0
    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)
Esempio n. 13
0
    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

        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.
        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)

        # In the past, if there were no results, the renderer would output
        # a special column to indicate status. That provided a strong cue to the
        # interactive user that there were no results but confused tools that
        # process Rekall output automatically. If there are no rows in the
        # output and we don't know the output header then we return right away.
        # To provide a visual cue we use unstructured output.
        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)