Example #1
0
    def __init__(self, *pos_args, **kwargs):
        self.ignore_required = kwargs.get("ignore_required", False)

        # If this is set we do not enforce required args. This is useful when
        # callers want to instantiate a plugin in order to use its methods as a
        # utility.
        if self.plugin_args is None:
            self.plugin_args = utils.AttributeDict()

        # Collect args in the declared order (basically follow the mro
        # backwards).
        definitions = []
        definitions_classes = {}
        for cls in self.__class__.__mro__:
            args_definition = getattr(cls, "_%s__args" % cls.__name__, [])
            for definition in args_definition:
                # Definitions can be just simple dicts.
                if isinstance(definition, dict):
                    definition = CommandOption(**definition)

                # We have seen this arg before.
                previous_definition = definitions_classes.get(definition.name)
                if previous_definition:
                    # Since we traverse the definition in reverse MRO order,
                    # later definitions should be masked by earlier (more
                    # derived) definitions.
                    continue

                definitions_classes[definition.name] = cls
                definitions.append(definition)

        # Handle positional args by consuming them off the pos_args array in
        # definition order. This allows positional args to be specified either
        # by position, or by keyword.
        positional_args = [x for x in definitions if x.positional]
        if len(positional_args) < len(pos_args):
            raise TypeError("Too many positional args provided.")

        for pos_arg, definition in zip(pos_args, positional_args):
            # If the positional arg is also defined as a keyword arg this is a
            # bug.
            if definition.name in kwargs:
                raise TypeError(
                    "Positional Args %s is also supplied as a keyword arg." %
                    definition.name)

            kwargs[definition.name] = pos_arg

        # Collect all the declared args and parse them.
        for definition in definitions:
            value = kwargs.pop(definition.name, None)
            if (value is None and definition.required
                    and not self.ignore_required):
                raise InvalidArgs("%s is required." % definition.name)

            self.plugin_args[definition.name] = definition.parse(
                value, session=kwargs.get("session"))

        super(ArgsParserMixin, self).__init__(**kwargs)
Example #2
0
    def collect(self):
        kuser_shared = self.session.address_resolver.get_constant_object(
            "nt!KI_USER_SHARED_DATA", "_KUSER_SHARED_DATA")

        seconds_since_boot = self.session.plugins.imageinfo().GetBootTime(
            kuser_shared)

        kernel_time = kuser_shared.SystemTime
        boot_timestamp = basic.UnixTimeStamp(
            value=kernel_time - seconds_since_boot,
            session=self.session)

        yield [utils.AttributeDict(now=kernel_time, boot=boot_timestamp,
                                   uptime=seconds_since_boot)]
Example #3
0
    def LoadConfigFile(self):
        """Parses the the config file.

        Applies interpolations and produces a dict of config options for each
        test. This also adds useful defaults to be available for interpolations
        in the config file itself. This config file is not written back.

        Returns:
          a dict with keys being the test names, and values being config_options
          for each test.
        """
        config = yaml.load(open(self.FLAGS.config).read())

        # Set some useful defaults - These do not get written to the file.
        config.setdefault("DEFAULT", {})
        defaults = config["DEFAULT"]
        defaults.update(
            dict(tempdir=self.temp_directory,
                 testdir=self.test_directory,
                 executable=self.FLAGS.executable))

        # Extra options to be used for testing.
        defaults["--format"] = "test"

        # Interpolate parameters in dicts from the config.
        for test_config in list(config.values()):
            if not isinstance(test_config, dict):
                continue

            # For each test config interpolate the parameter if it is a string.
            for k, v in list(test_config.items()):
                merged_config = defaults.copy()
                merged_config.update(test_config)

                if isinstance(v, (str, unicode)):
                    v = v % merged_config
                    test_config[k] = v

        return utils.AttributeDict(config)
Example #4
0
    def DecodeFromJsonSafe(self, state, options):
        state = super(AttributeDictObjectRenderer,
                      self).DecodeFromJsonSafe(state, options)

        return utils.AttributeDict(state.get("data", {}))
Example #5
0
 def __init__(self, session=None, **kwargs):
     """Instantiate the plugin with the provided kwargs."""
     self.args = utils.AttributeDict(kwargs)
     self.session = session
     self.pool = threadpool.ThreadPool(self.args.processes)
Example #6
0
 def column_types(self):
     return dict(Result=utils.AttributeDict())
Example #7
0
    def __init__(self, *pos_args, **kwargs):
        self.ignore_required = kwargs.get("ignore_required", False)

        # If this is set we do not enforce required args. This is useful when
        # callers want to instantiate a plugin in order to use its methods as a
        # utility.
        if self.plugin_args is None:
            self.plugin_args = utils.AttributeDict()

        # Collect args in the declared order (basically follow the mro
        # backwards).
        definitions = []
        definitions_classes = {}
        for cls in self.__class__.__mro__:
            args_definition = getattr(cls, "_%s__args" % cls.__name__, [])
            for definition in args_definition:
                # Definitions can be just simple dicts.
                if isinstance(definition, dict):
                    definition = CommandOption(**definition)

                # We have seen this arg before.
                previous_definition = definitions_classes.get(definition.name)
                if previous_definition:
                    # Since we traverse the definition in reverse MRO order,
                    # later definitions should be masked by earlier (more
                    # derived) definitions.
                    continue

                definitions_classes[definition.name] = cls
                definitions.append(definition)

        # Handle positional args by consuming them off the pos_args array in
        # definition order. This allows positional args to be specified either
        # by position, or by keyword.
        positional_args = [x for x in definitions if x.positional]
        if len(positional_args) < len(pos_args):
            raise TypeError("Too many positional args provided.")

        for pos_arg, definition in zip(pos_args, positional_args):
            # If the positional arg is also defined as a keyword arg this is a
            # bug.
            if definition.name in kwargs:
                raise TypeError(
                    "Positional Args %s is also supplied as a keyword arg." %
                    definition.name)

            kwargs[definition.name] = pos_arg

        # Collect all the declared args and parse them.
        for definition in definitions:
            value = kwargs.pop(definition.name, None)
            if (value is None and definition.required
                    and not self.ignore_required):
                raise InvalidArgs("%s is required." % definition.name)

            # A sentinel means that the option is unset. We pass the
            # sentinel directly to the plugin so it can determine for
            # example, if the option was set at all or set to an empty
            # list on purpose. Without this behavior it is impossible
            # to specify e.g. pslist pids=[] to make pslist display no
            # pids as opposed to pslist pids=Sentienl to make pslist
            # ignore the pids arg.
            if isinstance(value, Sentinel):
                self.plugin_args[definition.name] = value
                continue

            try:
                self.plugin_args[definition.name] = definition.parse(
                    value, session=kwargs.get("session"))
            except (ValueError, TypeError) as e:
                raise InvalidArgs("%s invalid: %s." % (definition.name, e))

        super(ArgsParserMixin, self).__init__(**kwargs)
Example #8
0
def parse_args(argv=None, user_session=None, global_arg_cb=None):
    """Parse the args from the command line argv.

    Args:
      argv: The args to process.
      user_session: The session we work with.
      global_arg_cb: A callback that will be used to process global
         args. Global args are those which affect the state of the
         Rekall framework and must be processed prior to any plugin
         specific args. In essence these flags control which plugins
         can be available.
    """
    if argv is None:
        argv = sys.argv[1:]

    parser = RekallArgParser(
        description=constants.BANNER,
        conflict_handler='resolve',
        add_help=True,
        session=user_session,
        epilog="When no module is provided, drops into interactive mode",
        formatter_class=RekallHelpFormatter)

    # Parse the global and critical args from the command line.
    global_flags, unknown_flags = ParseGlobalArgs(parser, argv, user_session)
    if global_arg_cb:
        global_arg_cb(global_flags, unknown_flags)

    # The plugin name is taken from the command line, but it is not enough to
    # know which specific implementation will be used. For example there are 3
    # classes implementing the pslist plugin WinPsList, LinPsList and OSXPsList.
    plugin_name, argv = FindPlugin(argv, user_session)

    # Add all critical parameters. Critical parameters are those which are
    # common to all implementations of a certain plugin and are required in
    # order to choose from these implementations. For example, the profile or
    # filename are usually used to select the specific implementation of a
    # plugin.
    for metadata in user_session.plugins.plugin_db.MetadataByName(plugin_name):
        ConfigureCommandLineParser(metadata, parser, critical=True)

    # Parse the global and critical args from the command line.
    ParseGlobalArgs(parser, argv, user_session)

    # Find the specific implementation of the plugin that applies here. For
    # example, we have 3 different pslist implementations depending on the
    # specific profile loaded.
    command_metadata = user_session.plugins.Metadata(plugin_name)
    if not command_metadata:
        raise plugin.PluginError(
            "Plugin %s is not available for this configuration" % plugin_name)

    # Configure the arg parser for this command's options.
    plugin_cls = command_metadata.plugin_cls
    ConfigureCommandLineParser(command_metadata, parser)

    # We handle help especially.
    if global_flags.help:
        parser.print_help()
        sys.exit(-1)

    # Parse the final command line.
    result = parser.parse_args(argv)

    # Apply the defaults to the parsed args.
    result = utils.AttributeDict(vars(result))
    result.pop("__dummy", None)

    command_metadata.ApplyDefaults(result)

    return plugin_cls, result