dissect.target.plugin

Dissect plugin system.

See dissect/target/plugins/general/example.py for an example plugin.

Module Contents

Classes

OperatingSystem

Sortable and serializible string-based enum

PluginDescriptor

FunctionDescriptor

FailureDescriptor

PluginDescriptorLookup

FunctionDescriptorLookup

PluginRegistry

Plugin

Base class for plugins.

OSPlugin

Base class for OS plugins.

ChildTargetPlugin

A Child target is a special plugin that can list more Targets.

NamespacePlugin

A namespace plugin provides services to access functionality from a group of subplugins.

InternalPlugin

Parent class for internal plugins.

InternalNamespacePlugin

A namespace plugin provides services to access functionality from a group of subplugins.

Functions

export

Decorator to be used on Plugin functions that should be exported.

internal

Decorator to be used on plugin functions that should be internal only.

arg

Decorator to be used on Plugin functions that accept additional command line arguments.

alias

Decorator to be used on Plugin functions to register an alias of that function.

clone_alias

Clone the given attribute to an alias in the provided class.

register

Register a plugin, and put related data inside PLUGINS.

plugins

Walk the plugin registry and return plugin descriptors.

os_plugins

Retrieve all OS plugin descriptors.

child_plugins

Retrieve all child plugin descriptors.

functions

Retrieve all function descriptors.

lookup

Lookup a function descriptor by function name.

load

Helper function that loads a plugin from a given function or plugin descriptor.

os_match

Check if a plugin descriptor is compatible with the target OS.

failed

Return all plugins that failed to load.

find_functions

Finds exported plugin functions that match the target and the patterns.

find_functions_by_record_field_type

Find functions that yield records with a specific field type.

generate

Internal function to generate the list of available plugins.

load_module_from_name

Load a module from module_path.

load_module_from_file

Loads a module from a file indicated by path relative to base_path.

load_modules_from_paths

Iterate over the paths and load all .py files.

get_external_module_paths

Return a list of external plugin directories.

environment_variable_paths

Return additional plugin directories specified by the DISSECT_PLUGINS environment variable.

Attributes

TypeAlias

log

MODULE_PATH

The base module path to the in-tree plugins.

OS_MODULE_PATH

OUTPUTS

The different output types supported by @export.

PLUGINS

The plugin registry.

GENERATED

__INTERNAL_PLUGIN_METHOD_NAMES__

dissect.target.plugin.TypeAlias
dissect.target.plugin.log
dissect.target.plugin.MODULE_PATH = 'dissect.target.plugins'

The base module path to the in-tree plugins.

dissect.target.plugin.OS_MODULE_PATH = 'dissect.target.plugins.os'
dissect.target.plugin.OUTPUTS = ('default', 'record', 'yield', 'none')

The different output types supported by @export.

class dissect.target.plugin.OperatingSystem

Bases: dissect.target.helpers.utils.StrEnum

Sortable and serializible string-based enum

ANDROID = 'android'
BSD = 'bsd'
CITRIX = 'citrix-netscaler'
ESXI = 'esxi'
FORTIOS = 'fortios'
IOS = 'ios'
LINUX = 'linux'
OSX = 'osx'
PROXMOX = 'proxmox'
UNIX = 'unix'
VYOS = 'vyos'
WINDOWS = 'windows'
class dissect.target.plugin.PluginDescriptor
__slots__ = ('module', 'qualname', 'namespace', 'path', 'findable', 'functions', 'exports')
module: str
qualname: str
namespace: str
path: str
findable: bool
functions: list[str]
exports: list[str]
property cls: type[Plugin]
class dissect.target.plugin.FunctionDescriptor
__slots__ = ('name', 'namespace', 'path', 'exported', 'internal', 'findable', 'alias', 'output',...
name: str
namespace: str
path: str
exported: bool
internal: bool
findable: bool
alias: bool
output: str | None
method_name: str
module: str
qualname: str
property cls: type[Plugin]
property func: Callable[Ellipsis, Any]
property record: flow.record.RecordDescriptor | list[flow.record.RecordDescriptor] | None
property args: list[tuple[list[str], dict[str, Any]]]
class dissect.target.plugin.FailureDescriptor
__slots__ = ('module', 'stacktrace')
module: str
stacktrace: list[str]
class dissect.target.plugin.PluginDescriptorLookup
__regular__: dict[str, PluginDescriptor]
__os__: dict[str, PluginDescriptor]
__child__: dict[str, PluginDescriptor]
class dissect.target.plugin.FunctionDescriptorLookup
__regular__: dict[str, dict[str, FunctionDescriptor]]
__os__: dict[str, dict[str, FunctionDescriptor]]
__child__: dict[str, dict[str, FunctionDescriptor]]
class dissect.target.plugin.PluginRegistry
__plugins__: PluginDescriptorLookup
__functions__: FunctionDescriptorLookup
__ostree__: _OSTree
__failed__: list[FailureDescriptor] = []
dissect.target.plugin.PLUGINS: PluginRegistry

The plugin registry.

Note: It’s very important that all values in this dictionary are serializable. The plugin registry can be stored in a file and loaded later. Plain Python syntax is used to store the registry. An exception is made for FailureDescriptor, FunctionDescriptor and PluginDescriptor.

dissect.target.plugin.GENERATED = False
dissect.target.plugin.export(*args, **kwargs) Callable[Ellipsis, Any]

Decorator to be used on Plugin functions that should be exported.

Supported keyword arguments:
property (bool): Whether this export should be regarded as a property.

Properties are implicitly cached.

cache (bool): Whether the result of this function should be cached.

record (RecordDescriptor): The flow.record.RecordDescriptor for the records that this function yields.

If multiple record types are yielded, specificy each descriptor in a list or tuple. If the records are dynamically made, use dissect.target.helpers.record.DynamicDescriptor() instead.

output (str): The output type of this function. Must be one of: - default: Single return value - record: Yields records. Implicit when record argument is given. - yield: Yields printable values. - none: No return value. Plugin is responsible for output formatting and should return None.

The export decorator adds some additional private attributes to an exported method or property: - __output__: The output type to expect for this function, this is the same as output. - __record__: The type of record to expect, this value is the same as record. - __exported__: set to True to indicate the method or property is exported.

Raises:

ValueError – if there was an invalid output type.

Returns:

An exported function from a plugin.

dissect.target.plugin.internal(*args, **kwargs) Callable[Ellipsis, Any]

Decorator to be used on plugin functions that should be internal only.

Making a plugin internal means that it’s only callable from the Python API and not through target-query.

This decorator adds the __internal__ private attribute to a method or property. The attribute is always set to True, to tell register() that it is an internal method or property.

dissect.target.plugin.arg(*args, **kwargs) Callable[Ellipsis, Any]

Decorator to be used on Plugin functions that accept additional command line arguments.

Command line arguments can be added using the @arg decorator. Arguments to this decorator are directly forwarded to the ArgumentParser.add_argument function of argparse. Resulting arguments are passed to the function using kwargs. The keyword argument name must match the argparse argument name.

This decorator adds the __args__ private attribute to a method or property. This attribute holds all the command line arguments that were added to the plugin function.

dissect.target.plugin.alias(*args, **kwargs: dict[str, Any]) Callable[Ellipsis, Any]

Decorator to be used on Plugin functions to register an alias of that function.

dissect.target.plugin.clone_alias(cls: type, attr: Callable[Ellipsis, Any], alias: str) None

Clone the given attribute to an alias in the provided class.

class dissect.target.plugin.Plugin(target: dissect.target.Target)

Base class for plugins.

Plugins can optionally be namespaced by specifying the __namespace__ class attribute. Namespacing results in your plugin needing to be prefixed with this namespace when being called. For example, if your plugin has specified test as namespace and a function called example, you must call your plugin with test.example.

A Plugin class has the following private class attributes:

  • __namespace__

  • __record_descriptors__

With the following two being assigned in register():

  • __functions__

  • __exports__

Additionally, the methods and attributes of Plugin receive more private attributes by using decorators.

The export() decorator adds the following private attributes

  • __exported__

  • __output__: Set with the export() decorator.

  • __record__: Set with the export() decorator.

The internal() decorator and InternalPlugin set the __internal__ attribute. Finally. args() decorator sets the __args__ attribute.

The alias() decorator populates the __aliases__ private attribute of Plugin methods. Resulting clones of the Plugin are populated with the boolean __alias__ attribute set to True.

Parameters:

target – The Target object to load the plugin for.

__namespace__: str = None

Defines the plugin namespace.

__record_descriptors__: list[flow.record.RecordDescriptor] = None

Defines a list of RecordDescriptor of the exported plugin functions.

__register__: bool = True

Determines whether this plugin will be registered.

__findable__: bool = True

Determines whether this plugin will be revealed when using search patterns.

Some (meta)-plugins are not very suitable for wild cards on CLI or plugin searches, because they will produce duplicate records or results. For instance a plugin that offers the same functions as subplugins will produce redundant results when used with a wild card (browser.* -> browser.history + browser.*.history).

__functions__: list[str]

Internal. A list of all method names decorated with @internal or @export.

__exports__: list[str]

Internal. A list of all method names decorated with @export.

classmethod __init_subclass__(**kwargs)
target
is_compatible() bool

Perform a compatibility check with the target.

abstract check_compatible() None

Perform a compatibility check with the target.

This function should return None if the plugin is compatible with the current target (self.target). For example, check if a certain file exists. Otherwise it should raise an UnsupportedPluginError.

Raises:

UnsupportedPluginError – If the plugin could not be loaded.

__call__(*args, **kwargs) Iterator[flow.record.Record | Any]

Return the records of all exported methods.

Raises:

PluginError – If the subclass is not a namespace plugin.

dissect.target.plugin.register(plugincls: type[Plugin]) None

Register a plugin, and put related data inside PLUGINS.

This function uses the following private attributes that are set using decorators:
Additionally, register sets the following private attributes on the plugincls:
  • __functions__: A list of all the methods and properties that are __internal__ or __exported__.

  • __exports__: A list of all the methods or properties that were explicitly exported.

If a plugincls __register__ attribute is set to False, the plugin will not be registered, but the plugin will still be processed for the private attributes mentioned above.

Parameters:

plugincls – A plugin class to register.

Raises:

ValueError – If plugincls is not a subclass of Plugin.

dissect.target.plugin.plugins(osfilter: type[OSPlugin] | None = None, *, index: str = '__regular__') Iterator[PluginDescriptor]

Walk the plugin registry and return plugin descriptors.

If osfilter is specified, only plugins related to the provided OSPlugin, or plugins with no OS relation are returned. If osfilter is None, all plugins will be returned.

One exception to this is if the osfilter is a (sub-)class of DefaultPlugin, then plugins are returned as if no osfilter was specified.

The index parameter can be used to specify the index to return plugins from. By default, this is set to return regular plugins. Other possible values are __os__ and __child__. These return OSPlugin and ChildTargetPlugin respectively.

Parameters:
  • osfilter – The optional OSPlugin to filter the returned plugins on.

  • index – The plugin index to return plugins from. Defaults to regular plugins.

Yields:

Plugin descriptors in the plugin registry based on the given filter criteria.

dissect.target.plugin.os_plugins() Iterator[PluginDescriptor]

Retrieve all OS plugin descriptors.

dissect.target.plugin.child_plugins() Iterator[PluginDescriptor]

Retrieve all child plugin descriptors.

dissect.target.plugin.functions(osfilter: type[OSPlugin] | None = None, *, index: str = '__regular__') Iterator[FunctionDescriptor]

Retrieve all function descriptors.

Parameters:
  • osfilter – The optional OSPlugin to filter the returned functions on.

  • index – The plugin index to return functions from. Defaults to regular functions.

Yields:

Function descriptors in the plugin registry based on the given filter criteria.

dissect.target.plugin.lookup(function_name: str, osfilter: type[OSPlugin] | None = None, *, index: str = '__regular__') Iterator[FunctionDescriptor]

Lookup a function descriptor by function name.

Parameters:
  • func_name – Function name to lookup.

  • osfilter – The optional OSPlugin to filter results with for compatibility.

  • index – The plugin index to return plugins from. Defaults to regular functions.

Yields:

Function descriptors that match the given function name and filter criteria.

dissect.target.plugin.load(desc: FunctionDescriptor | PluginDescriptor) type[Plugin]

Helper function that loads a plugin from a given function or plugin descriptor.

Parameters:

desc – Function descriptor as returned by plugin.lookup() or plugin descriptor as returned by plugin.plugins().

Returns:

The plugin class.

Raises:

PluginError – Raised when any other exception occurs while trying to load the plugin.

dissect.target.plugin.os_match(target: dissect.target.Target, descriptor: PluginDescriptor) bool

Check if a plugin descriptor is compatible with the target OS.

Parameters:
  • target – The target to check compatibility with.

  • descriptor – The plugin descriptor to check compatibility for.

dissect.target.plugin.failed() list[FailureDescriptor]

Return all plugins that failed to load.

dissect.target.plugin.find_functions(patterns: str, target: dissect.target.Target | None = None, compatibility: bool = False, ignore_load_errors: bool = False, show_hidden: bool = False) tuple[list[FunctionDescriptor], set[str]]

Finds exported plugin functions that match the target and the patterns.

Given a target, a comma separated list of patterns and an optional compatibility flag, this function finds matching plugins, optionally checking compatibility.

Returns:

A tuple containing a list of matching function descriptors and a set of invalid patterns.

dissect.target.plugin.find_functions_by_record_field_type(field_types: str | list[str], target: dissect.target.Target | None = None, compatibility: bool = False, ignore_load_errors: bool = False) Iterator[FunctionDescriptor]

Find functions that yield records with a specific field type.

Parameters:
  • field_types – The field type to search for.

  • target – The target to check compatibility with.

  • compatibility – Whether to check compatibility with the target.

  • ignore_load_errors – Whether to ignore load errors.

dissect.target.plugin.generate() dict[str, Any]

Internal function to generate the list of available plugins.

Walks the plugins directory and imports any .py files in there. Plugins will be automatically registered.

Returns:

The global PLUGINS dictionary.

dissect.target.plugin.load_module_from_name(module_path: str) None

Load a module from module_path.

dissect.target.plugin.load_module_from_file(path: pathlib.Path, base_path: pathlib.Path) None

Loads a module from a file indicated by path relative to base_path.

The module is added to sys.modules so it can be found everywhere.

Parameters:
  • path – The file to load as module.

  • base_path – The base directory of the module.

dissect.target.plugin.load_modules_from_paths(paths: list[pathlib.Path]) None

Iterate over the paths and load all .py files.

dissect.target.plugin.get_external_module_paths(path_list: list[pathlib.Path]) list[pathlib.Path]

Return a list of external plugin directories.

dissect.target.plugin.environment_variable_paths() list[pathlib.Path]

Return additional plugin directories specified by the DISSECT_PLUGINS environment variable.

class dissect.target.plugin.OSPlugin(target: dissect.target.Target)

Bases: Plugin

Base class for OS plugins.

This provides a base class for certain common functions of OS’s, which each OS plugin has to implement separately.

For example, it provides an interface for retrieving the hostname and users of a target.

All derived classes MUST implement ALL the classmethods and exported methods with the same @classmethod or @export(...) annotation.

classmethod __init_subclass__(**kwargs)
check_compatible() bool

OSPlugin’s use a different compatibility check, override the one from the Plugin class.

Returns:

This function always returns True.

classmethod detect(fs: dissect.target.filesystem.Filesystem) dissect.target.filesystem.Filesystem | None
Abstractmethod:

Provide detection of this OSPlugin on a given filesystem.

Parameters:

fsFilesystem to detect the OS on.

Returns:

The root filesystem / sysvol when found.

classmethod create(target: dissect.target.Target, sysvol: dissect.target.filesystem.Filesystem) OSPlugin
Abstractmethod:

Initiate this OSPlugin with the given target and detected filesystem.

Parameters:
  • target – The Target object.

  • sysvol – The filesystem that was detected in the detect() function.

Returns:

An instantiated version of the OSPlugin.

abstract hostname() str | None

Return the target’s hostname.

Returns:

The hostname as string.

abstract ips() list[str]

Return the IP addresses configured in the target.

Returns:

The IPs as list.

abstract version() str | None

Return the target’s OS version.

Returns:

The OS version as string.

abstract users() list[flow.record.Record]

Return the users available in the target.

Returns:

A list of user records.

abstract os() str

Return a slug of the target’s OS name.

Returns:

A slug of the OS name, e.g. ‘windows’ or ‘linux’.

abstract architecture() str | None

Return a slug of the target’s OS architecture.

Returns:

A slug of the OS architecture, e.g. ‘x86_32-unix’, ‘MIPS-linux’ or ‘AMD64-win32’, or ‘unknown’ if the architecture is unknown.

class dissect.target.plugin.ChildTargetPlugin(target: dissect.target.Target)

Bases: Plugin

A Child target is a special plugin that can list more Targets.

For example, ESXiChildTargetPlugin can list all of the Virtual Machines on the host.

__type__ = None
abstract list_children() Iterator[dissect.target.helpers.record.ChildTargetRecord]

Yield ChildTargetRecord records of all possible child targets on this target.

class dissect.target.plugin.NamespacePlugin(target: dissect.target.Target)

Bases: Plugin

A namespace plugin provides services to access functionality from a group of subplugins.

Support is currently limited to shared exported functions with output type record and yield.

classmethod __init_subclass__(**kwargs)
__init_subclass_subplugin__(**kwargs) None
check_compatible() None

Perform a compatibility check with the target.

This function should return None if the plugin is compatible with the current target (self.target). For example, check if a certain file exists. Otherwise it should raise an UnsupportedPluginError.

Raises:

UnsupportedPluginError – If the plugin could not be loaded.

dissect.target.plugin.__INTERNAL_PLUGIN_METHOD_NAMES__
class dissect.target.plugin.InternalPlugin(target: dissect.target.Target)

Bases: Plugin

Parent class for internal plugins.

InternalPlugin marks all non-private methods internal by default (same as @internal decorator).

classmethod __init_subclass__(**kwargs)
class dissect.target.plugin.InternalNamespacePlugin(target: dissect.target.Target)

Bases: NamespacePlugin, InternalPlugin

A namespace plugin provides services to access functionality from a group of subplugins.

Support is currently limited to shared exported functions with output type record and yield.