Import from old repository

This commit is contained in:
Stefan
2020-04-06 18:48:34 +02:00
commit 0da6783a45
762 changed files with 103065 additions and 0 deletions
+20
View File
@@ -0,0 +1,20 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2014 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""This file contains import statements for the ESE database plugins."""
from plaso.parsers.esedb_plugins import msie_webcache
+303
View File
@@ -0,0 +1,303 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2014 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""This file contains the interface for ESE database plugins."""
import construct
import logging
import pyesedb
from plaso.lib import errors
from plaso.parsers import plugins
class EseDbPlugin(plugins.BasePlugin):
"""The ESE database plugin interface."""
NAME = 'esedb'
BINARY_DATA_COLUMN_TYPES = frozenset([
pyesedb.column_types.BINARY_DATA,
pyesedb.column_types.LARGE_BINARY_DATA])
FLOATING_POINT_COLUMN_TYPES = frozenset([
pyesedb.column_types.FLOAT_32BIT,
pyesedb.column_types.DOUBLE_64BIT])
INTEGER_COLUMN_TYPES = frozenset([
pyesedb.column_types.CURRENCY,
pyesedb.column_types.DATE_TIME,
pyesedb.column_types.INTEGER_8BIT_UNSIGNED,
pyesedb.column_types.INTEGER_16BIT_SIGNED,
pyesedb.column_types.INTEGER_16BIT_UNSIGNED,
pyesedb.column_types.INTEGER_32BIT_SIGNED,
pyesedb.column_types.INTEGER_32BIT_UNSIGNED,
pyesedb.column_types.INTEGER_64BIT_SIGNED])
STRING_COLUMN_TYPES = frozenset([
pyesedb.column_types.TEXT,
pyesedb.column_types.LARGE_TEXT])
_UINT64_BIG_ENDIAN = construct.UBInt64('value')
_UINT64_LITTLE_ENDIAN = construct.ULInt64('value')
# Dictionary containing a callback method per table name.
# E.g. 'SystemIndex_0A': 'ParseSystemIndex_0A'
REQUIRED_TABLES = {}
OPTIONAL_TABLES = {}
def __init__(self):
"""Initializes the ESE database plugin."""
super(EseDbPlugin, self).__init__()
self._required_tables = frozenset(self.REQUIRED_TABLES.keys())
self._tables = {}
self._tables.update(self.REQUIRED_TABLES)
self._tables.update(self.OPTIONAL_TABLES)
def _ConvertValueBinaryDataToStringAscii(self, value):
"""Converts a binary data value into a string.
Args:
value: The binary data value containing an ASCII string or None.
Returns:
A string or None if value is None.
"""
if value:
return value.decode('ascii')
def _ConvertValueBinaryDataToStringBase16(self, value):
"""Converts a binary data value into a base-16 (hexadecimal) string.
Args:
value: The binary data value or None.
Returns:
A string or None if value is None.
"""
if value:
return value.encode('hex')
def _ConvertValueBinaryDataToUBInt64(self, value):
"""Converts a binary data value into an integer.
Args:
value: The binary data value containing an unsigned 64-bit big-endian
integer.
Returns:
An integer or None if value is None.
"""
if value:
return self._UINT64_BIG_ENDIAN.parse(value)
def _ConvertValueBinaryDataToULInt64(self, value):
"""Converts a binary data value into an integer.
Args:
value: The binary data value containing an unsigned 64-bit little-endian
integer.
Returns:
An integer or None if value is None.
"""
if value:
return self._UINT64_LITTLE_ENDIAN.parse(value)
def _GetRecordValue(self, record, value_entry):
"""Retrieves a specific value from the record.
Args:
record: The ESE record object (instance of pyesedb.record).
value_entry: The value entry.
Returns:
An object containing the value.
"""
column_type = record.get_column_type(value_entry)
value_data_flags = record.get_value_data_flags(value_entry)
if value_data_flags & pyesedb.value_flags.MULTI_VALUE:
# TODO: implement
pass
elif column_type == pyesedb.column_types.NULL:
return
elif column_type == pyesedb.column_types.BOOLEAN:
# TODO: implement
pass
elif column_type in self.INTEGER_COLUMN_TYPES:
return record.get_value_data_as_integer(value_entry)
elif column_type in self.FLOATING_POINT_COLUMN_TYPES:
return record.get_value_data_as_floating_point(value_entry)
elif column_type in self.STRING_COLUMN_TYPES:
return record.get_value_data_as_string(value_entry)
elif column_type == pyesedb.column_types.GUID:
# TODO: implement
pass
return record.get_value_data(value_entry)
def _GetRecordValues(self, table_name, record, value_mappings=None):
"""Retrieves the values from the record.
Args:
table_name: The name of the table.
record: The ESE record object (instance of pyesedb.record).
value_mappings: Optional dict of value mappings, which map the column
name to a callback method. The default is None.
Returns:
An dict containing the values.
"""
record_values = {}
for value_entry in range(0, record.number_of_values):
column_name = record.get_column_name(value_entry)
if column_name in record_values:
logging.warning(
u'[{0:s}] duplicate column: {1:s} in table: {2:s}'.format(
self.NAME, column_name, table_name))
continue
value_callback = None
if value_mappings and column_name in value_mappings:
value_callback_method = value_mappings.get(column_name)
if value_callback_method:
value_callback = getattr(self, value_callback_method, None)
if value_callback is None:
logging.warning((
u'[{0:s}] missing value callback method: {1:s} for column: '
u'{2:s} in table: {3:s}').format(
self.NAME, value_callback_method, column_name, table_name))
value = self._GetRecordValue(record, value_entry)
if value_callback:
value = value_callback(value)
record_values[column_name] = value
return record_values
def _GetTableNames(self, database):
"""Retrieves the table names in a database.
Args:
database: The ESE database object (instance of pyesedb.file).
Returns:
A list of the table names.
"""
table_names = []
for esedb_table in database.tables:
table_names.append(esedb_table.name)
return table_names
def GetEntries(
self, parser_context, file_entry=None, parser_chain=None, database=None,
cache=None, **kwargs):
"""Extracts event objects from the database.
Args:
parser_context: A parser context object (instance of ParserContext).
file_entry: Optional file entry object (instance of dfvfs.FileEntry).
The default is None.
parser_chain: Optional string containing the parsing chain up to this
point. The default is None.
database: Optional ESE database object (instance of pyesedb.file).
The default is None.
cache: Optional cache object (instance of EseDbCache). The default is
None.
Raises:
ValueError: If the database attribute is not valid.
"""
if database is None:
raise ValueError(u'Invalid database.')
for table_name, callback_method in self._tables.iteritems():
if not callback_method:
# Table names without a callback method are allowed to improve
# the detection of a database based on its table names.
continue
callback = getattr(self, callback_method, None)
if callback is None:
logging.warning(
u'[{0:s}] missing callback method: {1:s} for table: {2:s}'.format(
self.NAME, callback_method, table_name))
continue
esedb_table = database.get_table_by_name(table_name)
if not esedb_table:
logging.warning(u'[{0:s}] missing table: {1:s}'.format(
self.NAME, table_name))
continue
# The database is passed in case the database contains table names
# that are assigned dynamically and cannot be defined by
# the table name-callback mechanism.
callback(
parser_context, file_entry=file_entry, parser_chain=parser_chain,
database=database, table=esedb_table, cache=cache, **kwargs)
def Process(
self, parser_context, file_entry=None, parser_chain=None, database=None,
cache=None, **kwargs):
"""Determines if this is the appropriate plugin for the database.
Args:
parser_context: A parser context object (instance of ParserContext).
file_entry: Optional file entry object (instance of dfvfs.FileEntry).
The default is None.
parser_chain: Optional string containing the parsing chain up to this
point. The default is None.
database: Optional ESE database object (instance of pyesedb.file).
The default is None.
cache: Optional cache object (instance of EseDbCache). The default is
None.
Raises:
errors.WrongPlugin: If the database does not contain all the tables
defined in the required_tables set.
ValueError: If the database attribute is not valid.
"""
if database is None:
raise ValueError(u'Invalid database.')
table_names = frozenset(self._GetTableNames(database))
if self._required_tables.difference(table_names):
raise errors.WrongPlugin(
u'[{0:s}] required tables not found.'.format(self.NAME))
# This will raise if unhandled keyword arguments are passed.
super(EseDbPlugin, self).Process(parser_context, **kwargs)
# Add ourselves to the parser chain, which will be used in all subsequent
# event creation in this parser.
parser_chain = self._BuildParserChain(parser_chain)
self.GetEntries(
parser_context, file_entry=file_entry, parser_chain=parser_chain,
database=database, cache=cache, **kwargs)
@@ -0,0 +1,366 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2014 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Parser for the Microsoft Internet Explorer WebCache ESE database.
The WebCache database (WebCacheV01.dat or WebCacheV24.dat) are used by MSIE
as of version 10.
"""
import logging
from plaso.events import time_events
from plaso.lib import eventdata
from plaso.parsers import esedb
from plaso.parsers.esedb_plugins import interface
class MsieWebCacheContainersEventObject(time_events.FiletimeEvent):
"""Convenience class for a MSIE WebCache Containers table event."""
DATA_TYPE = 'msie:webcache:containers'
def __init__(self, timestamp, usage, record_values):
"""Initializes the event.
Args:
timestamp: The FILETIME timestamp value.
usage: The usage string, describing the timestamp value.
record_values: A dict object containing the record values.
"""
super(MsieWebCacheContainersEventObject, self).__init__(timestamp, usage)
self.container_identifier = record_values.get('ContainerId', 0)
self.set_identifier = record_values.get('SetId', 0)
self.name = record_values.get('Name', u'')
self.directory = record_values.get('Directory', u'')
class MsieWebCacheContainerEventObject(time_events.FiletimeEvent):
"""Convenience class for a MSIE WebCache Container table event."""
DATA_TYPE = 'msie:webcache:container'
def __init__(self, timestamp, usage, record_values):
"""Initializes the event.
Args:
timestamp: The FILETIME timestamp value.
usage: The usage string, describing the timestamp value.
record_values: A dict object containing the record values.
"""
super(MsieWebCacheContainerEventObject, self).__init__(timestamp, usage)
self.entry_identifier = record_values.get(u'EntryId', 0)
self.container_identifier = record_values.get(u'ContainerId', 0)
self.cache_identifier = record_values.get(u'CacheId', 0)
url = record_values.get(u'Url', u'')
# Ignore URL that start with a binary value.
if ord(url[0]) >= 0x20:
self.url = url
self.redirect_url = record_values.get(u'RedirectUrl', u'')
self.access_count = record_values.get(u'AccessCount', 0)
self.sync_count = record_values.get(u'SyncCount', 0)
self.cached_filename = record_values.get('Filename', u'')
self.file_extension = record_values.get(u'FileExtension', u'')
self.cached_file_size = record_values.get(u'FileSize', 0)
# Ignore non-Unicode request headers values.
request_headers = record_values.get(u'RequestHeaders', u'')
if type(request_headers) == unicode and request_headers:
self.request_headers = request_headers
# Ignore non-Unicode response headers values.
response_headers = record_values.get(u'ResponseHeaders', u'')
if type(response_headers) == unicode and response_headers:
self.response_headers = response_headers
class MsieWebCacheLeakFilesEventObject(time_events.FiletimeEvent):
"""Convenience class for a MSIE WebCache LeakFiles table event."""
DATA_TYPE = 'msie:webcache:leak_file'
def __init__(self, timestamp, usage, record_values):
"""Initializes the event.
Args:
timestamp: The FILETIME timestamp value.
usage: The usage string, describing the timestamp value.
record_values: A dict object containing the record values.
"""
super(MsieWebCacheLeakFilesEventObject, self).__init__(timestamp, usage)
self.leak_identifier = record_values.get('LeakId', 0)
self.cached_filename = record_values.get('Filename', u'')
class MsieWebCachePartitionsEventObject(time_events.FiletimeEvent):
"""Convenience class for a MSIE WebCache Partitions table event."""
DATA_TYPE = 'msie:webcache:partitions'
def __init__(self, timestamp, usage, record_values):
"""Initializes the event.
Args:
timestamp: The FILETIME timestamp value.
usage: The usage string, describing the timestamp value.
record_values: A dict object containing the record values.
"""
super(MsieWebCachePartitionsEventObject, self).__init__(timestamp, usage)
self.partition_identifier = record_values.get('PartitionId', 0)
self.partition_type = record_values.get('PartitionType', 0)
self.directory = record_values.get('Directory', u'')
self.table_identifier = record_values.get('TableId', 0)
class MsieWebCacheEseDbPlugin(interface.EseDbPlugin):
"""Parses a MSIE WebCache ESE database file."""
NAME = 'msie_webcache'
DESCRIPTION = u'Parser for MSIE WebCache ESE database files.'
# TODO: add support for AppCache_#, AppCacheEntry_#, DependencyEntry_#
REQUIRED_TABLES = {
'Containers': 'ParseContainersTable',
'LeakFiles': 'ParseLeakFilesTable',
'Partitions': 'ParsePartitionsTable'}
_CONTAINER_TABLE_VALUE_MAPPINGS = {
'RequestHeaders': '_ConvertValueBinaryDataToStringAscii',
'ResponseHeaders': '_ConvertValueBinaryDataToStringAscii'}
def _ParseContainerTable(
self, parser_context, file_entry=None, parser_chain=None, table=None,
container_name=u'Unknown'):
"""Parses a Container_# table.
Args:
parser_context: A parser context object (instance of ParserContext).
file_entry: Optional file entry object (instance of dfvfs.FileEntry).
parser_chain: Optional string containing the parsing chain up to this
point.
table: Optional table object (instance of pyesedb.table).
container_name: Optional string that contains the container name.
The container name indicates the table type.
The default is a string containing 'Unknown'.
"""
if table is None:
logging.warning(u'[{0:s}] invalid Container_# table'.format(self.NAME))
return
for esedb_record in table.records:
# TODO: add support for:
# wpnidm, iecompat, iecompatua, DNTException, DOMStore
if container_name == u'Content':
value_mappings = self._CONTAINER_TABLE_VALUE_MAPPINGS
else:
value_mappings = None
try:
record_values = self._GetRecordValues(
table.name, esedb_record, value_mappings=value_mappings)
except UnicodeDecodeError as exception:
logging.error((
u'[{0:s}] Unable to return record values for {1:s} with error: '
u'{2:s}').format(
parser_chain,
file_entry.path_spec.comparable.replace(u'\n', u';'),
exception))
continue
if (container_name in [
u'Content', u'Cookies', u'History', u'iedownload'] or
container_name.startswith(u'MSHist')):
timestamp = record_values.get(u'SyncTime', 0)
if timestamp:
event_object = MsieWebCacheContainerEventObject(
timestamp, u'Synchronization time', record_values)
parser_context.ProduceEvent(
event_object, parser_chain=parser_chain, file_entry=file_entry)
timestamp = record_values.get(u'CreationTime', 0)
if timestamp:
event_object = MsieWebCacheContainerEventObject(
timestamp, eventdata.EventTimestamp.CREATION_TIME, record_values)
parser_context.ProduceEvent(
event_object, parser_chain=parser_chain, file_entry=file_entry)
timestamp = record_values.get(u'ExpiryTime', 0)
if timestamp:
event_object = MsieWebCacheContainerEventObject(
timestamp, eventdata.EventTimestamp.EXPIRATION_TIME,
record_values)
parser_context.ProduceEvent(
event_object, parser_chain=parser_chain, file_entry=file_entry)
timestamp = record_values.get(u'ModifiedTime', 0)
if timestamp:
event_object = MsieWebCacheContainerEventObject(
timestamp, eventdata.EventTimestamp.MODIFICATION_TIME,
record_values)
parser_context.ProduceEvent(
event_object, parser_chain=parser_chain, file_entry=file_entry)
timestamp = record_values.get(u'AccessedTime', 0)
if timestamp:
event_object = MsieWebCacheContainerEventObject(
timestamp, eventdata.EventTimestamp.ACCESS_TIME, record_values)
parser_context.ProduceEvent(
event_object, parser_chain=parser_chain, file_entry=file_entry)
timestamp = record_values.get(u'PostCheckTime', 0)
if timestamp:
event_object = MsieWebCacheContainerEventObject(
timestamp, u'Post check time', record_values)
parser_context.ProduceEvent(
event_object, parser_chain=parser_chain, file_entry=file_entry)
def ParseContainersTable(
self, parser_context, file_entry=None, parser_chain=None, database=None,
table=None, **unused_kwargs):
"""Parses the Containers table.
Args:
parser_context: A parser context object (instance of ParserContext).
file_entry: Optional file entry object (instance of dfvfs.FileEntry).
The default is None.
parser_chain: Optional string containing the parsing chain up to this
point. The default is None.
database: Optional database object (instance of pyesedb.file).
The default is None.
table: Optional table object (instance of pyesedb.table).
The default is None.
"""
if database is None:
logging.warning(u'[{0:s}] invalid database'.format(self.NAME))
return
if table is None:
logging.warning(u'[{0:s}] invalid Containers table'.format(self.NAME))
return
for esedb_record in table.records:
record_values = self._GetRecordValues(table.name, esedb_record)
timestamp = record_values.get(u'LastScavengeTime', 0)
if timestamp:
event_object = MsieWebCacheContainersEventObject(
timestamp, u'Last Scavenge Time', record_values)
parser_context.ProduceEvent(
event_object, parser_chain=parser_chain, file_entry=file_entry)
timestamp = record_values.get(u'LastAccessTime', 0)
if timestamp:
event_object = MsieWebCacheContainersEventObject(
timestamp, eventdata.EventTimestamp.ACCESS_TIME, record_values)
parser_context.ProduceEvent(
event_object, parser_chain=parser_chain, file_entry=file_entry)
container_identifier = record_values.get(u'ContainerId', None)
container_name = record_values.get(u'Name', None)
if not container_identifier or not container_name:
continue
table_name = u'Container_{0:d}'.format(container_identifier)
esedb_table = database.get_table_by_name(table_name)
if not esedb_table:
logging.warning(
u'[{0:s}] missing table: {1:s}'.format(self.NAME, table_name))
continue
self._ParseContainerTable(
parser_context, file_entry=file_entry, parser_chain=parser_chain,
table=esedb_table, container_name=container_name)
def ParseLeakFilesTable(
self, parser_context, file_entry=None, parser_chain=None, database=None,
table=None, **unused_kwargs):
"""Parses the LeakFiles table.
Args:
parser_context: A parser context object (instance of ParserContext).
file_entry: Optional file entry object (instance of dfvfs.FileEntry).
The default is None.
parser_chain: Optional string containing the parsing chain up to this
point. The default is None.
database: Optional database object (instance of pyesedb.file).
The default is None.
table: Optional table object (instance of pyesedb.table).
The default is None.
"""
if database is None:
logging.warning(u'[{0:s}] invalid database'.format(self.NAME))
return
if table is None:
logging.warning(u'[{0:s}] invalid LeakFiles table'.format(self.NAME))
return
for esedb_record in table.records:
record_values = self._GetRecordValues(table.name, esedb_record)
timestamp = record_values.get(u'CreationTime', 0)
if timestamp:
event_object = MsieWebCacheLeakFilesEventObject(
timestamp, eventdata.EventTimestamp.CREATION_TIME, record_values)
parser_context.ProduceEvent(
event_object, parser_chain=parser_chain, file_entry=file_entry)
def ParsePartitionsTable(
self, parser_context, file_entry=None, parser_chain=None, database=None,
table=None, **unused_kwargs):
"""Parses the Partitions table.
Args:
parser_context: A parser context object (instance of ParserContext).
file_entry: Optional file entry object (instance of dfvfs.FileEntry).
The default is None.
parser_chain: Optional string containing the parsing chain up to this
point. The default is None.
database: Optional database object (instance of pyesedb.file).
The default is None.
table: Optional table object (instance of pyesedb.table).
The default is None.
"""
if database is None:
logging.warning(u'[{0:s}] invalid database'.format(self.NAME))
return
if table is None:
logging.warning(u'[{0:s}] invalid Partitions table'.format(self.NAME))
return
for esedb_record in table.records:
record_values = self._GetRecordValues(table.name, esedb_record)
timestamp = record_values.get(u'LastScavengeTime', 0)
if timestamp:
event_object = MsieWebCachePartitionsEventObject(
timestamp, u'Last Scavenge Time', record_values)
parser_context.ProduceEvent(
event_object, parser_chain=parser_chain, file_entry=file_entry)
esedb.EseDbParser.RegisterPlugin(MsieWebCacheEseDbPlugin)
@@ -0,0 +1,71 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2014 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests for the Microsoft Internet Explorer WebCache database."""
import unittest
# pylint: disable=unused-import
from plaso.formatters import msie_webcache as msie_webcache_formatter
from plaso.lib import eventdata
from plaso.lib import timelib_test
from plaso.parsers.esedb_plugins import msie_webcache
from plaso.parsers.esedb_plugins import test_lib
class MsieWebCacheEseDbPluginTest(test_lib.EseDbPluginTestCase):
"""Tests for the MSIE WebCache ESE database plugin."""
def setUp(self):
"""Sets up the needed objects used throughout the test."""
self._plugin = msie_webcache.MsieWebCacheEseDbPlugin()
def testProcess(self):
"""Tests the Process function."""
test_file = self._GetTestFilePath(['WebCacheV01.dat'])
event_queue_consumer = self._ParseEseDbFileWithPlugin(
test_file, self._plugin)
event_objects = self._GetEventObjectsFromQueue(event_queue_consumer)
self.assertEquals(len(event_objects), 1354)
event_object = event_objects[0]
self.assertEquals(event_object.container_identifier, 1)
expected_timestamp = timelib_test.CopyStringToTimestamp(
'2014-05-12 07:30:25.486198')
self.assertEquals(event_object.timestamp, expected_timestamp)
self.assertEquals(
event_object.timestamp_desc, eventdata.EventTimestamp.ACCESS_TIME)
expected_msg = (
u'Container identifier: 1 '
u'Set identifier: 0 '
u'Name: Content '
u'Directory: C:\\Users\\test\\AppData\\Local\\Microsoft\\Windows\\'
u'INetCache\\IE\\ '
u'Table: Container_1')
expected_msg_short = (
u'Directory: C:\\Users\\test\\AppData\\Local\\Microsoft\\Windows\\'
u'INetCache\\IE\\')
self._TestGetMessageStrings(event_object, expected_msg, expected_msg_short)
if __name__ == '__main__':
unittest.main()
+76
View File
@@ -0,0 +1,76 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2014 The Plaso Project Authors.
# Please see the AUTHORS file for details on individual authors.
#
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""ESEDB plugin related functions and classes for testing."""
import pyesedb
from dfvfs.lib import definitions
from dfvfs.path import factory as path_spec_factory
from dfvfs.resolver import resolver as path_spec_resolver
from plaso.engine import single_process
from plaso.parsers import test_lib
class EseDbPluginTestCase(test_lib.ParserTestCase):
"""The unit test case for ESE database based plugins."""
def _OpenEseDbFile(self, path):
"""Opens an ESE database file and returns back a pyesedb.file object.
Args:
path: The path to the ESE database test file.
"""
path_spec = path_spec_factory.Factory.NewPathSpec(
definitions.TYPE_INDICATOR_OS, location=path)
file_entry = path_spec_resolver.Resolver.OpenFileEntry(path_spec)
file_object = file_entry.GetFileObject()
esedb_file = pyesedb.file()
esedb_file.open_file_object(file_object)
return esedb_file
def _ParseEseDbFileWithPlugin(
self, path, plugin_object, knowledge_base_values=None):
"""Parses a file as an ESE database file and returns an event generator.
Args:
path: The path to the ESE database test file.
plugin_object: The plugin object that is used to extract an event
generator.
knowledge_base_values: optional dict containing the knowledge base
values. The default is None.
Returns:
An event object queue consumer object (instance of
TestEventObjectQueueConsumer).
"""
event_queue = single_process.SingleProcessQueue()
event_queue_consumer = test_lib.TestEventObjectQueueConsumer(event_queue)
parse_error_queue = single_process.SingleProcessQueue()
parser_context = self._GetParserContext(
event_queue, parse_error_queue,
knowledge_base_values=knowledge_base_values)
esedb_file = self._OpenEseDbFile(path)
plugin_object.Process(parser_context, database=esedb_file)
return event_queue_consumer