Skip to content

Commit

Permalink
Added analysis counter to analysis report
Browse files Browse the repository at this point in the history
  • Loading branch information
joachimmetz committed Jan 17, 2021
1 parent 502268c commit a35c896
Show file tree
Hide file tree
Showing 13 changed files with 82 additions and 68 deletions.
6 changes: 3 additions & 3 deletions plaso/analysis/browser_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from plaso.analysis import interface
from plaso.analysis import logger
from plaso.analysis import manager
from plaso.containers import reports


class BrowserSearchPlugin(interface.AnalysisPlugin):
Expand Down Expand Up @@ -286,8 +285,9 @@ def CompileReport(self, mediator):

lines_of_text.append('')
report_text = '\n'.join(lines_of_text)
analysis_report = reports.AnalysisReport(
plugin_name=self.NAME, text=report_text)

analysis_report = super(BrowserSearchPlugin, self).CompileReport(mediator)
analysis_report.text = report_text
analysis_report.report_dict = results
return analysis_report

Expand Down
6 changes: 3 additions & 3 deletions plaso/analysis/chrome_extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from plaso.analysis import interface
from plaso.analysis import logger
from plaso.analysis import manager
from plaso.containers import reports


class ChromeExtensionPlugin(interface.AnalysisPlugin):
Expand Down Expand Up @@ -140,8 +139,9 @@ def CompileReport(self, mediator):

lines_of_text.append('')
report_text = '\n'.join(lines_of_text)
analysis_report = reports.AnalysisReport(
plugin_name=self.NAME, text=report_text)

analysis_report = super(ChromeExtensionPlugin, self).CompileReport(mediator)
analysis_report.text = report_text
analysis_report.report_dict = self._results
return analysis_report

Expand Down
5 changes: 3 additions & 2 deletions plaso/analysis/file_hashes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

from plaso.analysis import interface
from plaso.analysis import manager
from plaso.containers import reports


class FileHashesPlugin(interface.AnalysisPlugin):
Expand Down Expand Up @@ -94,7 +93,9 @@ def CompileReport(self, mediator):

lines_of_text.append('')
report_text = '\n'.join(lines_of_text)
return reports.AnalysisReport(plugin_name=self.NAME, text=report_text)
analysis_report = super(FileHashesPlugin, self).CompileReport(mediator)
analysis_report.text = report_text
return analysis_report


manager.AnalysisPluginManager.RegisterPlugin(FileHashesPlugin)
7 changes: 4 additions & 3 deletions plaso/analysis/hash_tagging.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from plaso.analysis import interface
from plaso.analysis import logger
from plaso.containers import events
from plaso.containers import reports
from plaso.lib import errors


Expand Down Expand Up @@ -228,8 +227,10 @@ def CompileReport(self, mediator):
for event_tag in tags:
mediator.ProduceEventTag(event_tag)

return reports.AnalysisReport(
plugin_name=self.NAME, text=report_text)
analysis_report = super(HashTaggingAnalysisPlugin, self).CompileReport(
mediator)
analysis_report.text = report_text
return analysis_report

def EstimateTimeRemaining(self):
"""Estimates how long until all hashes have been analyzed.
Expand Down
28 changes: 21 additions & 7 deletions plaso/analysis/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@
"""This file contains the interface for analysis plugins."""

import abc
import calendar
import collections
import time

from plaso.analysis import definitions
from plaso.analysis import definitions as analysis_definitions
from plaso.analysis import logger
from plaso.containers import events
from plaso.containers import reports
from plaso.lib import definitions


class AnalysisPlugin(object):
Expand All @@ -19,7 +24,8 @@ class AnalysisPlugin(object):
def __init__(self):
"""Initializes an analysis plugin."""
super(AnalysisPlugin, self).__init__()
self.plugin_type = definitions.PLUGIN_TYPE_REPORT
self._analysis_counter = collections.Counter()
self.plugin_type = analysis_definitions.PLUGIN_TYPE_REPORT

@property
def plugin_name(self):
Expand Down Expand Up @@ -48,14 +54,12 @@ def _CreateEventTag(self, event, labels):

return event_tag

# pylint: disable=redundant-returns-doc
@abc.abstractmethod
# pylint: disable=unused-argument
def CompileReport(self, mediator):
"""Compiles a report of the analysis.
After the plugin has received every copy of an event to
analyze this function will be called so that the report
can be assembled.
After the plugin has received every copy of an event to analyze this
function will be called so that the report can be assembled.
Args:
mediator (AnalysisMediator): mediates interactions between
Expand All @@ -64,6 +68,16 @@ def CompileReport(self, mediator):
Returns:
AnalysisReport: report.
"""
analysis_report = reports.AnalysisReport(plugin_name=self.NAME)

time_elements = time.gmtime()
time_compiled = calendar.timegm(time_elements)
analysis_report.time_compiled = (
time_compiled * definitions.MICROSECONDS_PER_SECOND)

analysis_report.analysis_counter = self._analysis_counter

return analysis_report

@abc.abstractmethod
def ExamineEvent(self, mediator, event, event_data, event_data_stream):
Expand Down
2 changes: 1 addition & 1 deletion plaso/analysis/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def GetAllPluginInformation(cls):
# TODO: Use a specific description variable, not the docstring.
doc_string, _, _ = plugin_class.__doc__.partition('\n')
type_string = cls._PLUGIN_TYPE_STRINGS.get(plugin_object.plugin_type)
information_tuple = (plugin_object.plugin_name, doc_string, type_string)
information_tuple = (plugin_object.NAME, doc_string, type_string)
results.append(information_tuple)

return sorted(results)
Expand Down
16 changes: 2 additions & 14 deletions plaso/analysis/mediator.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
# -*- coding: utf-8 -*-
"""The analysis plugin mediator object."""

import calendar
import time

from plaso.containers import warnings
from plaso.engine import path_helper
from plaso.lib import definitions


class AnalysisMediator(object):
Expand Down Expand Up @@ -99,20 +97,10 @@ def ProduceAnalysisReport(self, plugin):
"""
analysis_report = plugin.CompileReport(self)
if not analysis_report:
# TODO: produce AnalysisWarning that no report can be generated.
return

time_elements = time.gmtime()
time_compiled = (
calendar.timegm(time_elements) * definitions.MICROSECONDS_PER_SECOND)
analysis_report.time_compiled = time_compiled

plugin_name = getattr(analysis_report, 'plugin_name', plugin.plugin_name)
if plugin_name:
analysis_report.plugin_name = plugin_name

if self._event_filter_expression:
# TODO: rename filter string when refactoring the analysis reports.
analysis_report.filter_string = self._event_filter_expression
analysis_report.event_filter = self._event_filter_expression

self._storage_writer.AddAnalysisReport(analysis_report)

Expand Down
7 changes: 5 additions & 2 deletions plaso/analysis/sessionize.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

from plaso.analysis import interface
from plaso.analysis import manager
from plaso.containers import reports
from plaso.lib import definitions


Expand Down Expand Up @@ -51,7 +50,11 @@ def CompileReport(self, mediator):
report_text.append('\tSession {0:d}: {1:d} events'.format(
session, event_count))
report_text = '\n'.join(report_text)
return reports.AnalysisReport(plugin_name=self.NAME, text=report_text)

analysis_report = super(SessionizeAnalysisPlugin, self).CompileReport(
mediator)
analysis_report.text = report_text
return analysis_report

# pylint: disable=unused-argument
def ExamineEvent(self, mediator, event, event_data, event_data_stream):
Expand Down
35 changes: 11 additions & 24 deletions plaso/analysis/tagging.py
Original file line number Diff line number Diff line change
@@ -1,40 +1,23 @@
# -*- coding: utf-8 -*-
"""A plugin to tag events according to rules in a tagging file."""
"""Analysis plugin that labels events according to rules in a tagging file."""

from plaso.analysis import interface
from plaso.analysis import manager
from plaso.containers import reports
from plaso.engine import tagging_file


class TaggingAnalysisPlugin(interface.AnalysisPlugin):
"""Analysis plugin that tags events according to rules in a tagging file."""
"""Analysis plugin that labels events according to rules in a tagging file."""

NAME = 'tagging'

def __init__(self):
"""Initializes a tagging analysis plugin."""
super(TaggingAnalysisPlugin, self).__init__()
self._number_of_event_tags = 0
self._tagging_rules = None

def CompileReport(self, mediator):
"""Compiles an analysis report.
Args:
mediator (AnalysisMediator): mediates interactions between
analysis plugins and other components, such as storage and dfvfs.
Returns:
AnalysisReport: analysis report.
"""
report_text = 'Tagging plugin produced {0:d} tags.\n'.format(
self._number_of_event_tags)
self._number_of_event_tags = 0
return reports.AnalysisReport(plugin_name=self.NAME, text=report_text)

def ExamineEvent(self, mediator, event, event_data, event_data_stream):
"""Analyzes an EventObject and tags it according to rules in the tag file.
"""Labels events according to the rules in a tagging file.
Args:
mediator (AnalysisMediator): mediates interactions between analysis
Expand All @@ -56,16 +39,20 @@ def ExamineEvent(self, mediator, event, event_data, event_data_stream):
event_tag = self._CreateEventTag(event, matched_label_names)

mediator.ProduceEventTag(event_tag)
self._number_of_event_tags += 1

for label_name in matched_label_names:
self._analysis_counter[label_name] += 1

self._analysis_counter['event_tags'] += 1

def SetAndLoadTagFile(self, tagging_file_path):
"""Sets the tag file to be used by the plugin.
"""Sets the tagging file to be used by the plugin.
Args:
tagging_file_path (str): path of the tagging file.
"""
tag_file = tagging_file.TaggingFile(tagging_file_path)
self._tagging_rules = tag_file.GetEventTaggingRules()
tagging_file_object = tagging_file.TaggingFile(tagging_file_path)
self._tagging_rules = tagging_file_object.GetEventTaggingRules()


manager.AnalysisPluginManager.RegisterPlugin(TaggingAnalysisPlugin)
7 changes: 5 additions & 2 deletions plaso/analysis/unique_domains_visited.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

from plaso.analysis import interface
from plaso.analysis import manager
from plaso.containers import reports


class UniqueDomainsVisitedPlugin(interface.AnalysisPlugin):
Expand Down Expand Up @@ -80,7 +79,11 @@ def CompileReport(self, mediator):

lines_of_text.append('')
report_text = '\n'.join(lines_of_text)
return reports.AnalysisReport(plugin_name=self.NAME, text=report_text)

analysis_report = super(UniqueDomainsVisitedPlugin, self).CompileReport(
mediator)
analysis_report.text = report_text
return analysis_report


manager.AnalysisPluginManager.RegisterPlugin(UniqueDomainsVisitedPlugin)
7 changes: 5 additions & 2 deletions plaso/analysis/windows_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

from plaso.analysis import interface
from plaso.analysis import manager
from plaso.containers import reports
from plaso.parsers.winreg_plugins import services


Expand Down Expand Up @@ -264,7 +263,11 @@ def CompileReport(self, mediator):

lines_of_text.append('')
report_text = '\n'.join(lines_of_text)
return reports.AnalysisReport(plugin_name=self.NAME, text=report_text)

analysis_report = super(WindowsServicesAnalysisPlugin, self).CompileReport(
mediator)
analysis_report.text = report_text
return analysis_report

# pylint: disable=unused-argument
def ExamineEvent(self, mediator, event, event_data, event_data_stream):
Expand Down
16 changes: 12 additions & 4 deletions plaso/containers/reports.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ class AnalysisReport(interface.AttributeContainer):
"""Analysis report attribute container.
Attributes:
filter_string (str): event filter expression.
analysis_counter (collections.Counter): counter of analysis results, for
example number of events analyzed and tagged.
event_filter (str): event filter expression that was used when the analysis
plugin was run.
filter_string (str): deprecated variant of event_filter.
plugin_name (str): name of the analysis plugin that generated the report.
report_dict (dict[str]): ???
text (str): report text.
Expand All @@ -28,6 +32,9 @@ def __init__(self, plugin_name=None, text=None):
text (Optional[str]): report text.
"""
super(AnalysisReport, self).__init__()
self.analysis_counter = None
self.event_filter = None
# TODO: filter_string is deprecated remove at some point.
self.filter_string = None
self.plugin_name = plugin_name
self.report_dict = None
Expand Down Expand Up @@ -70,9 +77,10 @@ def GetString(self):
if filter_string:
string_list.append('Filter String: {0:s}'.format(filter_string))

string_list.append('')
string_list.append('Report text:')
string_list.append(self.text)
if self.text:
string_list.append('')
string_list.append('Report text:')
string_list.append(self.text)

return '\n'.join(string_list)

Expand Down
8 changes: 7 additions & 1 deletion tests/containers/reports.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@ def testGetAttributeNames(self):
attribute_container = reports.AnalysisReport()

expected_attribute_names = [
'filter_string', 'plugin_name', 'report_dict', 'text', 'time_compiled']
'analysis_counter',
'event_filter',
'filter_string',
'plugin_name',
'report_dict',
'text',
'time_compiled']

attribute_names = sorted(attribute_container.GetAttributeNames())

Expand Down

0 comments on commit a35c896

Please sign in to comment.