Пример #1
0
 def __init__(self, data=None, offset_bytes=None):
     record_length = reverse_hexlify_int(data[0:4])
     self.data = data[0:record_length]
     self.offset_bytes = offset_bytes
     self.file_attributes_object = FileAttributesFlag(self.file_attributes)
Пример #2
0
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.content_data = self.data[self.header.content_offset:self.header.
                                   content_offset +
                                   self.header.content_size]
     self.flags_set = FileAttributesFlag(self.flags)
Пример #3
0
class UsnRecordBase():
    # Fields that are shared by both the USN record version 2 and 3 (4 is unknown at this moment)
    RECORD_LENGTH = ('record length', 0, 3)
    MAJOR_VERSION = ('major version', 4, 5)
    MINOR_VERSION = ('minor version', 6, 7)

    REASON_MAP = {
        0x00000001: 'DATA_OVERWRITE',
        0x00000002: 'DATA_EXTEND',
        0x00000004: 'DATA_TRUNCATION',
        0x00000010: 'NAMED_DATA_OVERWRITE',
        0x00000020: 'NAMED_DATA_EXTEND',
        0x00000040: 'NAMED_DATA_TRUNCATION',
        0x00000100: 'FILE_CREATE',
        0x00000200: 'FILE_DELETE',
        0x00000400: 'EA_CHANGE',
        0x00000800: 'SECURITY_CHANGE',
        0x00001000: 'RENAME_OLD_NAME',
        0x00002000: 'RENAME_NEW_NAME',
        0x00004000: 'INDEXABLE_CHANGE',
        0x00008000: 'BASIC_INFO_CHANGE',
        0x00010000: 'HARD_LINK_CHANGE',
        0x00020000: 'COMPRESSION_CHANGE',
        0x00040000: 'ENCRYPTION_CHANGE',
        0x00080000: 'OBJECT_ID_CHANGE',
        0x00100000: 'REPARSE_POINT_CHANGE',
        0x00200000: 'STREAM_CHANGE',
        0x80000000: 'CLOSE'
    }

    REASON_TUPLE = (
        (0x00000001, 'DATA_OVERWRITE'),
        (0x00000002, 'DATA_EXTEND'),
        (0x00000004, 'DATA_TRUNCATION'),
        (0x00000010, 'NAMED_DATA_OVERWRITE'),
        (0x00000020, 'NAMED_DATA_EXTEND'),
        (0x00000040, 'NAMED_DATA_TRUNCATION'),
        (0x00000100, 'FILE_CREATE'),
        (0x00000200, 'FILE_DELETE'),
        (0x00000400, 'EA_CHANGE'),
        (0x00000800, 'SECURITY_CHANGE'),
        (0x00001000, 'RENAME_OLD_NAME'),
        (0x00002000, 'RENAME_NEW_NAME'),
        (0x00004000, 'INDEXABLE_CHANGE'),
        (0x00008000, 'BASIC_INFO_CHANGE'),
        (0x00010000, 'HARD_LINK_CHANGE'),
        (0x00020000, 'COMPRESSION_CHANGE'),
        (0x00040000, 'ENCRYPTION_CHANGE'),
        (0x00080000, 'OBJECT_ID_CHANGE'),
        (0x00100000, 'REPARSE_POINT_CHANGE'),
        (0x00200000, 'STREAM_CHANGE'),
        (0x80000000, 'CLOSE')
    )



    # Source info
    USN_SOURCE_DATA_MANAGEMENT = 0x00000001
    USN_SOURCE_AUXILARY_DATA = 0x00000002
    USN_SOURCE_REPLICATION_MANAGEMENT = 0x00000004

    def __init__(self, data=None, offset_bytes=None):
        record_length = reverse_hexlify_int(data[0:4])
        self.data = data[0:record_length]
        self.offset_bytes = offset_bytes
        self.file_attributes_object = FileAttributesFlag(self.file_attributes)

    ####################################################################################################################
    # Raw values

    @property
    def record_length_raw(self):
        return self.data[0:4]

    @property
    def major_version_raw(self):
        return self.data[4:6]

    @property
    def minor_version_raw(self):
        return self.data[6:8]

    # Placeholders to be overridden by subclasses.
    @property
    def file_reference_number_raw(self): raise NotImplementedError()

    @property
    def parent_file_reference_number_raw(self): raise NotImplementedError()

    @property
    def usn_raw(self): raise NotImplementedError()

    @property
    def timestamp_raw(self): raise NotImplementedError()

    @property
    def reason_raw(self): raise NotImplementedError()

    @property
    def source_info_raw(self): raise NotImplementedError()

    @property
    def security_id_raw(self): raise NotImplementedError()

    @property
    def file_attributes_raw(self): raise NotImplementedError()

    @property
    def file_name_length_raw(self): raise NotImplementedError()

    @property
    def file_name_offset_raw(self): raise NotImplementedError()

    @property
    def file_name_raw(self):
        return self.data[self.file_name_offset : self.file_name_offset + self.file_name_length]

    ####################################################################################################################
    # Interpreted values

    @property
    def record_length(self):
        return reverse_hexlify_int(self.record_length_raw)

    @property
    def major_version(self):
        return reverse_hexlify_int(self.major_version_raw)

    @property
    def minor_version(self):
        return reverse_hexlify_int(self.minor_version_raw)

    @property
    def file_reference_number(self):
        return hexlify(self.file_reference_number_raw)

    @property
    def parent_file_reference_number(self):
        return hexlify(self.parent_file_reference_number_raw)

    @property
    def usn(self):
        return reverse_hexlify_int(self.usn_raw)

    @property
    def timestamp(self):
        return reverse_hexlify_int(self.timestamp_raw)

    @property
    def reason(self):
        return reverse_hexlify_int(self.reason_raw)

    @property
    def source_info(self):
        return reverse_hexlify_int(self.source_info_raw)

    @property
    def security_id(self):
        return reverse_hexlify_int(self.security_id_raw)

    @property
    def file_attributes(self):
        return reverse_hexlify_int(self.file_attributes_raw)

    @property
    def file_name_length(self):
        return reverse_hexlify_int(self.file_name_length_raw)

    @property
    def file_name_offset(self):
        return reverse_hexlify_int(self.file_name_offset_raw)

    @property
    def file_name(self):
        return self.file_name_raw.decode('utf-16')

    ####################################################################################################################
    # Derived values

    @property
    def timestamp_datetime(self):
        if not hasattr(self, '_timestamp_datetime'):
            self._timestamp_datetime = filetime_to_datetime(self.timestamp_raw)
        return self._timestamp_datetime

    @property
    def usn_source_data_management_flag_set(self):
        return bool(self.source_info & UsnRecordV2.USN_SOURCE_DATA_MANAGEMENT)

    @property
    def usn_source_auxiliary_data_flag_set(self):
        return bool(self.source_info & UsnRecordV2.USN_SOURCE_AUXILARY_DATA)

    @property
    def usn_source_replication_management_flag_set(self):
        return bool(self.source_info & UsnRecordV2.USN_SOURCE_REPLICATION_MANAGEMENT)

    @property
    def file_attributes_string(self):
        return '|'.join(self.file_attributes_object.reason_list())

    @property
    def reason_string(self):
        return '|'.join([second for first, second in self.REASON_TUPLE if self.reason & first])

    ####################################################################################################################
    # Printing

    def all_fields_described(self):
        return (
            (UsnRecordBase.RECORD_LENGTH, self.record_length, self.record_length_raw),
            (UsnRecordBase.MAJOR_VERSION, self.major_version, self.major_version_raw),
            (UsnRecordBase.MINOR_VERSION, self.minor_version, self.minor_version_raw),
        )

    def extra_pairs(self):
        return ()

    def formatted_csv(self):
        return [
            self.record_length,
            self.major_version,
            self.minor_version,
            #self.file_reference_number,
            #self.parent_file_reference_number,
            self.usn,
            self.timestamp_datetime,
            self.reason_string,
            self.source_info,
            self.security_id,
            self.file_attributes_string,
            self.file_name_length,
            self.file_name_offset,
            self.file_name
        ]

    def formatted_csv_column_headers(self):
        formatted = [
            'record length',
            'major version',
            'minor version',
            #'file reference number',
            #'parent file reference number',
            'usn',
            'timestamp',
            'reason',
            'source info',
            'security id',
            'file attributes',
            'file name length',
            'file name offset',
            'file name'
        ]
        return formatted

    def print(self):
        _INDENT = '    '
        for (description, low, high), value, value_raw in self.all_fields_described():
            print(_INDENT + '%-26s | %-5s | %-18s | %s' % (description, str(low) + '-' + str(high), value, hexlify(value_raw)))
        #print()
        #print(_INDENT + '%-47s | %s' % ('parent directory file reference sequence number', self.parent_directory_file_reference_sequence_number))
        #print(_INDENT + '%-47s | %s' % ('parent_directory_file_reference_mft entry', self.parent_directory_file_reference_mft_entry))
        #print(_INDENT + '%-47s | %s' % ('file creation time datetime', self.file_creation_time_datetime))
        #print(_INDENT + '%-47s | %s' % ('file modified time datetime', self.file_modification_time_datetime))
        #print(_INDENT + '%-47s | %s' % ('mft modified time datetime', self.mft_modification_time_datetime))
        #print(_INDENT + '%-47s | %s' % ('file access time datetime', self.file_access_time_datetime))
        #self.print_attribute_bottom()
    def print(self):
        pass

    def writeout_parsed(self, out, indent=0):
        for (description, low, high), value, value_raw in self.all_fields_described():
            out.write('%s%-26s | %-5s | %-18s | %s\n' % (indent * ' ', description, str(low) + '-' + str(high), value, hexlify(value_raw)))
        for key, val in self.extra_pairs():
            out.write('%-15s%s\n' % (key + ':', val))
Пример #4
0
class StandardInformation(Attribute):
    CREATION_TIME = ('creation time', 0, 7)
    FILE_ALTERED_TIME = ('file altered time', 8, 15)
    MFT_ALTERED_TIME = ('mft altered time', 16, 23)
    FILE_ACCESSED_TIME = ('file accessed time', 24, 31)
    FLAGS = ('flags', 32, 35)
    MAXIMUM_NUMBER_OF_VERSIONS = ('maximum version of numbers', 36, 39)
    VERSION_NUMBER = ('version number', 40, 43)
    CLASS_ID = ('class id', 44, 47)
    OWNER_ID = ('owner id', 48, 51)
    SECURITY_ID = ('security id', 52, 55)
    QUOTA_CHARGED = ('quota charged', 56, 63)
    USN = ('USN', 64, 71)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.content_data = self.data[self.header.content_offset:self.header.
                                      content_offset +
                                      self.header.content_size]
        self.flags_set = FileAttributesFlag(self.flags)

    ####################################################################################################################
    # Raw values

    @property
    def creation_time_raw(self):
        return self.content_data[0:8]

    @property
    def file_altered_time_raw(self):
        return self.content_data[8:16]

    @property
    def mft_altered_time_raw(self):
        return self.content_data[16:24]

    @property
    def file_accessed_time_raw(self):
        return self.content_data[24:32]

    @property
    def flags_raw(self):
        return self.content_data[32:36]

    @property
    def maximum_number_of_versions_raw(self):
        return self.content_data[36:40]

    @property
    def version_number_raw(self):
        return self.content_data[40:44]

    @property
    def class_id_raw(self):
        return self.content_data[44:48]

    @property
    def owner_id_raw(self):
        return self.content_data[48:52]

    @property
    def security_id_raw(self):
        return self.content_data[52:56]

    @property
    def quota_charged_raw(self):
        return self.content_data[56:64]

    @property
    def usn_raw(self):
        return self.content_data[64:72]

    ####################################################################################################################
    # Interpreted values

    @property
    def creation_time(self):
        return reverse_hexlify_int(self.creation_time_raw)

    @property
    def file_altered_time(self):
        return reverse_hexlify_int(self.file_altered_time_raw)

    @property
    def mft_altered_time(self):
        return reverse_hexlify_int(self.mft_altered_time_raw)

    @property
    def file_accessed_time(self):
        return reverse_hexlify_int(self.file_accessed_time_raw)

    @property
    def flags(self):
        return reverse_hexlify_int(self.flags_raw)

    @property
    def maximum_number_of_versions(self):
        return reverse_hexlify_int(self.maximum_number_of_versions_raw)

    @property
    def version_number(self):
        return reverse_hexlify_int(self.version_number_raw)

    @property
    def class_id(self):
        return reverse_hexlify_int(self.class_id_raw)

    @property
    def owner_id(self):
        return reverse_hexlify_int(self.owner_id_raw)

    @property
    def security_id(self):
        return reverse_hexlify_int(self.security_id_raw)

    @property
    def quota_charged(self):
        return reverse_hexlify_int(self.quota_charged_raw)

    @property
    def usn(self):
        return reverse_hexlify_int(self.usn_raw)

    ####################################################################################################################
    # Derived values

    @property
    def creation_time_datetime(self):
        if not hasattr(self, '_creation_time_datetime'):
            self._creation_time_datetime = filetime_to_datetime(
                self.creation_time_raw)
        return self._creation_time_datetime

    @property
    def file_altered_time_datetime(self):
        if not hasattr(self, '_file_altered_time_datetime'):
            self._file_altered_time_datetime = filetime_to_datetime(
                self.file_altered_time_raw)
        return self._file_altered_time_datetime

    @property
    def mft_altered_time_datetime(self):
        if not hasattr(self, '_mft_altered_time_datetime'):
            self._mft_altered_time_datetime = filetime_to_datetime(
                self.mft_altered_time_raw)
        return self._mft_altered_time_datetime

    @property
    def file_accessed_time_datetime(self):
        if not hasattr(self, '_file_accessed_time_datetime'):
            self._file_accessed_time_datetime = filetime_to_datetime(
                self.file_accessed_time_raw)
        return self._file_accessed_time_datetime

    @property
    def flags_string(self):
        return '|'.join(self.flags_set.reason_list())

    ####################################################################################################################
    # Printing

    def all_fields_described(self):
        base_tuple = ((StandardInformation.CREATION_TIME, self.creation_time,
                       self.creation_time_raw),
                      (StandardInformation.FILE_ALTERED_TIME,
                       self.file_altered_time, self.file_altered_time_raw),
                      (StandardInformation.MFT_ALTERED_TIME,
                       self.mft_altered_time, self.mft_altered_time_raw),
                      (StandardInformation.FILE_ACCESSED_TIME,
                       self.file_accessed_time, self.file_accessed_time_raw),
                      (StandardInformation.FLAGS, self.flags, self.flags_raw),
                      (StandardInformation.MAXIMUM_NUMBER_OF_VERSIONS,
                       self.maximum_number_of_versions,
                       self.maximum_number_of_versions_raw),
                      (StandardInformation.VERSION_NUMBER, self.version_number,
                       self.version_number_raw), (StandardInformation.CLASS_ID,
                                                  self.class_id,
                                                  self.class_id_raw))

        if len(self.content_data) == 48:
            return base_tuple
        elif len(self.content_data) == 72:
            return base_tuple + (
                (StandardInformation.OWNER_ID, self.owner_id,
                 self.owner_id_raw), (StandardInformation.SECURITY_ID,
                                      self.security_id, self.security_id_raw),
                (StandardInformation.QUOTA_CHARGED, self.quota_charged,
                 self.quota_charged_raw),
                (StandardInformation.USN, self.usn, self.usn_raw))
        else:
            raise Exception('StandardInformation is of length ' +
                            str(len(self.content_data)) +
                            ', case unaccounted for')

    def extra_pairs(self):
        return (('creation time datetime', self.creation_time_datetime),
                ('file altered time datetime',
                 self.file_altered_time_datetime),
                ('mft altered time datetime', self.mft_altered_time_datetime),
                ('file accessed time datetime',
                 self.file_accessed_time_datetime))

    @staticmethod
    def format_csv_column_headers():
        return [
            'SI creation time', 'SI file altered time', 'SI mft altered time',
            'SI file accessed time', 'SI flags',
            'SI maximum number of versions', 'SI version number',
            'SI class id', 'SI owner id', 'SI security id', 'SI quota charged',
            'SI usn'
        ]

    def format_csv(self):
        return [
            self.creation_time_datetime, self.file_altered_time_datetime,
            self.mft_altered_time_datetime, self.file_accessed_time_datetime,
            self.flags_string, self.maximum_number_of_versions,
            self.version_number, self.class_id, self.owner_id,
            self.security_id, self.quota_charged, self.usn
        ]
Пример #5
0
class FileName(Attribute):
    PARENT_DIRECTORY_FILE = ('parent directory file', 0, 7)
    FILE_CREATION_TIME = ('file creation time', 8, 15)
    FILE_MODIFICATION_TIME = ('file modification time', 16, 23)
    MFT_MODIFICATION_TIME = ('mft modification time', 24, 31)
    FILE_ACCESS_TIME = ('file access time', 32, 39)
    FILE_ALLOCATED_SIZE = ('file allocated size', 40, 47)
    FILE_REAL_SIZE = ('file real size', 48, 55)
    FLAGS = ('flags', 56, 59)
    REPARSE_VALUE = ('reparse value', 60, 63)
    NAME_LENGTH = ('name length', 64, 64)
    NAMESPACE = ('namespace', 65, 65)
    NAME = ('name', 66, '+')

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.content_data = self.data[self.header.content_offset:self.header.
                                      content_offset +
                                      self.header.content_size]
        self.flags_set = FileAttributesFlag(self.flags)

    ####################################################################################################################
    # Raw values

    @property
    def parent_directory_file_reference_raw(self):
        return self.content_data[0:8]

    @property
    def file_creation_time_raw(self):
        return self.content_data[8:16]

    @property
    def file_modification_time_raw(self):
        return self.content_data[16:24]

    @property
    def mft_modification_time_raw(self):
        return self.content_data[24:32]

    @property
    def file_access_time_raw(self):
        return self.content_data[32:40]

    @property
    def file_allocated_size_raw(self):
        return self.content_data[40:48]

    @property
    def file_real_size_raw(self):
        return self.content_data[48:56]

    @property
    def flags_raw(self):
        return self.content_data[56:60]

    @property
    def reparse_value_raw(self):
        return self.content_data[60:64]

    @property
    def name_length_raw(self):
        return self.content_data[64:65]

    @property
    def namespace_raw(self):
        return self.content_data[65:66]

    @property
    def name_raw(self):
        return self.content_data[66:66 + self.name_length * 2]

    ####################################################################################################################
    # Interpreted values

    @property
    def parent_directory_file_reference(self):
        return hexlify(self.parent_directory_file_reference_raw).decode()

    @property
    def file_creation_time(self):
        return reverse_hexlify_int(self.file_creation_time_raw)

    @property
    def file_modification_time(self):
        return reverse_hexlify_int(self.file_modification_time_raw)

    @property
    def mft_modification_time(self):
        return reverse_hexlify_int(self.mft_modification_time_raw)

    @property
    def file_access_time(self):
        return reverse_hexlify_int(self.file_access_time_raw)

    @property
    def file_allocated_size(self):
        return reverse_hexlify_int(self.file_allocated_size_raw)

    @property
    def file_real_size(self):
        return reverse_hexlify_int(self.file_allocated_size_raw)

    @property
    def flags(self):
        return reverse_hexlify_int(self.flags_raw)

    @property
    def reparse_value(self):
        return reverse_hexlify_int(self.reparse_value_raw)

    @property
    def name_length(self):
        return reverse_hexlify_int(self.name_length_raw)

    @property
    def namespace(self):
        return reverse_hexlify_int(self.namespace_raw)

    @property
    def name(self):
        return self.name_raw.decode('utf-16')

    ####################################################################################################################
    # Derived values

    @property
    def parent_directory_file_reference_sequence_number(self):
        return reverse_hexlify_int(
            self.parent_directory_file_reference_raw[6:8])

    @property
    def parent_directory_file_reference_mft_entry(self):
        return reverse_hexlify_int(
            self.parent_directory_file_reference_raw[0:6])

    @property
    def file_creation_time_datetime(self):
        try:
            if not hasattr(self, '_file_creation_time_datetime'):
                self._file_creation_time_datetime = filetime_to_datetime(
                    self.file_creation_time_raw)
            return self._file_creation_time_datetime
        except ValueError:
            return None

    @property
    def file_modification_time_datetime(self):
        try:
            if not hasattr(self, '_file_modification_time_datetime'):
                self._file_modification_time_datetime = filetime_to_datetime(
                    self.file_modification_time_raw)
            return self._file_modification_time_datetime
        except ValueError:
            return None

    @property
    def mft_modification_time_datetime(self):
        try:
            if not hasattr(self, '_mft_modification_time_datetime'):
                self._mft_modification_time_datetime = filetime_to_datetime(
                    self.mft_modification_time_raw)
            return self._mft_modification_time_datetime
        except ValueError:
            return None

    @property
    def file_access_time_datetime(self):
        try:
            if not hasattr(self, '_file_access_time_datetime'):
                self._file_access_time_datetime = filetime_to_datetime(
                    self.file_access_time_raw)
            return self._file_access_time_datetime
        except ValueError:
            return None

    @property
    def flags_string(self):
        return '|'.join(self.flags_set.reason_list())

    ####################################################################################################################
    # Printing

    def all_fields_described(self):
        return ((FileName.PARENT_DIRECTORY_FILE,
                 self.parent_directory_file_reference,
                 self.parent_directory_file_reference_raw),
                (FileName.FILE_CREATION_TIME, self.file_creation_time,
                 self.file_creation_time_raw),
                (FileName.FILE_MODIFICATION_TIME, self.file_modification_time,
                 self.file_modification_time_raw),
                (FileName.MFT_MODIFICATION_TIME, self.mft_modification_time,
                 self.file_modification_time_raw), (FileName.FILE_ACCESS_TIME,
                                                    self.file_access_time,
                                                    self.file_access_time_raw),
                (FileName.FILE_ALLOCATED_SIZE, self.file_allocated_size,
                 self.file_allocated_size_raw), (FileName.FILE_REAL_SIZE,
                                                 self.file_real_size,
                                                 self.file_real_size_raw),
                (FileName.FLAGS, self.flags,
                 self.flags_raw), (FileName.REPARSE_VALUE, self.reparse_value,
                                   self.reparse_value_raw),
                (FileName.NAME_LENGTH, self.name_length,
                 self.name_length_raw), (FileName.NAMESPACE, self.namespace,
                                         self.namespace_raw), (FileName.NAME,
                                                               self.name,
                                                               self.name_raw))

    def extra_pairs(self):
        return (('parent directory file reference sequence number',
                 self.parent_directory_file_reference_sequence_number),
                ('parent_directory_file_reference_mft entry',
                 self.parent_directory_file_reference_mft_entry),
                ('file creation time datetime',
                 self.file_creation_time_datetime),
                ('file modified time datetime',
                 self.file_modification_time_datetime),
                ('mft modified time datetime',
                 self.mft_modification_time_datetime),
                ('file access time datetime', self.file_access_time_datetime))

    @staticmethod
    def format_csv_column_headers():
        return [
            'FN file creation time', 'FN file modification time',
            'FN mft modification time', 'FN file access time',
            'FN file allocated size', 'FN file real size', 'FN flags',
            'FN reparse value', 'FN name length', 'FN namespace', 'FN name',
            'FN pdfme', 'FN pdfsn'
        ]

    def format_csv(self):
        return [
            self.file_creation_time_datetime,
            self.file_modification_time_datetime,
            self.mft_modification_time_datetime,
            self.file_access_time_datetime, self.file_allocated_size,
            self.file_real_size, self.flags_string, self.reparse_value,
            self.name_length, self.namespace, self.name,
            self.parent_directory_file_reference_mft_entry,
            self.parent_directory_file_reference_sequence_number
        ]
Пример #6
0
class StandardInformation(Attribute):
    CREATION_TIME = ('creation time', 0, 7)
    FILE_ALTERED_TIME = ('file altered time', 8,15)
    MFT_ALTERED_TIME = ('mft altered time', 16, 23)
    FILE_ACCESSED_TIME = ('file accessed time', 24, 31)
    FLAGS = ('flags', 32, 35)
    MAXIMUM_NUMBER_OF_VERSIONS = ('maximum version of numbers', 36, 39)
    VERSION_NUMBER = ('version number', 40, 43)
    CLASS_ID = ('class id', 44, 47)
    OWNER_ID = ('owner id', 48, 51)
    SECURITY_ID = ('security id', 52, 55)
    QUOTA_CHARGED = ('quota charged', 56, 63)
    USN = ('USN', 64, 71)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.content_data = self.data[
                            self.header.content_offset:
                            self.header.content_offset + self.header.content_size]
        self.flags_set = FileAttributesFlag(self.flags)

    ####################################################################################################################
    # Raw values

    @property
    def creation_time_raw(self):
        return self.content_data[0:8]

    @property
    def file_altered_time_raw(self):
        return self.content_data[8:16]

    @property
    def mft_altered_time_raw(self):
        return self.content_data[16:24]

    @property
    def file_accessed_time_raw(self):
        return self.content_data[24:32]

    @property
    def flags_raw(self):
        return self.content_data[32:36]

    @property
    def maximum_number_of_versions_raw(self):
        return self.content_data[36:40]

    @property
    def version_number_raw(self):
        return self.content_data[40:44]

    @property
    def class_id_raw(self):
        return self.content_data[44:48]

    @property
    def owner_id_raw(self):
        return self.content_data[48:52]

    @property
    def security_id_raw(self):
        return self.content_data[52:56]

    @property
    def quota_charged_raw(self):
        return self.content_data[56:64]

    @property
    def usn_raw(self):
        return self.content_data[64:72]


    ####################################################################################################################
    # Interpreted values

    @property
    def creation_time(self):
        return reverse_hexlify_int(self.creation_time_raw)

    @property
    def file_altered_time(self):
        return reverse_hexlify_int(self.file_altered_time_raw)

    @property
    def mft_altered_time(self):
        return reverse_hexlify_int(self.mft_altered_time_raw)

    @property
    def file_accessed_time(self):
        return reverse_hexlify_int(self.file_accessed_time_raw)

    @property
    def flags(self):
        return reverse_hexlify_int(self.flags_raw)

    @property
    def maximum_number_of_versions(self):
        return reverse_hexlify_int(self.maximum_number_of_versions_raw)

    @property
    def version_number(self):
        return reverse_hexlify_int(self.version_number_raw)

    @property
    def class_id(self):
        return reverse_hexlify_int(self.class_id_raw)

    @property
    def owner_id(self):
        return reverse_hexlify_int(self.owner_id_raw)

    @property
    def security_id(self):
        return reverse_hexlify_int(self.security_id_raw)

    @property
    def quota_charged(self):
        return reverse_hexlify_int(self.quota_charged_raw)

    @property
    def usn(self):
        return reverse_hexlify_int(self.usn_raw)


    ####################################################################################################################
    # Derived values

    @property
    def creation_time_datetime(self):
        if not hasattr(self, '_creation_time_datetime'):
            self._creation_time_datetime = filetime_to_datetime(self.creation_time_raw)
        return self._creation_time_datetime

    @property
    def file_altered_time_datetime(self):
        if not hasattr(self, '_file_altered_time_datetime'):
            self._file_altered_time_datetime = filetime_to_datetime(self.file_altered_time_raw)
        return self._file_altered_time_datetime

    @property
    def mft_altered_time_datetime(self):
        if not hasattr(self, '_mft_altered_time_datetime'):
            self._mft_altered_time_datetime = filetime_to_datetime(self.mft_altered_time_raw)
        return self._mft_altered_time_datetime

    @property
    def file_accessed_time_datetime(self):
        if not hasattr(self, '_file_accessed_time_datetime'):
            self._file_accessed_time_datetime = filetime_to_datetime(self.file_accessed_time_raw)
        return self._file_accessed_time_datetime

    @property
    def flags_string(self):
        return '|'.join(self.flags_set.reason_list())

    ####################################################################################################################
    # Printing

    def all_fields_described(self):
        base_tuple = (
            (StandardInformation.CREATION_TIME, self.creation_time, self.creation_time_raw),
            (StandardInformation.FILE_ALTERED_TIME, self.file_altered_time, self.file_altered_time_raw),
            (StandardInformation.MFT_ALTERED_TIME, self.mft_altered_time, self.mft_altered_time_raw),
            (StandardInformation.FILE_ACCESSED_TIME,self.file_accessed_time, self.file_accessed_time_raw),
            (StandardInformation.FLAGS, self.flags, self.flags_raw),
            (StandardInformation.MAXIMUM_NUMBER_OF_VERSIONS, self.maximum_number_of_versions, self.maximum_number_of_versions_raw),
            (StandardInformation.VERSION_NUMBER, self.version_number, self.version_number_raw),
            (StandardInformation.CLASS_ID, self.class_id, self.class_id_raw)
        )

        if len(self.content_data) == 48:
            return base_tuple
        elif len(self.content_data) == 72:
            return base_tuple + (
                (StandardInformation.OWNER_ID, self.owner_id, self.owner_id_raw),
                (StandardInformation.SECURITY_ID, self.security_id, self.security_id_raw),
                (StandardInformation.QUOTA_CHARGED, self.quota_charged, self.quota_charged_raw),
                (StandardInformation.USN, self.usn, self.usn_raw)
            )
        else:
            raise Exception('StandardInformation is of length ' + str(len(self.content_data)) + ', case unaccounted for')

    def extra_pairs(self):
        return (
            ('creation time datetime', self.creation_time_datetime),
            ('file altered time datetime', self.file_altered_time_datetime),
            ('mft altered time datetime', self.mft_altered_time_datetime),
            ('file accessed time datetime', self.file_accessed_time_datetime)
        )

    @staticmethod
    def format_csv_column_headers():
        return [
            'SI creation time',
            'SI file altered time',
            'SI mft altered time',
            'SI file accessed time',
            'SI flags',
            'SI maximum number of versions',
            'SI version number',
            'SI class id',
            'SI owner id',
            'SI security id',
            'SI quota charged',
            'SI usn'
        ]

    def format_csv(self):
        return [
            self.creation_time_datetime,
            self.file_altered_time_datetime,
            self.mft_altered_time_datetime,
            self.file_accessed_time_datetime,
            self.flags_string,
            self.maximum_number_of_versions,
            self.version_number,
            self.class_id,
            self.owner_id,
            self.security_id,
            self.quota_charged,
            self.usn
        ]
Пример #7
0
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.content_data = self.data[
                         self.header.content_offset:
                         self.header.content_offset + self.header.content_size]
     self.flags_set = FileAttributesFlag(self.flags)
Пример #8
0
class FileName(Attribute):
    PARENT_DIRECTORY_FILE  = ('parent directory file', 0, 7)
    FILE_CREATION_TIME = ('file creation time', 8, 15)
    FILE_MODIFICATION_TIME = ('file modification time', 16, 23)
    MFT_MODIFICATION_TIME = ('mft modification time', 24, 31)
    FILE_ACCESS_TIME = ('file access time', 32, 39)
    FILE_ALLOCATED_SIZE = ('file allocated size', 40, 47)
    FILE_REAL_SIZE = ('file real size', 48, 55)
    FLAGS = ('flags', 56, 59)
    REPARSE_VALUE = ('reparse value', 60, 63)
    NAME_LENGTH = ('name length', 64, 64)
    NAMESPACE = ('namespace', 65, 65)
    NAME = ('name', 66, '+')

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.content_data = self.data[
                            self.header.content_offset:
                            self.header.content_offset + self.header.content_size]
        self.flags_set = FileAttributesFlag(self.flags)

    ####################################################################################################################
    # Raw values

    @property
    def parent_directory_file_reference_raw(self):
        return self.content_data[0:8]

    @property
    def file_creation_time_raw(self):
        return self.content_data[8:16]

    @property
    def file_modification_time_raw(self):
        return self.content_data[16:24]

    @property
    def mft_modification_time_raw(self):
        return self.content_data[24:32]

    @property
    def file_access_time_raw(self):
        return self.content_data[32:40]

    @property
    def file_allocated_size_raw(self):
        return self.content_data[40:48]

    @property
    def file_real_size_raw(self):
        return self.content_data[48:56]

    @property
    def flags_raw(self):
        return self.content_data[56:60]

    @property
    def reparse_value_raw(self):
        return self.content_data[60:64]

    @property
    def name_length_raw(self):
        return self.content_data[64:65]

    @property
    def namespace_raw(self):
        return self.content_data[65:66]

    @property
    def name_raw(self):
        return self.content_data[66:66+self.name_length*2]

    ####################################################################################################################
    # Interpreted values

    @property
    def parent_directory_file_reference(self):
        return hexlify(self.parent_directory_file_reference_raw).decode()

    @property
    def file_creation_time(self):
        return reverse_hexlify_int(self.file_creation_time_raw)

    @property
    def file_modification_time(self):
        return reverse_hexlify_int(self.file_modification_time_raw)

    @property
    def mft_modification_time(self):
        return reverse_hexlify_int(self.mft_modification_time_raw)

    @property
    def file_access_time(self):
        return reverse_hexlify_int(self.file_access_time_raw)

    @property
    def file_allocated_size(self):
        return reverse_hexlify_int(self.file_allocated_size_raw)

    @property
    def file_real_size(self):
        return reverse_hexlify_int(self.file_allocated_size_raw)

    @property
    def flags(self):
        return reverse_hexlify_int(self.flags_raw)

    @property
    def reparse_value(self):
        return reverse_hexlify_int(self.reparse_value_raw)

    @property
    def name_length(self):
        return reverse_hexlify_int(self.name_length_raw)

    @property
    def namespace(self):
        return reverse_hexlify_int(self.namespace_raw)

    @property
    def name(self):
        return self.name_raw.decode('utf-16')

    ####################################################################################################################
    # Derived values

    @property
    def parent_directory_file_reference_sequence_number(self):
        return reverse_hexlify_int(self.parent_directory_file_reference_raw[6:8])

    @property
    def parent_directory_file_reference_mft_entry(self):
        return reverse_hexlify_int(self.parent_directory_file_reference_raw[0:6])

    @property
    def file_creation_time_datetime(self):
        try:
            if not hasattr(self, '_file_creation_time_datetime'):
                self._file_creation_time_datetime = filetime_to_datetime(self.file_creation_time_raw)
            return self._file_creation_time_datetime
        except ValueError:
            return None

    @property
    def file_modification_time_datetime(self):
        try:
            if not hasattr(self, '_file_modification_time_datetime'):
                self._file_modification_time_datetime = filetime_to_datetime(self.file_modification_time_raw)
            return self._file_modification_time_datetime
        except ValueError:
            return None
    @property
    def mft_modification_time_datetime(self):
        try:
            if not hasattr(self, '_mft_modification_time_datetime'):
                self._mft_modification_time_datetime = filetime_to_datetime(self.mft_modification_time_raw)
            return self._mft_modification_time_datetime
        except ValueError:
            return None
    @property
    def file_access_time_datetime(self):
        try:
            if not hasattr(self, '_file_access_time_datetime'):
                self._file_access_time_datetime = filetime_to_datetime(self.file_access_time_raw)
            return self._file_access_time_datetime
        except ValueError:
            return None

    @property
    def flags_string(self):
        return '|'.join(self.flags_set.reason_list())

    ####################################################################################################################
    # Printing

    def all_fields_described(self):
        return (
            (FileName.PARENT_DIRECTORY_FILE, self.parent_directory_file_reference, self.parent_directory_file_reference_raw),
            (FileName.FILE_CREATION_TIME, self.file_creation_time, self.file_creation_time_raw),
            (FileName.FILE_MODIFICATION_TIME, self.file_modification_time, self.file_modification_time_raw),
            (FileName.MFT_MODIFICATION_TIME, self.mft_modification_time, self.file_modification_time_raw),
            (FileName.FILE_ACCESS_TIME, self.file_access_time, self.file_access_time_raw),
            (FileName.FILE_ALLOCATED_SIZE, self.file_allocated_size, self.file_allocated_size_raw),
            (FileName.FILE_REAL_SIZE, self.file_real_size, self.file_real_size_raw),
            (FileName.FLAGS, self.flags, self.flags_raw),
            (FileName.REPARSE_VALUE, self.reparse_value, self.reparse_value_raw),
            (FileName.NAME_LENGTH, self.name_length, self.name_length_raw),
            (FileName.NAMESPACE, self.namespace, self.namespace_raw),
            (FileName.NAME, self.name, self.name_raw)
        )

    def extra_pairs(self):
        return (
            ('parent directory file reference sequence number', self.parent_directory_file_reference_sequence_number),
            ('parent_directory_file_reference_mft entry', self.parent_directory_file_reference_mft_entry),
            ('file creation time datetime', self.file_creation_time_datetime),
            ('file modified time datetime', self.file_modification_time_datetime),
            ('mft modified time datetime', self.mft_modification_time_datetime),
            ('file access time datetime', self.file_access_time_datetime)
        )

    @staticmethod
    def format_csv_column_headers():
        return [
            'FN file creation time',
            'FN file modification time',
            'FN mft modification time',
            'FN file access time',
            'FN file allocated size',
            'FN file real size',
            'FN flags',
            'FN reparse value',
            'FN name length',
            'FN namespace',
            'FN name',
            'FN pdfme',
            'FN pdfsn'
        ]

    def format_csv(self):
        return [
            self.file_creation_time_datetime,
            self.file_modification_time_datetime,
            self.mft_modification_time_datetime,
            self.file_access_time_datetime,
            self.file_allocated_size,
            self.file_real_size,
            self.flags_string,
            self.reparse_value,
            self.name_length,
            self.namespace,
            self.name,
            self.parent_directory_file_reference_mft_entry,
            self.parent_directory_file_reference_sequence_number
        ]