Source code for plaso.lib.specification

# -*- coding: utf-8 -*-
"""The format specification classes."""


[docs] class Signature(object): """The format specification signature. The signature consists of a byte string pattern, an optional offset relative to the start of the data, and a value to indicate if the pattern is bound to the offset. """
[docs] def __init__(self, pattern, offset=None): """Initializes a format specification signature. The signatures can be defined in 3 different "modes": * where offset >= 0, which represents that the signature is bound to the start of the data and only the relevant part is scanned; * where offset < 0, which represents that the signature is bound to the end of the data and only the relevant part is scanned; * offset == None, which represents that the signature is not offset bound and that all of the data is scanned. Args: pattern (bytes): pattern of the signature. Wildcards or regular expressions (regexp) are not supported. offset (int): offset of the signature. None is used to indicate the signature has no offset. A positive offset is relative from the start of the data a negative offset is relative from the end of the data. """ super(Signature, self).__init__() self.identifier = None self.offset = offset self.pattern = pattern
[docs] def SetIdentifier(self, identifier): """Sets the identifier of the signature in the specification store. Args: identifier (str): unique signature identifier for a specification store. """ self.identifier = identifier
[docs] class FormatSpecification(object): """The format specification."""
[docs] def __init__(self, identifier, text_format=False): """Initializes a format specification. Args: identifier (str): unique name for the format. text_format (Optional[bool]): True if the format is a text format, False otherwise. """ super(FormatSpecification, self).__init__() self._text_format = text_format self.identifier = identifier self.signatures = []
[docs] def AddNewSignature(self, pattern, offset=None): """Adds a signature. Args: pattern (bytes): pattern of the signature. offset (int): offset of the signature. None is used to indicate the signature has no offset. A positive offset is relative from the start of the data a negative offset is relative from the end of the data. """ self.signatures.append(Signature(pattern, offset=offset))
[docs] def IsTextFormat(self): """Determines if the format is a text format. Returns: bool: True if the format is a text format, False otherwise. """ return self._text_format
[docs] class FormatSpecificationStore(object): """The store for format specifications."""
[docs] def __init__(self): """Initializes a specification store.""" super(FormatSpecificationStore, self).__init__() self._format_specifications = {} # Maps signature identifiers to format specifications. self._signature_map = {}
@property def specifications(self): """iterator: specifications iterator.""" return iter(self._format_specifications.values())
[docs] def AddNewSpecification(self, identifier): """Adds a new format specification. Args: identifier (str): format identifier, which should be unique for the store. Returns: FormatSpecification: format specification. Raises: KeyError: if the store already contains a specification with the same identifier. """ if identifier in self._format_specifications: raise KeyError( 'Format specification {0:s} is already defined in store.'.format( identifier)) self._format_specifications[identifier] = FormatSpecification(identifier) return self._format_specifications[identifier]
[docs] def AddSpecification(self, specification): """Adds a format specification. Args: specification (FormatSpecification): format specification. Raises: KeyError: if the store already contains a specification with the same identifier. """ if specification.identifier in self._format_specifications: raise KeyError( 'Format specification {0:s} is already defined in store.'.format( specification.identifier)) self._format_specifications[specification.identifier] = specification for signature in specification.signatures: signature_index = len(self._signature_map) signature_identifier = '{0:s}:{1:d}'.format( specification.identifier, signature_index) if signature_identifier in self._signature_map: raise KeyError('Signature {0:s} is already defined in map.'.format( signature_identifier)) signature.SetIdentifier(signature_identifier) self._signature_map[signature_identifier] = specification
[docs] def GetSpecificationBySignature(self, signature_identifier): """Retrieves a specification mapped to a signature identifier. Args: signature_identifier (str): unique signature identifier for a specification store. Returns: FormatSpecification: format specification or None if the signature identifier does not exist within the specification store. """ return self._signature_map.get(signature_identifier, None)