Exemplo n.º 1
0
    def _PrintAPFSVolumeIdentifiersOverview(self, volume_system,
                                            volume_identifiers):
        """Prints an overview of APFS volume identifiers.

    Args:
      volume_system (dfvfs.APFSVolumeSystem): volume system.
      volume_identifiers (list[str]): allowed volume identifiers.

    Raises:
      SourceScannerError: if a volume cannot be resolved from the volume
          identifier.
    """
        header = 'The following Apple File System (APFS) volumes were found:\n'
        self._output_writer.Write(header)

        column_names = ['Identifier', 'Name']
        table_view = views.CLITabularTableView(column_names=column_names)

        for volume_identifier in volume_identifiers:
            volume = volume_system.GetVolumeByIdentifier(volume_identifier)
            if not volume:
                raise errors.SourceScannerError(
                    'Volume missing for identifier: {0:s}.'.format(
                        volume_identifier))

            volume_attribute = volume.GetAttribute('name')
            table_view.AddRow([volume.identifier, volume_attribute.value])

        self._output_writer.Write('\n')
        table_view.Write(self._output_writer)
        self._output_writer.Write('\n')
Exemplo n.º 2
0
    def _PrintTasksStatus(self, processing_status):
        """Prints the status of the tasks.

    Args:
      processing_status (ProcessingStatus): processing status.
    """
        if processing_status and processing_status.tasks_status:
            tasks_status = processing_status.tasks_status

            table_view = views.CLITabularTableView(
                column_names=[
                    'Tasks:', 'Queued', 'Processing', 'Merging', 'Abandoned',
                    'Total'
                ],
                column_sizes=[15, 7, 15, 15, 15, 0])

            table_view.AddRow([
                '', tasks_status.number_of_queued_tasks,
                tasks_status.number_of_tasks_processing,
                tasks_status.number_of_tasks_pending_merge,
                tasks_status.number_of_abandoned_tasks,
                tasks_status.total_number_of_tasks
            ])

            self._output_writer.Write('\n')
            table_view.Write(self._output_writer)
Exemplo n.º 3
0
    def _PrintTSKPartitionIdentifiersOverview(self, volume_system,
                                              volume_identifiers):
        """Prints an overview of TSK partition identifiers.

    Args:
      volume_system (dfvfs.TSKVolumeSystem): volume system.
      volume_identifiers (list[str]): allowed volume identifiers.

    Raises:
      SourceScannerError: if a volume cannot be resolved from the volume
          identifier.
    """
        header = 'The following partitions were found:\n'
        self._output_writer.Write(header)

        column_names = ['Identifier', 'Offset (in bytes)', 'Size (in bytes)']
        table_view = views.CLITabularTableView(column_names=column_names)

        for volume_identifier in sorted(volume_identifiers):
            volume = volume_system.GetVolumeByIdentifier(volume_identifier)
            if not volume:
                raise errors.SourceScannerError(
                    'Partition missing for identifier: {0:s}.'.format(
                        volume_identifier))

            volume_extent = volume.extents[0]
            volume_offset = '{0:d} (0x{0:08x})'.format(volume_extent.offset)
            volume_size = self._FormatHumanReadableSize(volume_extent.size)

            table_view.AddRow([volume.identifier, volume_offset, volume_size])

        self._output_writer.Write('\n')
        table_view.Write(self._output_writer)
        self._output_writer.Write('\n')
Exemplo n.º 4
0
  def _PrintAnalysisStatusUpdateWindow(self, processing_status):
    """Prints an analysis status update in window mode.

    Args:
      processing_status (ProcessingStatus): processing status.
    """
    if self._stdout_output_writer:
      self._ClearScreen()

    output_text = 'plaso - {0:s} version {1:s}\n\n'.format(
        self._tool_name, plaso.__version__)
    self._output_writer.Write(output_text)

    self._PrintAnalysisStatusHeader(processing_status)

    table_view = views.CLITabularTableView(column_names=[
        'Identifier', 'PID', 'Status', 'Memory', 'Events', 'Tags',
        'Reports'], column_sizes=[23, 7, 15, 15, 15, 15, 0])

    self._AddsAnalysisProcessStatusTableRow(
        processing_status.foreman_status, table_view)

    for worker_status in processing_status.workers_status:
      self._AddsAnalysisProcessStatusTableRow(worker_status, table_view)

    table_view.Write(self._output_writer)
    self._output_writer.Write('\n')

    if processing_status.aborted:
      self._output_writer.Write(
          'Processing aborted - waiting for clean up.\n\n')

    if self._stdout_output_writer:
      # We need to explicitly flush stdout to prevent partial status updates.
      sys.stdout.flush()
Exemplo n.º 5
0
  def _PrintLVMVolumeIdentifiersOverview(
      self, volume_system, volume_identifiers):
    """Prints an overview of LVM volume identifiers.

    Args:
      volume_system (dfvfs.LVMVolumeSystem): volume system.
      volume_identifiers (list[str]): allowed volume identifiers.

    Raises:
      SourceScannerError: if a volume cannot be resolved from the volume
          identifier.
    """
    header = 'The following Logical Volume Manager (LVM) volumes were found:\n'
    self._output_writer.Write(header)

    column_names = ['Identifier']
    table_view = views.CLITabularTableView(column_names=column_names)

    for volume_identifier in volume_identifiers:
      volume = volume_system.GetVolumeByIdentifier(volume_identifier)
      if not volume:
        raise errors.SourceScannerError(
            'Volume missing for identifier: {0:s}.'.format(
                volume_identifier))

      table_view.AddRow([volume.identifier])

    self._output_writer.Write('\n')
    table_view.Write(self._output_writer)
    self._output_writer.Write('\n')
Exemplo n.º 6
0
    def PrintExtractionStatusHeader(self, processing_status):
        """Prints the extraction status header.

    Args:
      processing_status (ProcessingStatus): processing status.
    """
        self._output_writer.Write('Source path\t\t: {0:s}\n'.format(
            self._source_path))
        self._output_writer.Write('Source type\t\t: {0:s}\n'.format(
            self._source_type))

        if self._artifact_filters:
            artifacts_string = ', '.join(self._artifact_filters)
            self._output_writer.Write(
                'Artifact filters\t: {0:s}\n'.format(artifacts_string))
        if self._filter_file:
            self._output_writer.Write('Filter file\t\t: {0:s}\n'.format(
                self._filter_file))

        if not processing_status:
            processing_time = '00:00:00'
        else:
            processing_time = time.time() - processing_status.start_time
            time_struct = time.gmtime(processing_time)
            processing_time = time.strftime('%H:%M:%S', time_struct)

        self._output_writer.Write(
            'Processing time\t\t: {0:s}\n'.format(processing_time))

        if processing_status and processing_status.tasks_status:
            tasks_status = processing_status.tasks_status

            table_view = views.CLITabularTableView(
                column_names=[
                    'Tasks:', 'Queued', 'Processing', 'Merging', 'Abandoned',
                    'Total'
                ],
                column_sizes=[15, 7, 15, 15, 15, 0])

            table_view.AddRow([
                '', tasks_status.number_of_queued_tasks,
                tasks_status.number_of_tasks_processing,
                tasks_status.number_of_tasks_pending_merge,
                tasks_status.number_of_abandoned_tasks,
                tasks_status.total_number_of_tasks
            ])

            self._output_writer.Write('\n')
            table_view.Write(self._output_writer)

        self._output_writer.Write('\n')
Exemplo n.º 7
0
    def _PrintEventsStatus(self, events_status):
        """Prints the status of the events.

    Args:
      events_status (EventsStatus): events status.
    """
        # TODO: print additional event status as "Events MACB grouped",
        # "Duplicate events removed", "Events filtered"
        if events_status:
            table_view = views.CLITabularTableView(
                column_names=['Events:', 'Total'], column_sizes=[15, 0])

            table_view.AddRow(['', events_status.total_number_of_events])

            self._output_writer.Write('\n')
            table_view.Write(self._output_writer)
Exemplo n.º 8
0
    def _PrintExtractionStatusUpdateWindow(self, processing_status):
        """Prints an extraction status update in window mode.

    Args:
      processing_status (ProcessingStatus): processing status.
    """
        if self._stdout_output_writer:
            self._ClearScreen()

        output_text = 'plaso - {0:s} version {1:s}\n\n'.format(
            self._tool_name, plaso.__version__)
        self._output_writer.Write(output_text)

        self.PrintExtractionStatusHeader(processing_status)

        table_view = views.CLITabularTableView(
            column_names=[
                'Identifier', 'PID', 'Status', 'Memory', 'Sources', 'Events',
                'File'
            ],
            column_sizes=[15, 7, 15, 15, 15, 15, 0])

        self._AddExtractionProcessStatusTableRow(
            processing_status.foreman_status, table_view)

        for worker_status in processing_status.workers_status:
            self._AddExtractionProcessStatusTableRow(worker_status, table_view)

        table_view.Write(self._output_writer)
        self._output_writer.Write('\n')

        if processing_status.aborted:
            self._output_writer.Write(
                'Processing aborted - waiting for clean up.\n\n')

        # TODO: remove update flicker. For win32console we could set the cursor
        # top left, write the table, clean the remainder of the screen buffer
        # and set the cursor at the end of the table.
        if self._stdout_output_writer:
            # We need to explicitly flush stdout to prevent partial status updates.
            sys.stdout.flush()
Exemplo n.º 9
0
  def _PrintEventsStatus(self, events_status):
    """Prints the status of the events.

    Args:
      events_status (EventsStatus): events status.
    """
    if events_status:
      table_view = views.CLITabularTableView(
          column_names=['Events:', 'Filtered', 'In time slice', 'Duplicates',
                        'MACB grouped', 'Total'],
          column_sizes=[15, 15, 15, 15, 15, 0])

      table_view.AddRow([
          '', events_status.number_of_filtered_events,
          events_status.number_of_events_from_time_slice,
          events_status.number_of_duplicate_events,
          events_status.number_of_macb_grouped_events,
          events_status.total_number_of_events])

      self._output_writer.Write('\n')
      table_view.Write(self._output_writer)
Exemplo n.º 10
0
    def testWrite(self):
        """Tests the Write function."""
        output_writer = test_lib.TestBinaryOutputWriter()

        table_view = views.CLITabularTableView(
            column_names=['Name', 'Description'])
        table_view.AddRow(['First name', 'The first name in the table'])
        table_view.AddRow(['Second name', 'The second name in the table'])

        table_view.Write(output_writer)
        string = output_writer.ReadOutput()

        expected_strings = [
            b'Name            Description',
            b'First name      The first name in the table',
            b'Second name     The second name in the table', b''
        ]

        if not sys.platform.startswith('win'):
            expected_strings[0] = b'\x1b[1mName            Description\x1b[0m'

        self.assertEqual(string.split(b'\n'), expected_strings)
Exemplo n.º 11
0
    def _PrintVSSStoreIdentifiersOverview(self, volume_system,
                                          volume_identifiers):
        """Prints an overview of VSS store identifiers.

    Args:
      volume_system (dfvfs.VShadowVolumeSystem): volume system.
      volume_identifiers (list[str]): allowed volume identifiers.

    Raises:
      SourceScannerError: if a volume cannot be resolved from the volume
          identifier.
    """
        header = 'The following Volume Shadow Snapshots (VSS) were found:\n'
        self._output_writer.Write(header)

        column_names = ['Identifier', 'Creation Time']
        table_view = views.CLITabularTableView(column_names=column_names)

        for volume_identifier in volume_identifiers:
            volume = volume_system.GetVolumeByIdentifier(volume_identifier)
            if not volume:
                raise errors.SourceScannerError(
                    'Volume missing for identifier: {0:s}.'.format(
                        volume_identifier))

            volume_attribute = volume.GetAttribute('creation_time')
            filetime = dfdatetime_filetime.Filetime(
                timestamp=volume_attribute.value)
            creation_time = filetime.CopyToDateTimeString()

            if volume.HasExternalData():
                creation_time = '{0:s}\tWARNING: data stored outside volume'.format(
                    creation_time)

            table_view.AddRow([volume.identifier, creation_time])

        self._output_writer.Write('\n')
        table_view.Write(self._output_writer)
        self._output_writer.Write('\n')
Exemplo n.º 12
0
    def PrintExtractionStatusHeader(self, processing_status):
        """Prints the extraction status header.

    Args:
      processing_status (ProcessingStatus): processing status.
    """
        self._output_writer.Write('Source path\t: {0:s}\n'.format(
            self._source_path))
        self._output_writer.Write('Source type\t: {0:s}\n'.format(
            self._source_type))

        if self._filter_file:
            self._output_writer.Write('Filter file\t: {0:s}\n'.format(
                self._filter_file))

        if processing_status and processing_status.tasks_status:
            tasks_status = processing_status.tasks_status

            table_view = views.CLITabularTableView(
                column_names=[
                    'Tasks:', 'Queued', 'Processing', 'To merge', 'Abandoned',
                    'Total'
                ],
                column_sizes=[15, 7, 15, 15, 15, 0])

            table_view.AddRow([
                '', tasks_status.number_of_queued_tasks,
                tasks_status.number_of_tasks_processing,
                tasks_status.number_of_tasks_pending_merge,
                tasks_status.number_of_abandoned_tasks,
                tasks_status.total_number_of_tasks
            ])

            self._output_writer.Write('\n')
            table_view.Write(self._output_writer)

        self._output_writer.Write('\n')
Exemplo n.º 13
0
    def _PromptUserForVSSStoreIdentifiers(self,
                                          volume_system,
                                          volume_identifiers,
                                          vss_stores=None):
        """Prompts the user to provide the VSS store identifiers.

    This method first checks for the preferred VSS stores and falls back
    to prompt the user if no usable preferences were specified.

    Args:
      volume_system (dfvfs.VShadowVolumeSystem): volume system.
      volume_identifiers (list[str]): allowed volume identifiers.
      vss_stores (Optional[list[str]]): preferred VSS store identifiers.

    Returns:
      list[str]: selected VSS store identifiers.

    Raises:
      SourceScannerError: if the source cannot be processed.
    """
        normalized_volume_identifiers = self._GetNormalizedVShadowVolumeIdentifiers(
            volume_system, volume_identifiers)

        # TODO: refactor this to _GetVSSStoreIdentifiers.
        if vss_stores:
            if vss_stores == ['all']:
                # We need to set the stores to cover all vss stores.
                vss_stores = range(1, volume_system.number_of_volumes + 1)

            if not set(vss_stores).difference(normalized_volume_identifiers):
                return vss_stores

        print_header = True
        while True:
            if print_header:
                self._output_writer.Write(
                    'The following Volume Shadow Snapshots (VSS) were found:\n'
                )

                table_view = views.CLITabularTableView(
                    column_names=['Identifier', 'Creation Time'])

                for volume_identifier in volume_identifiers:
                    volume = volume_system.GetVolumeByIdentifier(
                        volume_identifier)
                    if not volume:
                        raise errors.SourceScannerError(
                            'Volume missing for identifier: {0:s}.'.format(
                                volume_identifier))

                    vss_creation_time = volume.GetAttribute('creation_time')
                    filetime = dfdatetime_filetime.Filetime(
                        timestamp=vss_creation_time.value)
                    vss_creation_time = filetime.GetPlasoTimestamp()
                    vss_creation_time = timelib.Timestamp.CopyToIsoFormat(
                        vss_creation_time)

                    if volume.HasExternalData():
                        vss_creation_time = (
                            '{0:s}\tWARNING: data stored outside volume'
                        ).format(vss_creation_time)

                    table_view.AddRow([volume.identifier, vss_creation_time])

                self._output_writer.Write('\n')
                table_view.Write(self._output_writer)
                self._output_writer.Write('\n')

                print_header = False

            self._output_writer.Write(
                'Please specify the identifier(s) of the VSS that should be '
                'processed:\nNote that a range of stores can be defined as: 3..5. '
                'Multiple stores can\nbe defined as: 1,3,5 (a list of comma '
                'separated values). Ranges and lists can\nalso be combined '
                'as: 1,3..5. The first store is 1. All stores can be defined\n'
                'as "all". If no stores are specified none will be processed. You\n'
                'can abort with Ctrl^C.\n')

            selected_vss_stores = self._input_reader.Read()

            selected_vss_stores = selected_vss_stores.strip()
            if not selected_vss_stores:
                return []

            try:
                selected_vss_stores = self._ParseVSSStoresString(
                    selected_vss_stores)
            except errors.BadConfigOption:
                selected_vss_stores = []

            if selected_vss_stores == ['all']:
                # We need to set the stores to cover all vss stores.
                selected_vss_stores = range(
                    1, volume_system.number_of_volumes + 1)

            if not set(selected_vss_stores).difference(
                    normalized_volume_identifiers):
                break

            self._output_writer.Write(
                '\n'
                'Unsupported VSS identifier(s), please try again or abort with '
                'Ctrl^C.\n'
                '\n')

        self._output_writer.Write('\n')
        return selected_vss_stores
Exemplo n.º 14
0
    def _PromptUserForPartitionIdentifier(self, volume_system,
                                          volume_identifiers):
        """Prompts the user to provide a partition identifier.

    Args:
      volume_system (dfvfs.TSKVolumeSystem): volume system.
      volume_identifiers (list[str]): allowed volume identifiers.

    Returns:
      str: partition identifier or "all".

    Raises:
      SourceScannerError: if the source cannot be processed.
    """
        self._output_writer.Write('The following partitions were found:\n')

        table_view = views.CLITabularTableView(column_names=[
            'Identifier', 'Offset (in bytes)', 'Size (in bytes)'
        ])

        for volume_identifier in sorted(volume_identifiers):
            volume = volume_system.GetVolumeByIdentifier(volume_identifier)
            if not volume:
                raise errors.SourceScannerError(
                    'Volume missing for identifier: {0:s}.'.format(
                        volume_identifier))

            volume_extent = volume.extents[0]
            volume_offset = '{0:d} (0x{0:08x})'.format(volume_extent.offset)
            volume_size = self._FormatHumanReadableSize(volume_extent.size)

            table_view.AddRow([volume.identifier, volume_offset, volume_size])

        self._output_writer.Write('\n')
        table_view.Write(self._output_writer)
        self._output_writer.Write('\n')

        while True:
            self._output_writer.Write(
                'Please specify the identifier of the partition that should be '
                'processed.\nAll partitions can be defined as: "all". Note that you '
                'can abort with Ctrl^C.\n')

            selected_volume_identifier = self._input_reader.Read()
            selected_volume_identifier = selected_volume_identifier.strip()

            if not selected_volume_identifier.startswith('p'):
                try:
                    partition_number = int(selected_volume_identifier, 10)
                    selected_volume_identifier = 'p{0:d}'.format(
                        partition_number)
                except ValueError:
                    pass

            if (selected_volume_identifier == 'all'
                    or selected_volume_identifier in volume_identifiers):
                break

            self._output_writer.Write(
                '\n'
                'Unsupported partition identifier, please try again or abort '
                'with Ctrl^C.\n'
                '\n')

        self._output_writer.Write('\n')
        return selected_volume_identifier