コード例 #1
0
ファイル: dumpsgy.py プロジェクト: thecassion/PH5
def read_trace(n, l, f=5):
    ret = []
    if PRINT == True:
        for i in range(n):
            buf = FH.read(l)
            #   IBM floats - 4 byte - Must be big endian
            if f == 1:
                ret.append(
                    construct.BFloat32("x").parse(ibmfloat.ibm2ieee32(buf)))
            #   INT - 4 byte or 2 byte
            elif f == 2:
                if ENDIAN == 'little':
                    #   Swap 4 byte
                    b = construct.SLInt32("x").parse(buf)
                else:
                    b = construct.SBInt32("x").parse(buf)

                ret.append(b)
            elif f == 3:
                if ENDIAN == 'little':
                    #   Swap 2 byte
                    b = construct.SLInt16("x").parse(buf)
                else:
                    b = construct.SBInt16("x").parse(buf)

                ret.append(b)
            #   IEEE floats - 4 byte
            elif f == 5:
                if ENDIAN == 'little':
                    #   Swap 4 byte
                    b = construct.LFloat32("x").parse(buf)
                else:
                    b = construct.BFloat32("x").parse(buf)

                ret.append(b)
            #   INT - 1 byte
            elif f == 8:
                ret.append(construct.SBInt8("x").parse(buf))

    else:
        FH.read(n * l)

    return ret
コード例 #2
0
class TestRegValue(interface.WinRegValue):
    """Implementation of the Registry value interface for testing."""

    _INT32_BIG_ENDIAN = construct.SBInt32('value')
    _INT32_LITTLE_ENDIAN = construct.SLInt32('value')
    _INT64_LITTLE_ENDIAN = construct.SLInt64('value')

    def __init__(self, name, data, data_type, offset=0):
        """Set up the test reg value object."""
        super(TestRegValue, self).__init__()
        self._name = name
        self._data = data
        self._data_type = data_type
        self._offset = offset
        self._type_str = ''

    @property
    def name(self):
        """The name of the value."""
        return self._name

    @property
    def offset(self):
        """The offset of the value within the Windows Registry file."""
        return self._offset

    @property
    def data_type(self):
        """Numeric value that contains the data type."""
        return self._data_type

    @property
    def raw_data(self):
        """The value data as a byte string."""
        return self._data

    @property
    def data(self):
        """The value data as a native Python object."""
        if not self._data:
            return None

        if self._data_type in [self.REG_SZ, self.REG_EXPAND_SZ, self.REG_LINK]:
            try:
                return unicode(self._data.decode('utf-16-le'))
            except UnicodeError:
                pass

        elif self._data_type == self.REG_DWORD and len(self._data) == 4:
            return self._INT32_LITTLE_ENDIAN.parse(self._data)

        elif self._data_type == self.REG_DWORD_BIG_ENDIAN and len(
                self._data) == 4:
            return self._INT32_BIG_ENDIAN.parse(self._data)

        elif self._data_type == self.REG_QWORD and len(self._data) == 8:
            return self._INT64_LITTLE_ENDIAN.parse(self._data)

        elif self._data_type == self.REG_MULTI_SZ:
            try:
                utf16_string = unicode(self._data.decode('utf-16-le'))
                return filter(None, utf16_string.split('\x00'))
            except UnicodeError:
                pass

        return self._data
コード例 #3
0
ファイル: fake.py プロジェクト: SecurityTW/dfwinreg
class FakeWinRegistryValue(interface.WinRegistryValue):
    """Fake implementation of a Windows Registry value."""

    _INT32_BIG_ENDIAN = construct.SBInt32(u'value')
    _INT32_LITTLE_ENDIAN = construct.SLInt32(u'value')
    _INT64_LITTLE_ENDIAN = construct.SLInt64(u'value')

    def __init__(self, name, data=b'', data_type=0, offset=0):
        """Initializes a Windows Registry value object.

    Args:
      name: the name of the Windows Registry value.
      data: optional binary string containing the value data.
      data_type: optional integer containing the value data type.
      offset: optional offset of the value within the Windows Registry file.
    """
        super(FakeWinRegistryValue, self).__init__()
        self._data = data
        self._data_type = data_type
        self._data_size = len(data)
        self._name = name
        self._offset = offset

    @property
    def data(self):
        """The value data as a native Python object.

    Raises:
      WinRegistryValueError: if the value data cannot be read.
    """
        if not self._data:
            return None

        if self._data_type in self._STRING_VALUE_TYPES:
            try:
                return self._data.decode(u'utf-16-le')

            except UnicodeError as exception:
                raise errors.WinRegistryValueError(
                    u'Unable to read data from value: {0:s} with error: {1:s}'.
                    format(self._name, exception))

        elif (self._data_type == definitions.REG_DWORD
              and self._data_size == 4):
            return self._INT32_LITTLE_ENDIAN.parse(self._data)

        elif (self._data_type == definitions.REG_DWORD_BIG_ENDIAN
              and self._data_size == 4):
            return self._INT32_BIG_ENDIAN.parse(self._data)

        elif (self._data_type == definitions.REG_QWORD
              and self._data_size == 8):
            return self._INT64_LITTLE_ENDIAN.parse(self._data)

        elif self._data_type == definitions.REG_MULTI_SZ:
            try:
                utf16_string = self._data.decode(u'utf-16-le')
                return filter(None, utf16_string.split(u'\x00'))

            except UnicodeError as exception:
                raise errors.WinRegistryValueError(
                    u'Unable to read data from value: {0:s} with error: {1:s}'.
                    format(self._name, exception))

        return self._data

    @property
    def data_type(self):
        """Numeric value that contains the data type."""
        return self._data_type

    @property
    def name(self):
        """The name of the value."""
        return self._name

    @property
    def offset(self):
        """The offset of the value within the Windows Registry file."""
        return self._pyregf_value.offset

    @property
    def raw_data(self):
        """The value data as a byte string."""
        return self._data
コード例 #4
0
import construct as cons


class FrameAdapter(cons.Adapter):
    def _decode(self, obj, context):
        return Frame(context['_']['slp_file'], obj)


FRAME = cons.Struct(
    'frames',
    cons.ULInt32('cmd_table_offset'),
    cons.ULInt32('outline_table_offset'),
    cons.ULInt32('palette_offset'),
    cons.ULInt32('properties'),
    cons.SLInt32('width'),
    cons.SLInt32('height'),
    cons.SLInt32('hotspot_x'),
    cons.SLInt32('hotspot_y'),
)

HEADER = cons.Struct(
    'header',
    cons.String('version', 4),
    cons.ULInt32('num_frames'),
    cons.String('comment', 24),
    cons.Array(lambda ctx: ctx['num_frames'], FrameAdapter(FRAME)),
)


class ImageAdapter(object):
コード例 #5
0
class FakeWinRegistryValue(interface.WinRegistryValue):
  """Fake implementation of a Windows Registry value."""

  _INT32_BIG_ENDIAN = construct.SBInt32(u'value')
  _INT32_LITTLE_ENDIAN = construct.SLInt32(u'value')
  _INT64_LITTLE_ENDIAN = construct.SLInt64(u'value')

  def __init__(self, name, data=b'', data_type=definitions.REG_NONE, offset=0):
    """Initializes a Windows Registry value.

    Args:
      name (str): name of the Windows Registry value.
      data (Optional[bytes]): value data.
      data_type (Optional[int]): value data type.
      offset (Optional[int]): offset of the value within the Windows Registry
          file.
    """
    super(FakeWinRegistryValue, self).__init__()
    self._data = data
    self._data_type = data_type
    self._data_size = len(data)
    self._name = name
    self._offset = offset

  @property
  def data(self):
    """bytes: value data as a byte string."""
    return self._data

  @property
  def data_type(self):
    """int: data type."""
    return self._data_type

  @property
  def name(self):
    """str: name of the value."""
    return self._name

  @property
  def offset(self):
    """int: offset of the value within the Windows Registry file."""
    return self._offset

  def GetDataAsObject(self):
    """Retrieves the data as an object.

    Returns:
      object: data as a Python type.

    Raises:
      WinRegistryValueError: if the value data cannot be read.
    """
    if not self._data:
      return

    if self._data_type in self._STRING_VALUE_TYPES:
      try:
        return self._data.decode(u'utf-16-le')

      # AttributeError is raised when self._data has no decode method.
      except AttributeError as exception:
        raise errors.WinRegistryValueError((
            u'Unsupported data type: {0!s} of value: {1!s} with error: '
            u'{2!s}').format(type(self._data), self._name, exception))

      except UnicodeError as exception:
        raise errors.WinRegistryValueError(
            u'Unable to decode data of value: {0!s} with error: {1!s}'.format(
                self._name, exception))

    elif (self._data_type == definitions.REG_DWORD and
          self._data_size == 4):
      return self._INT32_LITTLE_ENDIAN.parse(self._data)

    elif (self._data_type == definitions.REG_DWORD_BIG_ENDIAN and
          self._data_size == 4):
      return self._INT32_BIG_ENDIAN.parse(self._data)

    elif (self._data_type == definitions.REG_QWORD and
          self._data_size == 8):
      return self._INT64_LITTLE_ENDIAN.parse(self._data)

    elif self._data_type == definitions.REG_MULTI_SZ:
      try:
        utf16_string = self._data.decode(u'utf-16-le')
        # TODO: evaluate the use of filter here is appropriate behavior.
        return list(filter(None, utf16_string.split(u'\x00')))

      # AttributeError is raised when self._data has no decode method.
      except AttributeError as exception:
        raise errors.WinRegistryValueError((
            u'Unsupported data type: {0!s} of value: {1!s} with error: '
            u'{2!s}').format(type(self._data), self._name, exception))

      except UnicodeError as exception:
        raise errors.WinRegistryValueError(
            u'Unable to read data from value: {0!s} with error: {1!s}'.format(
                self._name, exception))

    return self._data
コード例 #6
0
class _GzipMember(object):
    """Gzip member.

  Gzip files have no index of members, so each member must be read
  sequentially before metadata and random seeks are possible. This class
  provides caching of gzip member data during the initial read of each member.

  Attributes:
    comment (str): comment stored in the member.
    member_end_offset (int): offset to the end of the member in the parent file
        object.
    member_start_offset (int): offset to the start of the member in the parent
        file object.
    operating_system (int): type of file system on which the compression
        took place.
    original_filename (str): original filename of the uncompressed file.
    uncompressed_data_offset (int): offset of the start of the uncompressed
        data in this member relative to the whole gzip file's uncompressed data.
    uncompressed_data_size (int): total size of the data in this gzip member
        after decompression.
  """
    _MEMBER_HEADER_STRUCT = construct.Struct(
        'file_header', construct.ULInt16('signature'),
        construct.UBInt8('compression_method'), construct.UBInt8('flags'),
        construct.SLInt32('modification_time'),
        construct.UBInt8('extra_flags'), construct.UBInt8('operating_system'))

    _MEMBER_FOOTER_STRUCT = construct.Struct(
        'file_footer', construct.ULInt32('checksum'),
        construct.ULInt32('uncompressed_data_size'))

    _GZIP_SIGNATURE = 0x8b1f

    _COMPRESSION_METHOD_DEFLATE = 8

    _FLAG_FTEXT = 0x01
    _FLAG_FHCRC = 0x02
    _FLAG_FEXTRA = 0x04
    _FLAG_FNAME = 0x08
    _FLAG_FCOMMENT = 0x10

    # The maximum size of the uncompressed data cache.
    _UNCOMPRESSED_DATA_CACHE_SIZE = 2 * 1024 * 1024

    def __init__(self, file_object, member_start_offset,
                 uncompressed_data_offset):
        """Initializes a gzip member.

    Args:
      file_object (FileIO): file-like object, containing the gzip member.
      member_start_offset (int): offset to the beginning of the gzip member
          in the containing file.
      uncompressed_data_offset (int): current offset into the uncompressed data
          in the containing file.
    """
        self.comment = None
        self.modification_time = None
        self.operating_system = None
        self.original_filename = None

        # Offset into this member's uncompressed data of the first item in
        # the cache.
        self._cache_start_offset = None
        # Offset into this member's uncompressed data of the last item in
        # the cache.
        self._cache_end_offset = None
        self._cache = b''

        # Total size of the data in this gzip member after decompression.
        self.uncompressed_data_size = None
        # Offset of the start of the uncompressed data in this member relative to
        # the whole gzip file's uncompressed data.
        self.uncompressed_data_offset = uncompressed_data_offset

        # Offset to the start of the member in the parent file object.
        self.member_start_offset = member_start_offset

        # Initialize the member with data.
        self._file_object = file_object
        self._file_object.seek(self.member_start_offset, os.SEEK_SET)

        self._ReadAndParseHeader(file_object)
        # Offset to the beginning of the compressed data in the file object.
        self._compressed_data_start = file_object.get_offset()

        self._decompressor_state = _GzipDecompressorState(
            self._compressed_data_start)

        self._LoadDataIntoCache(file_object, 0, read_all_data=True)

        self._ReadAndParseFooter(file_object)

        # Offset to the end of the member in the parent file object.
        self.member_end_offset = file_object.get_offset()

    def GetCacheSize(self):
        """Determines the size of the uncompressed cached data.

    Returns:
      int: number of cached bytes.
    """
        if not self._cache_start_offset or not self._cache_end_offset:
            return 0
        return self._cache_end_offset - self._cache_start_offset

    def IsCacheFull(self):
        """Checks whether the uncompressed data cache is full.

    Returns:
      bool: True if the cache is full.
    """
        return self.GetCacheSize() >= self._UNCOMPRESSED_DATA_CACHE_SIZE

    def FlushCache(self):
        """Empties the cache that holds cached decompressed data."""
        self._cache = b''
        self._cache_start_offset = None
        self._cache_end_offset = None
        self._ResetDecompressorState()

    def _ResetDecompressorState(self):
        """Resets the state of the internal decompression object."""
        self._decompressor_state = _GzipDecompressorState(
            self._compressed_data_start)

    def ReadAtOffset(self, offset, size=None):
        """Reads a byte string from the gzip member at the specified offset.

    The function will read a byte string of the specified size or
    all of the remaining data if no size was specified.

    Args:
      offset (int): offset within the uncompressed data in this member to
        read from.
      size (Optional[int]): maximum number of bytes to read, where None
          represents all remaining data, to a maximum of the uncompressed
          cache size.

    Returns:
      bytes: data read.

    Raises:
      IOError: if the read failed.
      ValueError: if a negative read size or offset is specified.
    """
        if size is not None and size < 0:
            raise ValueError('Invalid size value {0!d}'.format(size))

        if offset < 0:
            raise ValueError('Invalid offset value {0!d}'.format(offset))

        if size == 0 or offset >= self.uncompressed_data_size:
            return b''

        if self._cache_start_offset is None:
            self._LoadDataIntoCache(self._file_object, offset)

        if offset > self._cache_end_offset or offset < self._cache_start_offset:
            self.FlushCache()
            self._LoadDataIntoCache(self._file_object, offset)

        cache_offset = offset - self._cache_start_offset
        if not size:
            return self._cache[cache_offset:]

        data_end_offset = cache_offset + size

        if data_end_offset > self._cache_end_offset:
            return self._cache[cache_offset:]

        return self._cache[cache_offset:data_end_offset]

    def _LoadDataIntoCache(self,
                           file_object,
                           minimum_offset,
                           read_all_data=False):
        """Reads and decompresses the data in the member.

    This function already loads as much data as possible in the cache, up to
    UNCOMPRESSED_DATA_CACHE_SIZE bytes.

    Args:
      file_object (FileIO): file-like object.
      minimum_offset (int): offset into this member's uncompressed data at
          which the cache should start.
      read_all_data (bool): True if all the compressed data should be read
          from the member.
    """
        # Decompression can only be performed from beginning to end of the stream.
        # So, if data before the current position of the decompressor in the stream
        # is required, it's necessary to throw away the current decompression
        # state and start again.
        if minimum_offset < self._decompressor_state.uncompressed_offset:
            self._ResetDecompressorState()

        while not self.IsCacheFull() or read_all_data:
            decompressed_data = self._decompressor_state.Read(file_object)
            decompressed_data_length = len(decompressed_data)
            decompressed_end_offset = self._decompressor_state.uncompressed_offset
            decompressed_start_offset = (decompressed_end_offset -
                                         decompressed_data_length)

            data_to_add = decompressed_data
            added_data_start_offset = decompressed_start_offset

            if decompressed_start_offset < minimum_offset:
                data_to_add = None

            if decompressed_start_offset < minimum_offset < decompressed_end_offset:
                data_add_offset = decompressed_end_offset - minimum_offset
                data_to_add = decompressed_data[-data_add_offset]
                added_data_start_offset = decompressed_end_offset - data_add_offset

            if not self.IsCacheFull() and data_to_add:
                self._cache = b''.join([self._cache, data_to_add])
                if self._cache_start_offset is None:
                    self._cache_start_offset = added_data_start_offset
                if self._cache_end_offset is None:
                    self._cache_end_offset = self._cache_start_offset + len(
                        data_to_add)
                else:
                    self._cache_end_offset += len(data_to_add)

            # If there's no more data in the member, the unused_data value is
            # populated in the decompressor. When this situation arises, we rewind
            # to the end of the compressed_data section.
            unused_data = self._decompressor_state.GetUnusedData()
            if unused_data:
                seek_offset = -len(unused_data)
                file_object.seek(seek_offset, os.SEEK_CUR)
                self._ResetDecompressorState()
                break

    def _ReadAndParseHeader(self, file_object):
        """Reads the member header and sets relevant member values.

    Args:
      file_object (FileIO): file-like object to read from.

    Raises:
      FileFormatError: if file format related errors are detected.
    """
        member_header = self._MEMBER_HEADER_STRUCT.parse_stream(file_object)

        if member_header.signature != self._GZIP_SIGNATURE:
            raise errors.FileFormatError(
                'Unsupported file signature: 0x{0:04x}.'.format(
                    member_header.signature))

        if member_header.compression_method != self._COMPRESSION_METHOD_DEFLATE:
            raise errors.FileFormatError(
                'Unsupported compression method: {0:d}.'.format(
                    member_header.compression_method))

        self.modification_time = member_header.modification_time
        self.operating_system = member_header.operating_system

        if member_header.flags & self._FLAG_FEXTRA:
            extra_field_data_size = construct.ULInt16(
                'extra_field_data_size').parse_stream(file_object)
            file_object.seek(extra_field_data_size, os.SEEK_CUR)

        if member_header.flags & self._FLAG_FNAME:
            # Since encoding is set construct will convert the C string to Unicode.
            # Note that construct 2 does not support the encoding to be a Unicode
            # string.
            self.original_filename = construct.CString(
                'original_filename',
                encoding=b'iso-8859-1').parse_stream(file_object)

        if member_header.flags & self._FLAG_FCOMMENT:
            # Since encoding is set construct will convert the C string to Unicode.
            # Note that construct 2 does not support the encoding to be a Unicode
            # string.
            self.comment = construct.CString(
                'comment', encoding=b'iso-8859-1').parse_stream(file_object)

        if member_header.flags & self._FLAG_FHCRC:
            file_object.read(2)

    def _ReadAndParseFooter(self, file_object):
        """Reads the member footer and sets relevant member values.

    Args:
      file_object (FileIO): file-like object to read from.

    Raises:
      FileFormatError: if file format related errors are detected.
    """
        file_footer = self._MEMBER_FOOTER_STRUCT.parse_stream(file_object)
        self.uncompressed_data_size = file_footer.uncompressed_data_size
コード例 #7
0
ファイル: gzip_file_io.py プロジェクト: thezedwards/dfvfs
class GzipFile(file_object_io.FileObjectIO):
  """Class that implements a file-like object of a gzip file.

     The gzip file is a zlib compressed data stream with additional metadata.
  """
  _FILE_HEADER_STRUCT = construct.Struct(
      u'file_header',
      construct.ULInt16(u'signature'),
      construct.UBInt8(u'compression_method'),
      construct.UBInt8(u'flags'),
      construct.SLInt32(u'modification_time'),
      construct.UBInt8(u'extra_flags'),
      construct.UBInt8(u'operating_system'))

  _FILE_FOOTER_STRUCT = construct.Struct(
      u'file_footer',
      construct.ULInt32(u'checksum'),
      construct.ULInt32(u'uncompressed_data_size'))

  _FILE_SIGNATURE = 0x8b1f

  _COMPRESSION_METHOD_DEFLATE = 8

  _FLAG_FTEXT = 0x01
  _FLAG_FHCRC = 0x02
  _FLAG_FEXTRA = 0x04
  _FLAG_FNAME = 0x08
  _FLAG_FCOMMENT = 0x10

  def __init__(self, resolver_context, file_object=None):
    """Initializes the file-like object.

    Args:
      resolver_context: the resolver context (instance of resolver.Context).
      file_object: optional file-like object. The default is None.

    Raises:
      ValueError: when file_object is set.
    """
    if file_object:
      raise ValueError(u'File object value set.')

    super(GzipFile, self).__init__(resolver_context)
    self._compressed_data_offset = -1
    self._compressed_data_size = -1
    self.comment = None
    self.modification_time = None
    self.operating_system = None
    self.original_filename = None
    self.uncompressed_data_size = 0

  def _ReadFileHeader(self, file_object):
    """Reads the file header.

    Args:
      file_object: the file-like object to read from.

    Raises:
      FileFormatError: if file format related errors are detected.
    """
    file_object.seek(0, os.SEEK_SET)
    file_header = self._FILE_HEADER_STRUCT.parse_stream(file_object)
    self._compressed_data_offset = file_object.get_offset()

    if file_header.signature != self._FILE_SIGNATURE:
      raise errors.FileFormatError(
          u'Unsuppored file signature: 0x{0:04x}.'.format(
              file_header.signature))

    if file_header.compression_method != self._COMPRESSION_METHOD_DEFLATE:
      raise errors.FileFormatError(
          u'Unsuppored compression method: {0:d}.'.format(
              file_header.compression_method))

    self.modification_time = file_header.modification_time
    self.operating_system = file_header.operating_system

    if file_header.flags & self._FLAG_FEXTRA:
      extra_field_data_size = construct.ULInt16(
          u'extra_field_data_size').parse_stream(file_object)
      file_object.seek(extra_field_data_size, os.SEEK_CUR)
      self._compressed_data_offset += 2 + extra_field_data_size

    if file_header.flags & self._FLAG_FNAME:
      # Since encoding is set construct will convert the C string to Unicode.
      # Note that construct 2 does not support the encoding to be a Unicode
      # string.
      self.original_filename = construct.CString(
          u'original_filename', encoding='iso-8859-1').parse_stream(
              file_object)
      self._compressed_data_offset = file_object.get_offset()

    if file_header.flags & self._FLAG_FCOMMENT:
      # Since encoding is set construct will convert the C string to Unicode.
      # Note that construct 2 does not support the encoding to be a Unicode
      # string.
      self.comment = construct.CString(
          u'comment', encoding='iso-8859-1').parse_stream(file_object)
      self._compressed_data_offset = file_object.get_offset()

    if file_header.flags & self._FLAG_FHCRC:
      self._compressed_data_offset += 2

    self._compressed_data_size = (
        file_object.get_size() - (self._compressed_data_offset + 8))

  def _ReadFileFooter(self, file_object):
    """Reads the file footer.

    Args:
      file_object: the file-like object to read from.

    Raises:
      FileFormatError: if file format related errors are detected.
    """
    file_object.seek(-8, os.SEEK_END)
    file_footer = self._FILE_FOOTER_STRUCT.parse_stream(file_object)

    self.uncompressed_data_size = file_footer.uncompressed_data_size

  def _OpenFileObject(self, path_spec):
    """Opens the file-like object defined by path specification.

    Args:
      path_spec: optional the path specification (instance of path.PathSpec).
                 The default is None.

    Returns:
      A file-like object.
    """
    gzip_file_object = resolver.Resolver.OpenFileObject(
        path_spec.parent, resolver_context=self._resolver_context)

    try:
      self._ReadFileHeader(gzip_file_object)
      self._ReadFileFooter(gzip_file_object)

    finally:
      gzip_file_object.close()

    path_spec_data_range = data_range_path_spec.DataRangePathSpec(
        range_offset=self._compressed_data_offset,
        range_size=self._compressed_data_size, parent=path_spec.parent)
    path_spec_compressed_stream = (
        compressed_stream_path_spec.CompressedStreamPathSpec(
            compression_method=definitions.COMPRESSION_METHOD_DEFLATE,
            parent=path_spec_data_range))

    return resolver.Resolver.OpenFileObject(
        path_spec_compressed_stream, resolver_context=self._resolver_context)
コード例 #8
0
ファイル: sac_h.py プロジェクト: kujaku11/PH5_py3
def bin_header_le_int():
    BIN = construct.Struct(
        "BIN",
        # GMT year corresponding to reference (zero) time in
        # file.
        construct.SLInt32("nzyear"),
        construct.SLInt32("nzjday"),  # GMT julian day.
        construct.SLInt32("nzhour"),  # GMT hour.
        construct.SLInt32("nzmin"),  # GMT minute.
        construct.SLInt32("nzsec"),  # GMT second.
        construct.SLInt32("nzmsec"),  # GMT millisecond.
        # Header version number. Current value is the
        # integer 6.
        construct.SLInt32("nvhdr"),
        # Older version data (NVHDR < 6) are automatically
        # updated
        construct.SLInt32("norid"),  # Origin ID (CSS 3.0)
        construct.SLInt32("nevid"),  # Event ID (CSS 3.0)
        # Number of points per data component. [required]
        construct.SLInt32("npts"),
        construct.SLInt32("nsnpts"),  #
        construct.SLInt32("nwfid"),  # Waveform ID (CSS 3.0)
        construct.SLInt32("nxsize"),  #
        construct.SLInt32("nysize"),  #
        construct.SLInt32("unused15"),  #
        # Type of file [required]:
        construct.SLInt32("iftype"),
        #    * ITIME {Time series file}
        #    * IRLIM {Spectral file---real and imaginary}
        #    * IAMPH {Spectral file---amplitude and phase}
        #    * IXY {General x versus y data}
        #    * IXYZ {General XYZ (3-D) file}
        # Type of dependent variable:
        construct.SLInt32("idep"),
        #    * IUNKN (Unknown)
        #    * IDISP (Displacement in nm)
        #    * IVEL (Velocity in nm/sec)
        #    * IVOLTS (Velocity in volts)
        #    * IACC (Acceleration in nm/sec/sec)
        # Reference time equivalence:
        construct.SLInt32("iztype"),
        #    * IUNKN (5): Unknown
        #    * IB (9): Begin time
        #    * IDAY (10): Midnight of refernece GMT day
        #    * IO (11): Event origin time
        #    * IA (12): First arrival time
        #    * ITn (13-22): User defined time pick n,n=0,9
        construct.SLInt32("unused16"),  #
        # Type of recording instrument. [currently not used]
        construct.SLInt32("iinst"),
        # Station geographic region. [not currently used]
        construct.SLInt32("istreg"),
        # Event geographic region. [not currently used]
        construct.SLInt32("ievreg"),
        construct.SLInt32("ievtyp"),  # Type of event:
        # * IUNKN (Unknown)
        # * INUCL (Nuclear event)
        # * IPREN (Nuclear pre-shot event)
        # * IPOSTN (Nuclear post-shot event)
        # * IQUAKE (Earthquake)
        # * IPREQ (Foreshock)
        # * IPOSTQ (Aftershock)
        # * ICHEM (Chemical explosion)
        # * IQB (Quarry or mine blast confirmed by quarry)
        # * IQB1 (Quarry/mine blast with designed shot
        #   info-ripple fired)
        # * IQB2 (Quarry/mine blast with observed shot
        #   info-ripple fired)
        # * IQMT (Quarry/mining-induced events:
        #   tremors and rockbursts)
        # * IEQ (Earthquake)
        # * IEQ1 (Earthquakes in a swarm or aftershock
        #   sequence)
        # * IEQ2 (Felt earthquake)
        # * IME (Marine explosion)
        # * IEX (Other explosion)
        # * INU (Nuclear explosion)
        # * INC (Nuclear cavity collapse)
        # * IO\_ (Other source of known origin)
        # * IR (Regional event of unknown origin)
        # * IT (Teleseismic event of unknown origin)
        # * IU (Undetermined or conflicting information)
        # Quality of data [not currently used]:
        construct.SLInt32("iqual"),
        #    * IGOOD (Good data)
        #    * IGLCH (Glitches)
        #    * IDROP (Dropouts)
        #    * ILOWSN (Low signal to noise ratio)
        #    * IOTHER (Other)
        # Synthetic data flag [not currently used]:
        construct.SLInt32("isynth"),
        #    * IRLDTA (Real data)
        #    * ?????
        #    (Flags for various synthetic seismogram
        #      codes)
        construct.SLInt32("imagtyp"),  #
        construct.SLInt32("imagsrc"),  #
        construct.SLInt32("unused19"),  #
        construct.SLInt32("unused20"),  #
        construct.SLInt32("unused21"),  #
        construct.SLInt32("unused22"),  #
        construct.SLInt32("unused23"),  #
        construct.SLInt32("unused24"),  #
        construct.SLInt32("unused25"),  #
        construct.SLInt32("unused26"),  #
        # TRUE if data is evenly spaced. [required]
        construct.SLInt32("leven"),
        # TRUE if station components have a positive
        # polarity
        construct.SLInt32("lpspol"),
        # (left-hand rule).
        # TRUE if it is okay to overwrite this file on disk.
        construct.SLInt32("lovrok"),
        # TRUE if DIST AZ BAZ and GCARC are to be calculated
        # from
        construct.SLInt32("lcalda"),
        # st event coordinates.
        construct.SLInt32("unused27"))
    return BIN