コード例 #1
0
    def _ReadFileHeader(self):
        """Reads the file header.

    Raises:
      IOError: if the file header cannot be read.
    """
        if self._debug:
            print(u'Seeking file header offset: 0x{0:08x}'.format(0))

        self._file_object.seek(0, os.SEEK_SET)

        file_header_data = self._file_object.read(self._FILE_HEADER.sizeof())

        if self._debug:
            print(u'File header data:')
            print(hexdump.Hexdump(file_header_data))

        try:
            file_header_struct = self._FILE_HEADER.parse(file_header_data)
        except construct.FieldError as exception:
            raise IOError(
                u'Unable to parse file header with error: {0:s}'.format(
                    exception))

        if self._debug:
            print(u'Signature\t\t\t\t\t\t\t: {0!s}'.format(
                file_header_struct.signature))
            print(u'Number of pages\t\t\t\t\t\t\t: {0:d}'.format(
                file_header_struct.number_of_pages))

            print(u'')

        page_sizes_data_size = file_header_struct.number_of_pages * 4

        page_sizes_data = self._file_object.read(page_sizes_data_size)

        if self._debug:
            print(u'Page sizes data:')
            print(hexdump.Hexdump(page_sizes_data))

        try:
            page_sizes_array = construct.Array(
                file_header_struct.number_of_pages,
                construct.UBInt32(u'page_sizes')).parse(page_sizes_data)

        except construct.FieldError as exception:
            raise IOError(
                u'Unable to parse page sizes array with error: {0:s}'.format(
                    exception))

        self._page_sizes = []
        for page_index in range(file_header_struct.number_of_pages):
            self._page_sizes.append(page_sizes_array[page_index])

            if self._debug:
                print(u'Page: {0:d} size\t\t\t\t\t\t\t: {1:d}'.format(
                    page_index, page_sizes_array[page_index]))

        if self._debug:
            print(u'')
コード例 #2
0
ファイル: wsi_extract.py プロジェクト: kalnyc1/assorted
    def WriteShellItem(self, shell_item_data):
        """Writes a shell item.

    Args:
      shell_item_data: a binary string containing the shell item data.
    """
        print(hexdump.Hexdump(shell_item_data))
コード例 #3
0
  def WriteShellItem(self, shell_item_data):
    """Writes a shell item.

    Args:
      shell_item_data (bytes): shell item data.
    """
    print(hexdump.Hexdump(shell_item_data))
コード例 #4
0
    def _ReadFileFooter(self):
        """Reads the file footer.

    Raises:
      IOError: if the file footer cannot be read.
    """
        file_footer_data = self._file_object.read(self._FILE_FOOTER.sizeof())

        if self._debug:
            print(u'File footer data:')
            print(hexdump.Hexdump(file_footer_data))
コード例 #5
0
  def _ReadDestListHeader(self, olecf_item):
    """Reads the DestList stream header.

    Args:
      olecf_item: the OLECF item (instance of pyolecf.item).

    Raises:
      IOError: if the DestList stream header cannot be read.
    """
    olecf_item.seek(0, os.SEEK_SET)

    if self._debug:
      print(u'Reading header at offset: 0x{0:08x}'.format(0))

    header_data = olecf_item.read(self._DEST_LIST_STREAM_HEADER.sizeof())

    if self._debug:
      print(u'Header data:')
      print(hexdump.Hexdump(header_data))

    try:
      dest_list_header_struct = self._DEST_LIST_STREAM_HEADER.parse(header_data)
    except construct.FieldError as exception:
      raise IOError((
          u'Unable to parse header with error: {0:s}').format(exception))

    if self._debug:
      print(u'Format version\t\t\t\t\t\t\t\t: {0:d}'.format(
          dest_list_header_struct.format_version))
      print(u'Number of entries\t\t\t\t\t\t\t: {0:d}'.format(
          dest_list_header_struct.number_of_entries))
      print(u'Number of pinned entries\t\t\t\t\t\t: {0:d}'.format(
          dest_list_header_struct.number_of_pinned_entries))
      print(u'Unknown1\t\t\t\t\t\t\t\t: {0:f}'.format(
          dest_list_header_struct.unknown1))
      print(u'Last entry number\t\t\t\t\t\t\t: {0:d}'.format(
          dest_list_header_struct.last_entry_number))
      print(u'Unknown2\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(
          dest_list_header_struct.unknown2))
      print(u'Last revision number\t\t\t\t\t\t\t: {0:d}'.format(
          dest_list_header_struct.last_revision_number))
      print(u'Unknown3\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(
          dest_list_header_struct.unknown3))

      print(u'')

    if dest_list_header_struct.format_version not in (1, 3, 4):
      raise IOError(
          u'Unsupported format version: {0:d}'.format(
              dest_list_header_struct.format_version))

    self._format_version = dest_list_header_struct.format_version
コード例 #6
0
ファイル: wemf.py プロジェクト: kalnyc1/assorted
    def _ReadFileHeader(self):
        """Reads a file header.

    Raises:
      IOError: if the file header cannot be read.
    """
        if self._debug:
            print(u'Seeking file header offset: 0x{0:08x}'.format(0))

        self._file_object.seek(0, os.SEEK_SET)

        file_header_data = self._file_object.read(
            self._EMF_FILE_HEADER.sizeof())

        if self._debug:
            print(u'File header data:')
            print(hexdump.Hexdump(file_header_data))

        try:
            emf_file_header_struct = self._EMF_FILE_HEADER.parse(
                file_header_data)
        except construct.FieldError as exception:
            raise IOError((u'Unable to parse file header with error: {0:s}'
                           ).format(exception))

        if self._debug:
            record_type_string = self._EMF_RECORD_TYPES.get(
                emf_file_header_struct.record_type, u'UNKNOWN')
            print(u'Record type\t\t\t\t\t\t\t: 0x{0:04x} ({1:s})'.format(
                emf_file_header_struct.record_type, record_type_string))
            print(u'Record size\t\t\t\t\t\t\t: {0:d}'.format(
                emf_file_header_struct.record_size))

            print(u'Signature\t\t\t\t\t\t\t: 0x{0:04x}'.format(
                emf_file_header_struct.signature))
            print(u'Signature\t\t\t\t\t\t\t: 0x{0:04x}'.format(
                emf_file_header_struct.format_version))
            print(u'File size\t\t\t\t\t\t\t: {0:d}'.format(
                emf_file_header_struct.file_size))
            print(u'Number of records\t\t\t\t\t\t: {0:d}'.format(
                emf_file_header_struct.number_of_records))
            print(u'Number of handles\t\t\t\t\t\t: {0:d}'.format(
                emf_file_header_struct.number_of_handles))
            print(u'Unknown (reserved)\t\t\t\t\t\t: 0x{0:04x}'.format(
                emf_file_header_struct.unknown1))
            print(u'Description string size\t\t\t\t\t\t: {0:d}'.format(
                emf_file_header_struct.description_string_size))
            print(u'Description string offset\t\t\t\t\t: 0x{0:04x}'.format(
                emf_file_header_struct.description_string_offset))

            print(u'')
コード例 #7
0
ファイル: wemf.py プロジェクト: kalnyc1/assorted
    def _ReadFileHeader(self):
        """Reads a file header.

    Raises:
      IOError: if the file header cannot be read.
    """
        if self._debug:
            print(u'Seeking file header offset: 0x{0:08x}'.format(0))

        self._file_object.seek(0, os.SEEK_SET)

        file_header_data = self._file_object.read(
            self._WMF_FILE_HEADER.sizeof())

        if self._debug:
            print(u'File header data:')
            print(hexdump.Hexdump(file_header_data))

        try:
            wmf_file_header_struct = self._WMF_FILE_HEADER.parse(
                file_header_data)
        except construct.FieldError as exception:
            raise IOError((u'Unable to parse file header with error: {0:s}'
                           ).format(exception))

        if self._debug:
            print(u'File type\t\t\t\t\t\t\t: 0x{0:04x}'.format(
                wmf_file_header_struct.file_type))
            print(u'Record size\t\t\t\t\t\t\t: {0:d}'.format(
                wmf_file_header_struct.record_size))

            print(u'Format version\t\t\t\t\t\t\t: {0:d}'.format(
                wmf_file_header_struct.format_version))
            print(u'File size\t\t\t\t\t\t\t: {0:d}'.format(
                wmf_file_header_struct.file_size))
            print(u'Maximum number of object\t\t\t\t\t: {0:d}'.format(
                wmf_file_header_struct.maximum_number_of_objects))
            print(u'Largest record size\t\t\t\t\t\t: {0:d}'.format(
                wmf_file_header_struct.largest_record_size))
            print(u'Number of records\t\t\t\t\t\t: {0:d}'.format(
                wmf_file_header_struct.number_of_records))

            print(u'')

        if wmf_file_header_struct.file_type not in (1, 2):
            raise IOError(u'Unsupported file type: {0:d}'.format(
                wmf_file_header_struct.file_type))

        if wmf_file_header_struct.record_size != 9:
            raise IOError(u'Unsupported record size: {0:d}'.format(
                wmf_file_header_struct.record_size))
コード例 #8
0
ファイル: wemf.py プロジェクト: kalnyc1/assorted
    def _ReadRecord(self, file_offset):
        """Reads a record.

    Args:
      file_offset: an integer containing the file offset of the record.

    Raises:
      IOError: if the record cannot be read.
    """
        if self._debug:
            print(u'Seeking record offset: 0x{0:08x}'.format(file_offset))

        self._file_object.seek(file_offset, os.SEEK_SET)

        record_header_data_size = self._WMF_RECORD_HEADER.sizeof()
        record_header_data = self._file_object.read(record_header_data_size)

        if self._debug:
            print(u'Record header data:')
            print(hexdump.Hexdump(record_header_data))

        try:
            wmf_record_header_struct = self._WMF_RECORD_HEADER.parse(
                record_header_data)
        except construct.FieldError as exception:
            raise IOError((u'Unable to parse record header with error: {0:s}'
                           ).format(exception))

        record_size = wmf_record_header_struct.record_size * 2

        if self._debug:
            print(u'Record size\t\t\t\t\t\t\t: {0:d} ({1:d})'.format(
                wmf_record_header_struct.record_size, record_size))

            record_type_string = self._WMF_RECORD_TYPES.get(
                wmf_record_header_struct.record_type, u'UNKNOWN')
            print(u'Record type\t\t\t\t\t\t\t: 0x{0:04x} ({1:s})'.format(
                wmf_record_header_struct.record_type, record_type_string))

            print(u'')

        data_offset = file_offset + record_header_data_size
        data_size = record_size - record_header_data_size

        if self._debug:
            self._ReadRecordData(wmf_record_header_struct.record_type,
                                 data_size)

        return Record(wmf_record_header_struct.record_type, record_size,
                      data_offset, data_size)
コード例 #9
0
  def _ReadLruData(self):
    """Reads the LRU data."""
    lru_data = self._file_object.read(self._LRU_DATA.sizeof())

    if self._debug:
      print(u'Index file LRU data:')
      print(hexdump.Hexdump(lru_data))

    try:
      index_file_lru = self._LRU_DATA.parse(lru_data)
    except construct.FieldError as exception:
      raise IOError(u'Unable to parse LRU data with error: {0:s}'.format(
          exception))

    if self._debug:
      print(u'Filled flag\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(
          index_file_lru.get(u'filled_flag')))

      for value in index_file_lru.get(u'sizes'):
        print(u'Size\t\t\t\t\t\t\t\t\t: {0:d}'.format(value))

      cache_address_index = 0
      for value in index_file_lru.get(u'head_addresses'):
        cache_address = CacheAddress(value)
        print(u'Head address: {0:d}\t\t\t\t\t\t\t\t: {1:s}'.format(
            cache_address_index, cache_address.GetDebugString()))
        cache_address_index += 1

      cache_address_index = 0
      for value in index_file_lru.get(u'tail_addresses'):
        cache_address = CacheAddress(value)
        print(u'Tail address: {0:d}\t\t\t\t\t\t\t\t: {1:s}'.format(
            cache_address_index, cache_address.GetDebugString()))
        cache_address_index += 1

      cache_address = CacheAddress(index_file_lru.get(u'transaction_address'))
      print(u'Transaction address\t\t\t\t\t\t\t: {0:s}'.format(
          cache_address.GetDebugString()))

      print(u'Operation\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(
          index_file_lru.get(u'operation')))

      print(u'Operation list\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(
          index_file_lru.get(u'operation_list')))

      print(u'')
コード例 #10
0
ファイル: wemf.py プロジェクト: kalnyc1/assorted
    def _ReadRecordData(self, record_type, data_size):
        """Reads a record.

    Args:
      record_type (int): record type.
      data_size (int): size of the record data.

    Raises:
      IOError: if the record cannot be read.
    """
        record_data = self._file_object.read(data_size)

        if self._debug and data_size > 0:
            print(u'Record data:')
            print(hexdump.Hexdump(record_data))

        # TODO: use lookup dict with callback.
        struct_type = self._EMF_RECORD_DATA_STRUCT_TYPES.get(record_type, None)
        if not struct_type:
            return

        try:
            record_data_struct = struct_type.parse(record_data)
        except construct.FieldError as exception:
            raise IOError((u'Unable to parse record data with error: {0:s}'
                           ).format(exception))

        if self._debug:
            if record_type == 0x0018:
                print(u'Color\t\t\t\t\t\t\t\t: 0x{0:04x}'.format(
                    record_data_struct.color))

            elif record_type == 0x0025:
                stock_object_string = self._EMF_STOCK_OBJECTS.get(
                    record_data_struct.object_identifier, None)
                if stock_object_string:
                    print(u'Object identifier\t\t\t\t\t\t: 0x{0:08x} ({1:s})'.
                          format(record_data_struct.object_identifier,
                                 stock_object_string))
                else:
                    print(u'Object identifier\t\t\t\t\t\t: 0x{0:08x}'.format(
                        record_data_struct.object_identifier))

            print(u'')
コード例 #11
0
    def _ReadVolumePath(self, volume_path_record_data):
        """Reads the volume path.

    Args:
      volume_path_record_data: the volume path record data.

    Raises:
      IOError: if the volume path cannot be read.
    """
        try:
            volume_path_struct = self._VOLUME_PATH.parse(
                volume_path_record_data)
        except construct.FieldError as exception:
            raise IOError(
                u'Unable to parse volume path with error: {0:s}'.format(
                    exception))

        record_size = volume_path_struct.get(u'record_size')

        record_type = volume_path_struct.get(u'record_type')
        if record_type != 2:
            raise IOError(
                u'Unsupported record type: {0:d}'.format(record_type))

        if self._debug:
            print(u'Volume path record data:')
            print(hexdump.Hexdump(volume_path_record_data))

        try:
            # The struct includes the end-of-string character that we need
            # to strip off.
            self.volume_path = volume_path_struct.get(u'volume_path')
            self.volume_path = b''.join(self.volume_path).decode(u'utf16')[:-1]
        except UnicodeDecodeError as exception:
            self.volume_path = u''

        if self._debug:
            print(u'Record size\t\t\t\t\t\t\t\t: {0:d}'.format(record_size))
            print(u'Record type\t\t\t\t\t\t\t\t: {0:d} ({1:s})'.format(
                record_type, self._RECORD_TYPES.get(record_type, u'Unknown')))
            print(u'Volume path\t\t\t\t\t\t\t\t: {0:s}'.format(
                self.volume_path))
            print(u'')
コード例 #12
0
    def _ReadPage(self, page_size):
        """Reads the page.

    Args:
      page_size (int): page size.
    """
        page_data = self._file_object.read(page_size)

        try:
            page_header_struct = self._PAGE_HEADER.parse(page_data)
        except construct.FieldError as exception:
            raise IOError(
                u'Unable to parse file header with error: {0:s}'.format(
                    exception))

        page_header_data_size = 8 + (4 * page_header_struct.number_of_records)

        if self._debug:
            print(u'Page header data:')
            print(hexdump.Hexdump(page_data[:page_header_data_size]))

        if self._debug:
            print(u'Signature\t\t\t\t\t\t\t: 0x{0:08x}'.format(
                page_header_struct.signature))
            print(u'Number of records\t\t\t\t\t\t: {0:d}'.format(
                page_header_struct.number_of_records))

        record_offsets = []
        for record_index in range(page_header_struct.number_of_records):
            record_offsets.append(page_header_struct.offsets[record_index])

            if self._debug:
                print(u'Record: {0:d} offset\t\t\t\t\t\t: {1:d}'.format(
                    record_index, page_header_struct.offsets[record_index]))

        if self._debug:
            print(u'')

        for record_offset in iter(record_offsets):
            self._ParseRecord(page_data, record_offset)
コード例 #13
0
    def _ParseRecord(self, page_data, record_offset):
        """Reads a record from the page data.

    Args:
      page_data (bytes): page data.
      record_offset (int): record offset.
    """
        try:
            record_header_struct = self._RECORD_HEADER.parse(
                page_data[record_offset:])
        except construct.FieldError as exception:
            raise IOError(
                u'Unable to parse record header with error: {0:s}'.format(
                    exception))

        record_data_size = record_offset + record_header_struct.size

        if self._debug:
            print(u'Record data:')
            print(hexdump.Hexdump(page_data[record_offset:record_data_size]))

        if self._debug:
            print(u'Size\t\t\t\t\t\t\t\t: {0:d}'.format(
                record_header_struct.size))
            print(u'Unknown1\t\t\t\t\t\t\t: 0x{0:08x}'.format(
                record_header_struct.unknown1))
            print(u'Flags\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(
                record_header_struct.flags))
            print(u'Unknown2\t\t\t\t\t\t\t: 0x{0:08x}'.format(
                record_header_struct.unknown2))
            print(u'URL offset\t\t\t\t\t\t\t: {0:d}'.format(
                record_header_struct.url_offset))
            print(u'name offset\t\t\t\t\t\t\t: {0:d}'.format(
                record_header_struct.name_offset))
            print(u'path offset\t\t\t\t\t\t\t: {0:d}'.format(
                record_header_struct.path_offset))
            print(u'value offset\t\t\t\t\t\t\t: {0:d}'.format(
                record_header_struct.value_offset))
            print(u'Unknown3\t\t\t\t\t\t\t: 0x{0:08x}'.format(
                record_header_struct.unknown3))

            date_time = (datetime.datetime(2001, 1, 1) + datetime.timedelta(
                seconds=int(record_header_struct.expiration_time)))
            print(u'expiration time\t\t\t\t\t\t\t: {0!s} ({1:f})'.format(
                date_time, record_header_struct.expiration_time))

            date_time = (datetime.datetime(2001, 1, 1) + datetime.timedelta(
                seconds=int(record_header_struct.creation_time)))
            print(u'creation time\t\t\t\t\t\t\t: {0!s} ({1:f})'.format(
                date_time, record_header_struct.creation_time))

            print(u'')

            if record_header_struct.url_offset:
                data_offset = record_offset + record_header_struct.url_offset
                string = construct.CString(u'string').parse(
                    page_data[data_offset:record_data_size])
            else:
                sting = u''

            print(u'URL\t\t\t\t\t\t\t\t: {0:s}'.format(string))

            if record_header_struct.name_offset:
                data_offset = record_offset + record_header_struct.name_offset
                string = construct.CString(u'string').parse(
                    page_data[data_offset:record_data_size])
            else:
                sting = u''

            print(u'Name\t\t\t\t\t\t\t\t: {0:s}'.format(string))

            if record_header_struct.path_offset:
                data_offset = record_offset + record_header_struct.path_offset
                string = construct.CString(u'string').parse(
                    page_data[data_offset:record_data_size])
            else:
                sting = u''

            print(u'Path\t\t\t\t\t\t\t\t: {0:s}'.format(string))

            if record_header_struct.value_offset:
                data_offset = record_offset + record_header_struct.value_offset
                string = construct.CString(u'string').parse(
                    page_data[data_offset:record_data_size])
            else:
                sting = u''

            print(u'Value\t\t\t\t\t\t\t\t: {0:s}'.format(string))

            print(u'')
コード例 #14
0
  def _ReadEntry(self, file_offset):
    """Reads an entry.

    Args:
      file_offset (int): entry offset relative to the start of the file.

    Returns:
      int: size of the entry.

    Raises:
      IOError: if the entry cannot be read.
    """
    if self._debug:
      print(u'Seeking entry at offset: 0x{0:08x}'.format(file_offset))

    self._file_object.seek(file_offset, os.SEEK_SET)

    entry_struct_size = self._UTMP_ENTRY.sizeof()
    entry_data = self._file_object.read(entry_struct_size)
    file_offset += entry_struct_size

    if self._debug:
      print(u'Entry data:')
      print(hexdump.Hexdump(entry_data))

    try:
      entry_struct = self._UTMP_ENTRY.parse(entry_data)
    except construct.FieldError as exception:
      raise IOError((
          u'Unable to parse entry data section with error: '
          u'{0:s}').file_format(exception))

    if self._debug:
      print(u'Type\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(entry_struct.type))
      print(u'PID\t\t\t\t\t\t\t\t: {0:d}'.format(entry_struct.pid))

      terminal = entry_struct.terminal.replace(u'\0', '')
      print(u'Terminal\t\t\t\t\t\t\t: {0:s}'.format(terminal))
      print(u'Terminal ID\t\t\t\t\t\t\t: {0:d}'.format(entry_struct.terminal_id))

      username = entry_struct.username.replace(u'\0', '')
      print(u'Username\t\t\t\t\t\t\t: {0:s}'.format(username))

      hostname = entry_struct.hostname.replace(u'\0', '')
      print(u'Hostname\t\t\t\t\t\t\t: {0:s}'.format(hostname))
      print(u'Termination\t\t\t\t\t\t\t: 0x{0:04x}'.format(entry_struct.termination))
      print(u'Exit\t\t\t\t\t\t\t\t: 0x{0:04x}'.format(entry_struct.exit))
      print(u'Session\t\t\t\t\t\t\t\t: {0:d}'.format(entry_struct.session))

      date_time = (datetime.datetime(1970, 1, 1) + datetime.timedelta(
          seconds=int(entry_struct.timestamp)))
      print(u'Timestamp\t\t\t\t\t\t\t: {0!s} ({1:d})'.format(
          date_time, entry_struct.timestamp))

      print(u'Micro seconds\t\t\t\t\t\t\t: {0:d}'.format(entry_struct.micro_seconds))
      print(u'Address A\t\t\t\t\t\t\t: 0x{0:08x}'.format(entry_struct.address_a))
      print(u'Address B\t\t\t\t\t\t\t: 0x{0:08x}'.format(entry_struct.address_b))
      print(u'Address C\t\t\t\t\t\t\t: 0x{0:08x}'.format(entry_struct.address_c))
      print(u'Address D\t\t\t\t\t\t\t: 0x{0:08x}'.format(entry_struct.address_d))
      print(u'')

    return entry_struct_size
コード例 #15
0
    def _ReadFixedSizeDataSection(self):
        """Reads the fixed size data section.

    Raises:
      IOError: if the fixed size data section cannot be read.
    """
        if self._debug:
            print(
                u'Seeking fixed size data section offset: 0x{0:08x}'.format(0))

        self._file_object.seek(0, os.SEEK_SET)

        fixed_size_data = self._file_object.read(
            self._JOB_FIXED_SIZE_DATA_STRUCT.sizeof())

        if self._debug:
            print(u'Fixed size data:')
            print(hexdump.Hexdump(fixed_size_data))

        try:
            job_fixed_size_data_struct = self._JOB_FIXED_SIZE_DATA_STRUCT.parse(
                fixed_size_data)
        except construct.FieldError as exception:
            raise IOError(
                (u'Unable to parse fixed size data section with error: '
                 u'{0:s}').format(exception))

        if self._debug:
            print(u'Product version\t\t\t\t\t\t\t: 0x{0:04x}'.format(
                job_fixed_size_data_struct.product_version))
            print(u'Format version\t\t\t\t\t\t\t: 0x{0:04x}'.format(
                job_fixed_size_data_struct.format_version))

            uuid_object = uuid.UUID(
                bytes_le=job_fixed_size_data_struct.job_identifier)
            print(u'Job identifier\t\t\t\t\t\t\t: {0!s}'.format(uuid_object))

            print(u'Application name size offset\t\t\t\t\t: 0x{0:04x}'.format(
                job_fixed_size_data_struct.application_name_size_offset))
            print(u'Trigger offset\t\t\t\t\t\t\t: 0x{0:04x}'.format(
                job_fixed_size_data_struct.trigger_offset))

            print(u'Error retry count\t\t\t\t\t\t: {0:d}'.format(
                job_fixed_size_data_struct.error_retry_count))
            print(u'Error retry interval\t\t\t\t\t\t: {0:d} minutes'.format(
                job_fixed_size_data_struct.error_retry_interval))
            print(u'Idle deadline\t\t\t\t\t\t\t: {0:d} minutes'.format(
                job_fixed_size_data_struct.idle_deadline))
            print(u'Idle wait\t\t\t\t\t\t\t: {0:d} minutes'.format(
                job_fixed_size_data_struct.idle_wait))
            print(u'Priority\t\t\t\t\t\t\t: 0x{0:08x}'.format(
                job_fixed_size_data_struct.priority))
            print(u'Maximum run time\t\t\t\t\t\t: {0:d} milliseconds'.format(
                job_fixed_size_data_struct.maximum_run_time))
            print(u'Exit code\t\t\t\t\t\t\t: 0x{0:08x}'.format(
                job_fixed_size_data_struct.exit_code))
            print(u'Status\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(
                job_fixed_size_data_struct.status))
            print(u'Flags\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(
                job_fixed_size_data_struct.flags))

            print(u'Year\t\t\t\t\t\t\t\t: {0:d}'.format(
                job_fixed_size_data_struct.year))
            print(u'Month\t\t\t\t\t\t\t\t: {0:d}'.format(
                job_fixed_size_data_struct.month))
            print(u'Weekday\t\t\t\t\t\t\t\t: {0:d}'.format(
                job_fixed_size_data_struct.weekday))
            print(u'Day\t\t\t\t\t\t\t\t: {0:d}'.format(
                job_fixed_size_data_struct.day))
            print(u'Hours\t\t\t\t\t\t\t\t: {0:d}'.format(
                job_fixed_size_data_struct.hours))
            print(u'Minutes\t\t\t\t\t\t\t\t: {0:d}'.format(
                job_fixed_size_data_struct.minutes))
            print(u'Seconds\t\t\t\t\t\t\t\t: {0:d}'.format(
                job_fixed_size_data_struct.seconds))
            print(u'Milliseconds\t\t\t\t\t\t\t: {0:d}'.format(
                job_fixed_size_data_struct.milliseconds))

            print(u'')
コード例 #16
0
  def _ReadDestListEntry(self, olecf_item, stream_offset):
    """Reads a DestList stream entry.

    Args:
      olecf_item: the OLECF item (instance of pyolecf.item).
      stream_offset: an integer containing the stream offset of the entry.

    Returns:
      An integer containing the entry data size.

    Raises:
      IOError: if the DestList stream entry cannot be read.
    """
    if self._format_version == 1:
      dest_list_entry = self._DEST_LIST_STREAM_ENTRY_V1
    elif self._format_version >= 3:
      dest_list_entry = self._DEST_LIST_STREAM_ENTRY_V3

    if self._debug:
      print(u'Reading entry at offset: 0x{0:08x}'.format(stream_offset))

    entry_data = olecf_item.read(dest_list_entry.sizeof())

    if self._debug:
      print(u'Entry data:')
      print(hexdump.Hexdump(entry_data))

    try:
      dest_list_entry_struct = dest_list_entry.parse(entry_data)
    except construct.FieldError as exception:
      raise IOError((
          u'Unable to parse entry with error: {0:s}').format(exception))

    entry_path_size = dest_list_entry_struct.path_size * 2

    if self._debug:
      print(u'Unknown1\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(
          dest_list_entry_struct.unknown1))

      try:
        uuid_object = uuid.UUID(
            bytes_le=dest_list_entry_struct.droid_volume_identifier)
        print(u'Droid volume identifier\t\t\t\t\t\t\t: {0:s}'.format(
            uuid_object))
      except (TypeError, ValueError):
        pass

      try:
        uuid_object = uuid.UUID(
            bytes_le=dest_list_entry_struct.droid_file_identifier)
        print(u'Droid file identifier\t\t\t\t\t\t\t: {0:s}'.format(
            uuid_object))
      except (TypeError, ValueError):
        pass

      try:
        uuid_object = uuid.UUID(
            bytes_le=dest_list_entry_struct.birth_droid_volume_identifier)
        print(u'Birth droid volume identifier\t\t\t\t\t\t: {0:s}'.format(
            uuid_object))
      except (TypeError, ValueError):
        pass

      try:
        uuid_object = uuid.UUID(
            bytes_le=dest_list_entry_struct.birth_droid_file_identifier)
        print(u'Birth droid file identifier\t\t\t\t\t\t: {0:s}'.format(
            uuid_object))
      except (TypeError, ValueError):
        pass

      hostname = dest_list_entry_struct.hostname
      hostname, _, _ = hostname.partition(u'\x00')
      print(u'Hostname\t\t\t\t\t\t\t\t: {0:s}'.format(hostname))

      print(u'Entry number\t\t\t\t\t\t\t\t: {0:d}'.format(
          dest_list_entry_struct.entry_number))
      print(u'Unknown2\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(
          dest_list_entry_struct.unknown2))
      print(u'Unknown3\t\t\t\t\t\t\t\t: {0:f}'.format(
          dest_list_entry_struct.unknown3))
      print(u'Last modification time\t\t\t\t\t\t\t: {0!s}'.format(
          FromFiletime(dest_list_entry_struct.last_modification_time)))

      # TODO: debug print pin status.
      print(u'Pin status\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(
          dest_list_entry_struct.pin_status))

      if self._format_version >= 3:
        print(u'Unknown4\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(
            dest_list_entry_struct.unknown4))
        print(u'Unknown5\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(
            dest_list_entry_struct.unknown5))
        print(u'Unknown6\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(
            dest_list_entry_struct.unknown6))

      print(u'Path size\t\t\t\t\t\t\t\t: {0:d} ({1:d})'.format(
          dest_list_entry_struct.path_size, entry_path_size))

      print(u'')

    entry_path_data = olecf_item.read(entry_path_size)

    if self._debug:
      print(u'Entry path data:')
      print(hexdump.Hexdump(entry_path_data))

    try:
      path_string = entry_path_data.decode(u'utf16')
    except UnicodeDecodeError as exception:
      path_string = u''

    if self._debug:
      print(u'Path string\t\t\t\t\t\t\t\t: {0:s}'.format(path_string))
      print(u'')

    entry_footer_data = b''
    if self._format_version >= 3:
      entry_footer_data = olecf_item.read(4)

      if self._debug:
        print(u'Entry footer data:')
        print(hexdump.Hexdump(entry_footer_data))

    return len(entry_data) + len(entry_path_data) + len(entry_footer_data)
コード例 #17
0
ファイル: wemf.py プロジェクト: kalnyc1/assorted
    def _ReadRecordData(self, record_type, data_size):
        """Reads a record.

    Args:
      record_type (int): record type.
      data_size (int): size of the record data.

    Raises:
      IOError: if the record cannot be read.
    """
        record_data = self._file_object.read(data_size)

        if self._debug and data_size > 0:
            print(u'Record data:')
            print(hexdump.Hexdump(record_data))

        # TODO: use lookup dict with callback.
        struct_type = self._WMF_RECORD_DATA_STRUCT_TYPES.get(record_type, None)
        if not struct_type:
            return

        try:
            record_data_struct = struct_type.parse(record_data)
        except construct.FieldError as exception:
            raise IOError((u'Unable to parse record data with error: {0:s}'
                           ).format(exception))

        if self._debug:
            if record_type == 0x0103:
                map_mode_string = self._WMF_MAP_MODES.get(
                    record_data_struct.map_mode, u'UNKNOWN')
                print(u'Map mode\t\t\t\t\t\t\t: 0x{0:04x} ({1:s})'.format(
                    record_data_struct.map_mode, map_mode_string))

            elif record_type == 0x0107:
                stretch_mode_string = self._WMF_STRETCH_MODES.get(
                    record_data_struct.stretch_mode, u'UNKNOWN')
                print(u'Stretch mode\t\t\t\t\t\t\t: 0x{0:04x} ({1:s})'.format(
                    record_data_struct.stretch_mode, stretch_mode_string))

            elif record_type == 0x0127:
                print(
                    u'Number of saved device context\t\t\t\t\t: {0:d}'.format(
                        record_data_struct.number_of_saved_device_context))

            elif record_type in (0x020b, 0x020c):
                print(u'X coordinate\t\t\t\t\t\t\t: {0:d}'.format(
                    record_data_struct.x_coordinate))
                print(u'Y coordinate\t\t\t\t\t\t\t: {0:d}'.format(
                    record_data_struct.y_coordinate))

            elif record_type == 0x0b41:
                raster_operation_string = self._WMF_RASTER_OPERATIONS.get(
                    record_data_struct.raster_operation, u'UNKNOWN')
                print(
                    u'Raster operation\t\t\t\t\t\t: 0x{0:08x} ({1:s})'.format(
                        record_data_struct.raster_operation,
                        raster_operation_string))

                print(u'Source height\t\t\t\t\t\t\t: {0:d}'.format(
                    record_data_struct.source_height))
                print(u'Source width\t\t\t\t\t\t\t: {0:d}'.format(
                    record_data_struct.source_width))
                print(u'Source X coordinate\t\t\t\t\t\t: {0:d}'.format(
                    record_data_struct.source_x_coordinate))
                print(u'Source Y coordinate\t\t\t\t\t\t: {0:d}'.format(
                    record_data_struct.source_y_coordinate))

                print(u'Destination height\t\t\t\t\t\t: {0:d}'.format(
                    record_data_struct.destination_height))
                print(u'Destination width\t\t\t\t\t\t: {0:d}'.format(
                    record_data_struct.destination_width))
                print(u'Destination X coordinate\t\t\t\t\t: {0:d}'.format(
                    record_data_struct.destination_x_coordinate))
                print(u'Destination Y coordinate\t\t\t\t\t: {0:d}'.format(
                    record_data_struct.destination_y_coordinate))

            print(u'')
コード例 #18
0
    def _ReadChangeLogEntry(self):
        """Reads a change log entry.

    Returns:
      A change log entry (instance of ChangeLogEntry).

    Raises:
      IOError: if the change log entry cannot be read.
    """
        file_offset = self._file_object.tell()

        try:
            change_log_entry_struct = self._CHANGE_LOG_ENTRY.parse_stream(
                self._file_object)
        except construct.FieldError as exception:
            raise IOError(
                u'Unable to parse change log entry with error: {0:s}'.format(
                    exception))

        record_size = change_log_entry_struct.get(u'record_size')

        record_type = change_log_entry_struct.get(u'record_type')
        if record_type != 1:
            raise IOError(
                u'Unsupported record type: {0:d}'.format(record_type))

        signature = change_log_entry_struct.get(u'signature')
        if signature != self.SIGNATURE:
            raise IOError(u'Unsupported change.log file signature')

        change_log_entry = ChangeLogEntry()
        change_log_entry.entry_type = change_log_entry_struct.get(
            u'entry_type')
        change_log_entry.entry_flags = change_log_entry_struct.get(
            u'entry_flags')
        change_log_entry.file_attribute_flags = change_log_entry_struct.get(
            u'file_attribute_flags')
        change_log_entry.sequence_number = change_log_entry_struct.get(
            u'sequence_number')

        try:
            # The struct includes the end-of-string character that we need
            # to strip off.
            process_name = change_log_entry_struct.get(u'process_name')
            process_name = b''.join(process_name).decode(u'utf16')[:-1]
        except UnicodeDecodeError as exception:
            process_name = u''

        change_log_entry.process_name = process_name

        self._file_object.seek(file_offset, os.SEEK_SET)

        change_log_entry_record_data = self._file_object.read(record_size)

        if self._debug:
            print(u'Change log entry record data:')
            print(hexdump.Hexdump(change_log_entry_record_data))

        if self._debug:
            print(u'Record size\t\t\t\t\t\t\t\t: {0:d}'.format(record_size))
            print(u'Record type\t\t\t\t\t\t\t\t: {0:d} ({1:s})'.format(
                record_type, self._RECORD_TYPES.get(record_type, u'Unknown')))
            print(u'Signature\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(signature))
            print(u'Entry type\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(
                change_log_entry.entry_type))
            for flag, description in self.LOG_ENTRY_TYPES.items():
                if change_log_entry.entry_type & flag:
                    print(u'\t{0:s}'.format(description))
            print(u'')

            print(u'Entry flags\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(
                change_log_entry.entry_flags))
            for flag, description in self.LOG_ENTRY_FLAGS.items():
                if change_log_entry.entry_flags & flag:
                    print(u'\t{0:s}'.format(description))
            print(u'')

            print(u'File attribute flags\t\t\t\t\t\t\t: 0x{0:08x}'.format(
                change_log_entry.file_attribute_flags))
            # TODO: print flags.

            print(u'Sequence number\t\t\t\t\t\t\t\t: {0:d}'.format(
                change_log_entry.sequence_number))
            print(u'Process name data size\t\t\t\t\t\t\t: 0x{0:08x}'.format(
                change_log_entry_struct.get(u'process_name_data_size')))
            print(u'Unknown1\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(
                change_log_entry_struct.get(u'unknown1')))
            print(u'Process name\t\t\t\t\t\t\t\t: {0:s}'.format(
                change_log_entry.process_name))

        sub_record_data_offset = (change_log_entry_struct.sub_record_data -
                                  file_offset)
        sub_record_data_size = record_size - 4
        if self._debug:
            print(u'Sub record data offset\t\t\t\t\t\t\t: {0:d}'.format(
                sub_record_data_offset))
            print(u'Sub record data size\t\t\t\t\t\t\t: {0:d}'.format(
                sub_record_data_size - sub_record_data_offset))
            if sub_record_data_offset < sub_record_data_size:
                print(u'')

        while sub_record_data_offset < sub_record_data_size:
            read_size = self._ReadRecord(change_log_entry_record_data,
                                         sub_record_data_offset)
            if read_size == 0:
                break
            sub_record_data_offset += read_size

        copy_of_record_size = construct.ULInt32(u'record_size').parse(
            change_log_entry_record_data[-4:])
        if record_size != copy_of_record_size:
            raise IOError(u'Record size mismatch ({0:d} != {1:d})'.format(
                record_size, copy_of_record_size))

        if self._debug:
            print(u'Copy of record size\t\t\t\t\t\t\t: {0:d}'.format(
                copy_of_record_size))
            print(u'')

        return change_log_entry
コード例 #19
0
    def _ReadFileHeader(self):
        """Reads the file header.

    Raises:
      IOError: if the file header cannot be read.
    """
        if self._debug:
            print(u'Seeking file header offset: 0x{0:08x}'.format(0))

        self._file_object.seek(0, os.SEEK_SET)

        try:
            file_header_struct = self._FILE_HEADER.parse_stream(
                self._file_object)
        except construct.FieldError as exception:
            raise IOError(
                u'Unable to parse file header with error: {0:s}'.format(
                    exception))

        signature = file_header_struct.get(u'signature')
        if signature != self.SIGNATURE:
            raise IOError(u'Unsupported change.log file signature')

        record_size = file_header_struct.get(u'record_size')

        record_type = file_header_struct.get(u'record_type')
        if record_type != 0:
            raise IOError(
                u'Unsupported record type: {0:d}'.format(record_type))

        format_version = file_header_struct.get(u'format_version')
        if format_version != 2:
            raise IOError(
                u'Unsupported change.log format version: {0:d}'.format(
                    format_version))

        self._file_object.seek(0, os.SEEK_SET)

        file_header_data = self._file_object.read(record_size)

        if self._debug:
            print(u'File header data:')
            print(hexdump.Hexdump(file_header_data))

        if self._debug:
            print(u'Record size\t\t\t\t\t\t\t\t: {0:d}'.format(record_size))
            print(u'Record type\t\t\t\t\t\t\t\t: {0:d} ({1:s})'.format(
                record_type, self._RECORD_TYPES.get(record_type, u'Unknown')))
            print(u'Signature\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(signature))
            print(u'Format version\t\t\t\t\t\t\t\t: {0:d}'.format(
                format_version))

        self._ReadVolumePath(file_header_data[16:-4])

        copy_of_record_size = construct.ULInt32(u'record_size').parse(
            file_header_data[-4:])
        if record_size != copy_of_record_size:
            raise IOError(u'Record size mismatch ({0:d} != {1:d})'.format(
                record_size, copy_of_record_size))

        if self._debug:
            print(u'Copy of record size\t\t\t\t\t\t\t: {0:d}'.format(
                copy_of_record_size))
            print(u'')
コード例 #20
0
  def _ReadFileHeader(self):
    """Reads the file header.

    Raises:
      IOError: if the file header cannot be read.
    """
    if self._debug:
      print(u'Seeking file header offset: 0x{0:08x}'.format(0))

    self._file_object.seek(0, os.SEEK_SET)

    file_header_data = self._file_object.read(self._FILE_HEADER.sizeof())

    if self._debug:
      print(u'Index file header data:')
      print(hexdump.Hexdump(file_header_data))

    try:
      file_header = self._FILE_HEADER.parse(file_header_data)
    except construct.FieldError as exception:
      raise IOError(u'Unable to parse file header with error: {0:s}'.format(
          exception))

    signature = file_header.get(u'signature')

    if signature != self.SIGNATURE:
      raise IOError(u'Unsupported index file signature')

    self.version = u'{0:d}.{1:d}'.format(
        file_header.get(u'major_version'),
        file_header.get(u'minor_version'))

    if self.version not in [u'2.0', u'2.1']:
      raise IOError(u'Unsupported index file version: {0:s}'.format(
          self.version))

    self.creation_time = file_header.get(u'creation_time')

    if self._debug:
      print(u'Signature\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(signature))

      print(u'Version\t\t\t\t\t\t\t\t\t: {0:s}'.format(self.version))

      print(u'Number of entries\t\t\t\t\t\t\t: {0:d}'.format(
          file_header.get(u'number_of_entries')))

      print(u'Stored data size\t\t\t\t\t\t\t: {0:d}'.format(
          file_header.get(u'stored_data_size')))

      print(u'Last created file number\t\t\t\t\t\t: f_{0:06x}'.format(
          file_header.get(u'last_created_file_number')))

      print(u'Unknown1\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(
          file_header.get(u'unknown1')))

      print(u'Unknown2\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(
          file_header.get(u'unknown2')))

      print(u'Table size\t\t\t\t\t\t\t\t: {0:d}'.format(
          file_header.get(u'table_size')))

      print(u'Unknown3\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(
          file_header.get(u'unknown3')))

      print(u'Unknown4\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(
          file_header.get(u'unknown4')))

      date_string = (
          datetime.datetime(1601, 1, 1) +
          datetime.timedelta(microseconds=self.creation_time))

      print(u'Creation time\t\t\t\t\t\t\t\t: {0!s} (0x{1:08x})'.format(
          date_string, self.creation_time))

      print(u'')
コード例 #21
0
    def _ReadRecord(self, record_data, record_data_offset):
        """Reads a record.

    Args:
      record_data: the record data.
      record_data_offset: the record data offset.

    Returns:
      The record size.

    Raises:
      IOError: if the record cannot be read.
    """
        try:
            record_header_struct = self._RECORD_HEADER.parse(
                record_data[record_data_offset:])
        except construct.FieldError as exception:
            raise IOError(
                u'Unable to parse record header with error: {0:s}'.format(
                    exception))

        record_size = record_header_struct.get(u'record_size')
        record_type = record_header_struct.get(u'record_type')

        if self._debug:
            print(u'Record data:')
            print(
                hexdump.Hexdump(
                    record_data[record_data_offset:record_data_offset +
                                record_size]))

        if self._debug:
            print(u'Record size\t\t\t\t\t\t\t\t: {0:d}'.format(record_size))
            print(u'Record type\t\t\t\t\t\t\t\t: {0:d} ({1:s})'.format(
                record_type, self._RECORD_TYPES.get(record_type, u'Unknown')))

        record_data_offset += self._RECORD_HEADER.sizeof()

        if record_type in [4, 5, 9]:
            try:
                utf16_stream = self._UTF16_STREAM.parse(
                    record_data[record_data_offset:])
            except construct.FieldError as exception:
                raise IOError(
                    u'Unable to parse UTF-16 stream with error: {0:s}'.format(
                        exception))

            try:
                # The UTF-16 stream includes the end-of-string character that we need
                # to strip off.
                value_string = b''.join(utf16_stream).decode(u'utf16')[:-1]
            except UnicodeDecodeError as exception:
                value_string = u''

        # TODO: add support for other record types.
        # TODO: store record values in runtime objects.

        if self._debug:
            if record_type == 4:
                print(u'Secondary path\t\t\t\t\t\t\t\t: {0:s}'.format(
                    value_string))
            elif record_type == 5:
                print(u'Backup filename\t\t\t\t\t\t\t\t: {0:s}'.format(
                    value_string))
            elif record_type == 9:
                print(u'Short filename\t\t\t\t\t\t\t\t: {0:s}'.format(
                    value_string))

            print(u'')

        return record_size
コード例 #22
0
  def _ReadFileHeader(self):
    """Reads the file header.

    Raises:
      IOError: if the file header cannot be read.
    """
    if self._debug:
      print(u'Seeking file header offset: 0x{0:08x}'.format(0))

    self._file_object.seek(0, os.SEEK_SET)

    file_header_data = self._file_object.read(self._FILE_HEADER.sizeof())

    if self._debug:
      print(u'Data block file header data:')
      print(hexdump.Hexdump(file_header_data))

    try:
      file_header = self._FILE_HEADER.parse(file_header_data)
    except construct.FieldError as exception:
      raise IOError(u'Unable to parse file header with error: {0:s}'.format(
          exception))

    signature = file_header.get(u'signature')

    if signature != self.SIGNATURE:
      raise IOError(u'Unsupported data block file signature')

    self.version = u'{0:d}.{1:d}'.format(
        file_header.get(u'major_version'),
        file_header.get(u'minor_version'))

    if self.version not in [u'2.0', u'2.1']:
      raise IOError(u'Unsupported data block file version: {0:s}'.format(
          self.version))

    self.version = u'{0:d}.{1:d}'.format(
        file_header.get(u'major_version'), file_header.get(u'minor_version'))

    self.block_size = file_header.get(u'block_size')
    self.number_of_entries = file_header.get(u'number_of_entries')

    if self._debug:
      print(u'Signature\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(signature))

      print(u'Version\t\t\t\t\t\t\t\t\t: {0:s}'.format(self.version))

      print(u'File number\t\t\t\t\t\t\t\t: {0:d}'.format(
          file_header.get(u'file_number')))

      print(u'Next file number\t\t\t\t\t\t\t: {0:d}'.format(
          file_header.get(u'next_file_number')))

      print(u'Block size\t\t\t\t\t\t\t\t: {0:d}'.format(self.block_size))

      print(u'Number of entries\t\t\t\t\t\t\t: {0:d}'.format(
          self.number_of_entries))

      print(u'Maximum number of entries\t\t\t\t\t\t: {0:d}'.format(
          file_header.get(u'maximum_number_of_entries')))

      # TODO: print emtpy, hints, updating and user.

      block_number = 0
      block_range_start = 0
      block_range_end = 0
      in_block_range = False
      for value_32bit in file_header.get(u'allocation_bitmap'):
        for unused_bit in range(0, 32):
          if value_32bit & 0x00000001:
            if not in_block_range:
              block_range_start = block_number
              block_range_end = block_number
              in_block_range = True

            block_range_end += 1

          elif in_block_range:
            in_block_range = False

            if self._debug:
              print(u'Block range\t: {0:d} - {1:d} ({2:d})'.format(
                  block_range_start, block_range_end,
                  block_range_end - block_range_start))

          value_32bit >>= 1
          block_number += 1

      print(u'')
コード例 #23
0
ファイル: cpio.py プロジェクト: kalnyc1/assorted
  def _ReadFileEntry(self, file_offset):
    """Reads a file entry.

    Args:
      file_offset (int): current file offset.

    Raises:
      IOError: if the file entry cannot be read.
    """
    if self._debug:
      print(u'Seeking file entry at offset: 0x{0:08x}'.format(file_offset))

    self._file_object.seek(file_offset, os.SEEK_SET)

    if self.file_format == u'bin-big-endian':
      file_entry_struct = self._CPIO_BINARY_BIG_ENDIAN_FILE_ENTRY_STRUCT
    elif self.file_format == u'bin-little-endian':
      file_entry_struct = self._CPIO_BINARY_LITTLE_ENDIAN_FILE_ENTRY_STRUCT
    elif self.file_format == u'odc':
      file_entry_struct = self._CPIO_PORTABLE_ASCII_FILE_ENTRY_STRUCT
    elif self.file_format in (u'crc', u'newc'):
      file_entry_struct = self._CPIO_NEW_ASCII_FILE_ENTRY_STRUCT

    file_entry_struct_size = file_entry_struct.sizeof()
    file_entry_data = self._file_object.read(file_entry_struct_size)
    file_offset += file_entry_struct_size

    if self._debug:
      print(u'File entry data:')
      print(hexdump.Hexdump(file_entry_data))

    try:
      file_entry_struct = file_entry_struct.parse(file_entry_data)
    except construct.FieldError as exception:
      raise IOError((
          u'Unable to parse file entry data section with error: '
          u'{0:s}').file_format(exception))

    if self.file_format in (u'bin-big-endian', u'bin-little-endian'):
      inode_number = file_entry_struct.inode_number
      mode = file_entry_struct.mode
      user_identifier = file_entry_struct.user_identifier
      group_identifier = file_entry_struct.group_identifier

      modification_time = (
          (file_entry_struct.modification_time_upper << 16) |
          file_entry_struct.modification_time_lower)

      path_string_size = file_entry_struct.path_string_size

      file_size = (
          (file_entry_struct.file_size_upper << 16) |
          file_entry_struct.file_size_lower)

    elif self.file_format == u'odc':
      inode_number = int(file_entry_struct.inode_number, 8)
      mode = int(file_entry_struct.mode, 8)
      user_identifier = int(file_entry_struct.user_identifier, 8)
      group_identifier = int(file_entry_struct.group_identifier, 8)
      modification_time = int(file_entry_struct.modification_time, 8)
      path_string_size = int(file_entry_struct.path_string_size, 8)
      file_size = int(file_entry_struct.file_size, 8)

    elif self.file_format in (u'crc', u'newc'):
      inode_number = int(file_entry_struct.inode_number, 16)
      mode = int(file_entry_struct.mode, 16)
      user_identifier = int(file_entry_struct.user_identifier, 16)
      group_identifier = int(file_entry_struct.group_identifier, 16)
      modification_time = int(file_entry_struct.modification_time, 16)
      path_string_size = int(file_entry_struct.path_string_size, 16)
      file_size = int(file_entry_struct.file_size, 16)

    if self._debug:
      if self.file_format in (u'bin-big-endian', u'bin-little-endian'):
        print(u'Signature\t\t\t\t\t\t\t\t: 0x{0:04x}'.format(
            file_entry_struct.signature))
      else:
        print(u'Signature\t\t\t\t\t\t\t\t: {0!s}'.format(
            file_entry_struct.signature))

      if self.file_format not in (u'crc', u'newc'):
        if self.file_format in (u'bin-big-endian', u'bin-little-endian'):
          device_number = file_entry_struct.device_number
        elif self.file_format == u'odc':
          device_number = int(file_entry_struct.device_number, 8)

        print(u'Device number\t\t\t\t\t\t\t\t: {0:d}'.format(device_number))

      print(u'Inode number\t\t\t\t\t\t\t\t: {0:d}'.format(inode_number))
      print(u'Mode\t\t\t\t\t\t\t\t\t: {0:o}'.format(mode))

      print(u'User identifier (UID)\t\t\t\t\t\t\t: {0:d}'.format(
          user_identifier))

      print(u'Group identifier (GID)\t\t\t\t\t\t\t: {0:d}'.format(
          group_identifier))

      if self.file_format in (u'bin-big-endian', u'bin-little-endian'):
        number_of_links = file_entry_struct.number_of_links
      elif self.file_format == u'odc':
        number_of_links = int(file_entry_struct.number_of_links, 8)
      elif self.file_format in (u'crc', u'newc'):
        number_of_links = int(file_entry_struct.number_of_links, 16)

      print(u'Number of links\t\t\t\t\t\t\t\t: {0:d}'.format(number_of_links))

      if self.file_format not in (u'crc', u'newc'):
        if self.file_format in (u'bin-big-endian', u'bin-little-endian'):
          special_device_number = file_entry_struct.special_device_number
        elif self.file_format == u'odc':
          special_device_number = int(
              file_entry_struct.special_device_number, 8)

        print(u'Special device number\t\t\t\t\t\t\t\t: {0:d}'.format(
            special_device_number))

      print(u'Modification time\t\t\t\t\t\t\t: {0:d}'.format(modification_time))

      if self.file_format not in (u'crc', u'newc'):
        print(u'Path string size\t\t\t\t\t\t\t: {0:d}'.format(path_string_size))

      print(u'File size\t\t\t\t\t\t\t\t: {0:d}'.format(file_size))

      if self.file_format in (u'crc', u'newc'):
        device_major_number = int(file_entry_struct.device_major_number, 16)

        print(u'Device major number\t\t\t\t\t\t\t: {0:d}'.format(
            device_major_number))

        device_minor_number = int(file_entry_struct.device_minor_number, 16)

        print(u'Device minor number\t\t\t\t\t\t\t: {0:d}'.format(
            device_minor_number))

        special_device_major_number = int(
            file_entry_struct.special_device_major_number, 16)

        print(u'Special device major number\t\t\t\t\t\t: {0:d}'.format(
            special_device_major_number))

        special_device_minor_number = int(
            file_entry_struct.special_device_minor_number, 16)

        print(u'Special device minor number\t\t\t\t\t\t: {0:d}'.format(
            special_device_minor_number))

        print(u'Path string size\t\t\t\t\t\t\t: {0:d}'.format(path_string_size))

        checksum = int(file_entry_struct.checksum, 16)

        print(u'Checksum\t\t\t\t\t\t\t\t: 0x{0:08x}'.format(checksum))

    path_string_data = self._file_object.read(path_string_size)
    file_offset += path_string_size

    # TODO: should this be ASCII?
    path_string = path_string_data.decode(u'ascii')
    path_string, _, _ = path_string.partition(u'\x00')

    if self._debug:
      print(u'Path string\t\t\t\t\t\t\t\t: {0:s}'.format(path_string))

    if self.file_format in (u'bin-big-endian', u'bin-little-endian'):
      padding_size = file_offset % 2
      if padding_size > 0:
        padding_size = 2 - padding_size

    elif self.file_format == u'odc':
      padding_size = 0

    elif self.file_format in (u'crc', u'newc'):
      padding_size = file_offset % 4
      if padding_size > 0:
        padding_size = 4 - padding_size

    if self._debug:
      padding_data = self._file_object.read(padding_size)
      print(u'Path string alignment padding:')
      print(hexdump.Hexdump(padding_data))

    file_offset += padding_size

    file_entry = CPIOArchiveFileEntry(self._file_object)

    file_entry.data_offset = file_offset
    file_entry.data_size = file_size
    file_entry.group_identifier = group_identifier
    file_entry.inode_number = inode_number
    file_entry.modification_time = modification_time
    file_entry.path = path_string
    file_entry.mode = mode
    file_entry.size = (
        file_entry_struct_size + path_string_size + padding_size + file_size)
    file_entry.user_identifier = user_identifier

    if self.file_format in (u'crc', u'newc'):
      file_offset += file_size

      padding_size = file_offset % 4
      if padding_size > 0:
        padding_size = 4 - padding_size

      if self._debug:
        self._file_object.seek(file_offset, os.SEEK_SET)
        padding_data = self._file_object.read(padding_size)

        print(u'File data alignment padding:')
        print(hexdump.Hexdump(padding_data))

      file_entry.size += padding_size

    if self._debug:
      print(u'')

    return file_entry