Skip to content

Commit

Permalink
Code review: 263060043: Refactored filters log2timeline#154
Browse files Browse the repository at this point in the history
  • Loading branch information
joachimmetz committed Dec 31, 2015
1 parent 01ad505 commit b9349f5
Show file tree
Hide file tree
Showing 30 changed files with 155 additions and 343 deletions.
2 changes: 1 addition & 1 deletion config/dpkg/changelog
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ python-plaso (1.3.1-1) unstable; urgency=low

* Auto-generated

-- Log2Timeline <[email protected]> Fri, 04 Sep 2015 12:45:13 +0200
-- Log2Timeline <[email protected]> Sat, 05 Sep 2015 19:14:12 +0200
2 changes: 1 addition & 1 deletion plaso/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
__version__ = '1.3.1'

VERSION_DEV = True
VERSION_DATE = '20150904'
VERSION_DATE = '20150905'


def GetVersion():
Expand Down
92 changes: 39 additions & 53 deletions plaso/frontend/preg.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,9 @@ def _GetRegistryTypes(self, plugin_name):
"""
types = set()
for plugin in self.GetRegistryPlugins(plugin_name):
for key_plugin_class in self._registry_plugin_list.GetAllKeyPlugins():
if plugin.NAME == key_plugin_class.NAME:
types.add(key_plugin_class.REG_TYPE)
for plugin_class in self._registry_plugin_list.GetAllPlugins():
if plugin.NAME == plugin_class.NAME:
types.add(plugin_class.REG_TYPE)
break

return list(types)
Expand All @@ -232,7 +232,7 @@ def _GetRegistryTypesFromPlugins(self, plugin_names):
registry_file_types = set()

for plugin_name in plugin_names:
for plugin_class in plugins_list.GetAllKeyPlugins():
for plugin_class in plugins_list.GetAllPlugins():
if plugin_name == plugin_class.NAME.lower():
# If a plugin is available for every Registry type
# we need to make sure all Registry files are included.
Expand Down Expand Up @@ -477,29 +477,29 @@ def GetRegistryHelpers(
helper for helper in self._GetRegistryHelperFromPath(path, codepage)])
return registry_helpers

def GetRegistryPlugins(self, plugin_name):
def GetRegistryPlugins(self, filter_string):
"""Retrieves the Windows Registry plugins based on a filter string.
Args:
plugin_name: string containing the name of the plugin or an empty
string for all the plugins.
filter_string: string containing the name of the plugin or an empty
string for all the plugins.
Returns:
A list of Windows Registry plugins (instance of RegistryPlugin).
"""
key_plugins = {}
for plugin in self._registry_plugin_list.GetAllKeyPlugins():
key_plugins[plugin.NAME] = plugin
plugins = {}
for plugin in self._registry_plugin_list.GetAllPlugins():
plugins[plugin.NAME] = plugin

if not plugin_name:
return key_plugins.values()
if not filter_string:
return plugins.values()

plugin_name = plugin_name.lower()
filter_string = filter_string.lower()

plugins_to_run = []
for key_plugin_name, key_plugin in iter(key_plugins.items()):
if plugin_name in key_plugin_name.lower():
plugins_to_run.append(key_plugin)
for plugin_name, plugin in iter(plugins.items()):
if filter_string in plugin_name.lower():
plugins_to_run.append(plugin)

return plugins_to_run

Expand All @@ -512,21 +512,21 @@ def GetRegistryPluginsFromRegistryType(self, registry_file_type):
Returns:
A list of Windows Registry plugins (instance of RegistryPlugin).
"""
key_plugins = {}
for plugin in self._registry_plugin_list.GetAllKeyPlugins():
key_plugins.setdefault(plugin.REG_TYPE.lower(), []).append(plugin)
plugins = {}
for plugin in self._registry_plugin_list.GetAllPlugins():
plugins.setdefault(plugin.REG_TYPE.lower(), []).append(plugin)

if not registry_file_type:
return key_plugins.values()
return plugins.values()

registry_file_type = registry_file_type.lower()

plugins_to_run = []
for key_plugin_type, key_plugin_list in iter(key_plugins.items()):
if registry_file_type == key_plugin_type:
plugins_to_run.extend(key_plugin_list)
elif key_plugin_type == u'any':
plugins_to_run.extend(key_plugin_list)
for plugin_type, plugin_list in iter(plugins.items()):
if registry_file_type == plugin_type:
plugins_to_run.extend(plugin_list)
elif plugin_type == u'any':
plugins_to_run.extend(plugin_list)

return plugins_to_run

Expand Down Expand Up @@ -605,47 +605,33 @@ def ParseRegistryKey(self, key, registry_helper, use_plugins=None):
A dictionary with plugin objects as keys and extracted event objects from
each plugin as values or an empty dict on error.
"""
return_dict = {}
if not registry_helper:
return return_dict
return {}

if isinstance(key, basestring):
key = registry_helper.GetKeyByPath(key)

if not key:
return return_dict

registry_file_type = registry_helper.file_type

plugins = {}
plugins_list = self._registry_plugin_list

# Compile a list of plugins we are about to use.
for weight in plugins_list.GetWeights():
plugin_list = plugins_list.GetPluginsByWeight(weight, registry_file_type)
plugins[weight] = []
for plugin in plugin_list:
plugin_object = plugin()
if use_plugins:
if plugin_object.NAME in use_plugins:
plugins[weight].append(plugin_object)
else:
plugins[weight].append(plugin_object)
return {}

event_queue = single_process.SingleProcessQueue()
event_queue_consumer = PregItemQueueConsumer(event_queue)

parser_mediator = self.CreateParserMediator(event_queue)
parser_mediator.SetFileEntry(registry_helper.file_entry)

for weight in plugins:
for plugin in plugins[weight]:
plugin.Process(parser_mediator, key=key)
event_queue_consumer.ConsumeItems()
event_objects = [
event_object for event_object in event_queue_consumer.GetItems()]
if event_objects:
return_dict[plugin] = event_objects
return_dict = {}
for plugin_object in self._registry_plugin_list.GetPluginObjects(
registry_helper.file_type):
if use_plugins and plugin_object.NAME not in use_plugins:
continue

plugin_object.Process(parser_mediator, key=key)
event_queue_consumer.ConsumeItems()
event_objects = [
event_object for event_object in event_queue_consumer.GetItems()]
if event_objects:
return_dict[plugin_object] = event_objects

return return_dict

Expand Down
147 changes: 39 additions & 108 deletions plaso/parsers/winreg.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,12 @@ class PluginList(object):
def __init__(self):
"""Initializes the plugin list object."""
super(PluginList, self).__init__()
self._key_plugins = {}
self._value_plugins = {}
self._plugins = {}

def __iter__(self):
"""Return an iterator of all Windows Registry plugins."""
ret = []
_ = map(ret.extend, self._key_plugins.values())
_ = map(ret.extend, self._value_plugins.values())
_ = map(ret.extend, self._plugins.values())
for item in ret:
yield item

Expand Down Expand Up @@ -52,25 +50,12 @@ def AddPlugin(self, registry_file_type, plugin_class):
e.g. NTUSER, SOFTWARE.
plugin_class: The plugin class that is being registered.
"""
# Cannot import the interface here otherwise this will create a cyclic
# dependency.
if hasattr(plugin_class, u'REG_VALUES'):
self._value_plugins.setdefault(
registry_file_type, []).append(plugin_class)
self._plugins.setdefault(registry_file_type, []).append(plugin_class)

else:
self._key_plugins.setdefault(registry_file_type, []).append(plugin_class)

def GetAllKeyPlugins(self):
def GetAllPlugins(self):
"""Return all key plugins as a list."""
ret = []
_ = map(ret.extend, self._key_plugins.values())
return ret

def GetAllValuePlugins(self):
"""Return a list of a all classes that implement value-based plugins."""
ret = []
_ = map(ret.extend, self._value_plugins.values())
_ = map(ret.extend, self._plugins.values())
return ret

def GetExpandedKeyPaths(self, parser_mediator, plugin_names=None):
Expand All @@ -86,104 +71,65 @@ def GetExpandedKeyPaths(self, parser_mediator, plugin_names=None):
A list of expanded Windows Registry key paths.
"""
key_paths = []
for key_plugin_cls in self.GetAllKeyPlugins():
key_plugin = key_plugin_cls()
for plugin_cls in self.GetAllPlugins():
plugin_object = plugin_cls()

if plugin_names and key_plugin.NAME not in plugin_names:
if plugin_names and plugin_object.NAME not in plugin_names:
continue
key_plugin.ExpandKeys(parser_mediator)
if not key_plugin.expanded_keys:
plugin_object.ExpandKeys(parser_mediator)
if not plugin_object.expanded_keys:
continue

for key_path in key_plugin.expanded_keys:
for key_path in plugin_object.expanded_keys:
if key_path not in key_paths:
key_paths.append(key_path)

return key_paths

def GetKeyPluginByName(self, registry_file_type, plugin_name):
"""Retrieves a Windows Registry key-based plugin for a specific name.
def GetPluginObjectByName(self, registry_file_type, plugin_name):
"""Creates a new instance of a specific Windows Registry plugin.
Args:
registry_file_type: string containing the Windows Registry file type,
registry_file_type: String containing the Windows Registry file type,
e.g. NTUSER, SOFTWARE.
plugin_name: the name of the plugin.
Returns:
The Windows Registry plugin (instance of RegistryPlugin) or None.
"""
# TODO: make this a dict lookup instead of a list iteration.
for plugin_cls in self.GetKeyPlugins(registry_file_type):
for plugin_cls in self.GetPlugins(registry_file_type):
if plugin_cls.NAME == plugin_name:
return plugin_cls()

def GetKeyPlugins(self, registry_file_type):
"""Retrieves the Windows Registry key-based plugins of a specific type.
def GetPluginObjects(self, registry_file_type):
"""Creates new instances of a specific type of Windows Registry plugins.
Args:
registry_file_type: string containing the Windows Registry file type,
registry_file_type: String containing the Windows Registry file type,
e.g. NTUSER, SOFTWARE.
Returns:
A list containing the Windows Registry plugins (instances of
RegistryPlugin) for the specific plugin type.
"""
return self._GetPluginsByType(self._key_plugins, registry_file_type)

def GetPluginsByWeight(self, weight, registry_file_type=u''):
"""Return a list of all plugins for a given weight or priority.
Each plugin defines a weight or a priority that defines in which order
it should be processed in the case of a parser that applies priority.
This method returns all plugins, whether they are key or value based
that use a defined weight or priority and are defined to parse keys
or values found in a certain Windows Registry type.
Args:
weight: An integer representing the weight or priority (usually a
number from 1 to 3).
registry_file_type: Optional string containing the Windows Registry
file type, e.g. NTUSER, SOFTWARE. The default is
an empty string that represents to return plugins
of all available Registry file types.
Returns:
A list of all plugins (instances of RegistryPlugin) that fit the defined
criteria.
The Windows Registry plugin (instance of RegistryPlugin) or None.
"""
ret = []
for reg_plugin in self.GetKeyPlugins(registry_file_type):
if reg_plugin.WEIGHT == weight:
ret.append(reg_plugin)

for reg_plugin in self.GetValuePlugins(registry_file_type):
if reg_plugin.WEIGHT == weight:
ret.append(reg_plugin)

return ret

def GetTypes(self):
"""Return a set of all plugins supported."""
return set(self._key_plugins).union(self._value_plugins)
return [plugin_cls() for plugin_cls in self.GetPlugins(registry_file_type)]

def GetValuePlugins(self, registry_file_type):
"""Retrieves the Windows Registry value-based plugins of a specific type.
def GetPlugins(self, registry_file_type):
"""Retrieves the Windows Registry key-based plugins of a specific type.
Args:
registry_file_type: string containing the Windows Registry file type,
registry_file_type: String containing the Windows Registry file type,
e.g. NTUSER, SOFTWARE.
Returns:
A list containing the Windows Registry plugins (instances of
A list containing the Windows Registry plugins (types of
RegistryPlugin) for the specific plugin type.
"""
return self._GetPluginsByType(self._value_plugins, registry_file_type)
return self._GetPluginsByType(self._plugins, registry_file_type)

def GetWeights(self):
"""Return a set of all weights/priority of the loaded plugins."""
return set(plugin.WEIGHT for plugin in self.GetAllValuePlugins()).union(
plugin.WEIGHT for plugin in self.GetAllKeyPlugins())
def GetTypes(self):
"""Return a set of all plugins supported."""
return set(self._plugins)


class WinRegistryParser(interface.BaseParser):
Expand Down Expand Up @@ -226,42 +172,27 @@ def _ParseRegistryFile(
Args:
parser_mediator: A parser mediator object (instance of ParserMediator).
winreg_file: A Windows Registry file (instance of dfwinreg.WinRegFile).
registry_file_type: String containing the Windows Registry file type,
e.g. NTUSER, SOFTWARE.
registry_file_type: The Registry file type.
"""
# TODO: move to separate function.
plugins = {}
number_of_plugins = 0
for weight in self._plugins.GetWeights():
plugins_list = self._plugins.GetPluginsByWeight(
weight, registry_file_type)
plugins[weight] = []
for plugin_class in plugins_list:
plugin_object = plugin_class()
plugins[weight].append(plugin_object)
number_of_plugins += 1

plugins = self._plugins.GetPluginObjects(registry_file_type)
logging.debug(
u'Number of plugins for this Windows Registry file: {0:d}.'.format(
number_of_plugins))
len(plugins)))

# Recurse through keys in the file and apply the plugins in the order:
# 1. file type specific key-based plugins.
# 2. generic key-based plugins.
# 3. file type specific value-based plugins.
# 4. generic value-based plugins.
# 1. file type specific plugins.
# 2. generic plugins.

for key in winreg_file.RecurseKeys():
for weight in iter(plugins.keys()):
for plugin_object in plugins:
# TODO: determine if the plugin matches the key and continue
# to the next key.
for plugin in plugins[weight]:
if parser_mediator.abort:
break
if parser_mediator.abort:
break

plugin.UpdateChainAndProcess(
parser_mediator, key=key, registry_file_type=registry_file_type,
codepage=parser_mediator.codepage)
plugin_object.UpdateChainAndProcess(
parser_mediator, key=key, registry_file_type=registry_file_type,
codepage=parser_mediator.codepage)

@classmethod
def GetFormatSpecification(cls):
Expand Down
Loading

0 comments on commit b9349f5

Please sign in to comment.