/usr/lib/python2.7/dist-packages/rekall/plugins/common/efilter_plugins/info.py is in python-rekall-core 1.6.0+dfsg-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | # Rekall Memory Forensics
# Copyright 2016 Google Inc. All Rights Reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or (at
# your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
"""Informational plugins for assistance of efilter operations."""
from efilter.protocols import structured
from rekall import plugin
from rekall import session
from rekall import testlib
class Describe(plugin.TypedProfileCommand, plugin.ProfileCommand):
"""Describe the output of a plugin."""
name = "describe"
PROFILE_REQUIRED = False
__args = [
dict(name="plugin_name", required=True, positional=True,
help="A plugin or plugin name to describe."),
dict(name="max_depth", positional=True, required=False,
type="IntParser", default=0,
help="The maximum depth to follow mappings."),
]
table_header = [
dict(name="Field", type="TreeNode", max_depth=5, width=50),
dict(name="Type"),
]
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
def _determine_type_name(self, column_type_instance):
if isinstance(column_type_instance, type):
column_type_instance = column_type_instance()
object_type = None
try:
object_type = column_type_instance.obj_type
except AttributeError:
pass
if object_type is None:
object_type = type(column_type_instance).__name__
return object_type
def collect(self):
plugin_name = self.plugin_args.plugin_name
if isinstance(plugin_name, session.PluginRunner):
plugin_name = self.plugin_args.plugin_name.plugin_name
plugin_cls = self.session.plugins.GetPluginClass(plugin_name)
if not plugin_cls:
raise plugin.PluginError("Please specify a valid plugin.")
instance = plugin_cls(session=self.session, ignore_required=True)
table_header = getattr(instance, "table_header", None)
if not table_header:
raise plugin.PluginError(
"Plugin %s is not a Typed Plugin. It can not be used in "
"searches." % plugin_name)
column_types = instance.column_types()
for i, column in enumerate(table_header):
column_name = column["name"]
if isinstance(column_types, dict):
column_type_instance = column_types.get(column_name)
else:
column_type_instance = column_types[i]
yield dict(
Field=column_name,
Type=self._determine_type_name(column_type_instance),
)
for x in self.collect_members(column_type_instance, 1):
yield x
class TestDescribe(testlib.SimpleTestCase):
PARAMETERS = dict(commandline="describe pslist")
|