:py:mod:`dissect.volume.vss` ============================ .. py:module:: dissect.volume.vss Module Contents --------------- Classes ~~~~~~~ .. autoapisummary:: dissect.volume.vss.VSS dissect.volume.vss.Catalog dissect.volume.vss.Store dissect.volume.vss.StoreStream dissect.volume.vss.BlockList dissect.volume.vss.RangeList dissect.volume.vss.StoreBitmap dissect.volume.vss.BlockMap dissect.volume.vss.BlockDescriptor Functions ~~~~~~~~~ .. autoapisummary:: :nosignatures: dissect.volume.vss.read_block dissect.volume.vss.read_block_data Attributes ~~~~~~~~~~ .. autoapisummary:: dissect.volume.vss.log dissect.volume.vss.vss_def dissect.volume.vss.c_vss dissect.volume.vss.RECORD_TYPE dissect.volume.vss.BLOCK_FLAG dissect.volume.vss.VSS_IDENTIFIER dissect.volume.vss.VOLUME_HEADER_OFFSET dissect.volume.vss.BLOCK_SIZE dissect.volume.vss.CATALOG_BLOCK_SIZE dissect.volume.vss.CATALOG_ENTRY_SIZE dissect.volume.vss.STORE_BLOCK_SIZE dissect.volume.vss.STORE_BLOCKLIST_ENTRY_SIZE dissect.volume.vss.STORE_RANGELIST_ENTRY_SIZE dissect.volume.vss.DEBUG .. py:data:: log .. py:data:: vss_def :value: Multiline-String .. raw:: html
Show Value .. code-block:: python """ flag _VSS_VOLUME_SNAPSHOT_ATTRIBUTES : uint32 { VSS_VOLSNAP_ATTR_PERSISTENT = 0x00000001, VSS_VOLSNAP_ATTR_NO_AUTORECOVERY = 0x00000002, VSS_VOLSNAP_ATTR_CLIENT_ACCESSIBLE = 0x00000004, VSS_VOLSNAP_ATTR_NO_AUTO_RELEASE = 0x00000008, VSS_VOLSNAP_ATTR_NO_WRITERS = 0x00000010, VSS_VOLSNAP_ATTR_TRANSPORTABLE = 0x00000020, VSS_VOLSNAP_ATTR_NOT_SURFACED = 0x00000040, VSS_VOLSNAP_ATTR_NOT_TRANSACTED = 0x00000080, VSS_VOLSNAP_ATTR_HARDWARE_ASSISTED = 0x00010000, VSS_VOLSNAP_ATTR_DIFFERENTIAL = 0x00020000, VSS_VOLSNAP_ATTR_PLEX = 0x00040000, VSS_VOLSNAP_ATTR_IMPORTED = 0x00080000, VSS_VOLSNAP_ATTR_EXPOSED_LOCALLY = 0x00100000, VSS_VOLSNAP_ATTR_EXPOSED_REMOTELY = 0x00200000, VSS_VOLSNAP_ATTR_AUTORECOVER = 0x00400000, VSS_VOLSNAP_ATTR_ROLLBACK_RECOVERY = 0x00800000, VSS_VOLSNAP_ATTR_DELAYED_POSTSNAPSHOT = 0x01000000, VSS_VOLSNAP_ATTR_TXF_RECOVERY = 0x02000000 }; enum RECORD_TYPE : uint32 { VOLUME_HEADER = 0x1, CATALOG = 0x2, STORE_INDEX = 0x3, STORE_HEADER = 0x4, STORE_BLOCK_RANGE = 0x5, STORE_BITMAP = 0x6 }; flag BLOCK_FLAG : uint32 { IS_FORWARDER = 0x1, IS_OVERLAY = 0x2, NOT_USED = 0x4 }; struct volume_header { char identifier[16]; uint32 version; uint32 record_type; uint64 current_offset; uint64 unk0; uint64 unk1; uint64 catalog_offset; uint64 maximum_size; char volume_identifier[16]; char store_volume_identifier[16]; uint32 unk2; char unk3[412]; }; struct catalog_header { char identifier[16]; uint32 version; uint32 record_type; uint64 relative_offset; uint64 offset; uint64 next_offset; char unk0[80]; }; struct catalog_entry_1 { uint64 entry_type; char unk0[120]; }; struct catalog_entry_2 { uint64 entry_type; uint64 volume_size; char store_identifier[16]; uint64 unk0; uint64 unk1; uint64 creation_time; char unk2[72]; }; struct catalog_entry_3 { uint64 entry_type; uint64 store_block_list_offset; char store_identifier[16]; uint64 store_header_offset; uint64 store_range_list_offset; uint64 store_bitmap_offset; uint64 metadata_reference; uint64 allocated_size; uint64 store_previous_bitmap_offset; uint64 unk0; char unk1[40]; }; struct store_header { char identifier[16]; uint32 version; RECORD_TYPE record_type; uint64 relative_offset; uint64 offset; uint64 next_offset; uint64 size; char unk0[72]; }; struct store_information { char unk_identifier[16]; char copy_identifier[16]; char copy_set_identifier[16]; uint32 type; uint32 provider; _VSS_VOLUME_SNAPSHOT_ATTRIBUTES attributes; uint32 unk0; uint16 operating_machine_len; wchar operating_machine[operating_machine_len / 2]; uint16 service_machine_len; wchar service_machine[service_machine_len / 2]; }; struct block_descriptor { uint64 original_offset; uint64 relative_offset; uint64 store_offset; BLOCK_FLAG flags; uint32 allocation_bitmap; }; struct range_descriptor { uint64 store_offset; uint64 relative_offset; uint64 size; }; """ .. raw:: html
.. py:data:: c_vss .. py:data:: RECORD_TYPE .. py:data:: BLOCK_FLAG .. py:data:: VSS_IDENTIFIER :value: b'k\x87\x088v\xc1HN\xb7\xae\x04\x04nl\xc7R' .. py:data:: VOLUME_HEADER_OFFSET :value: 7680 .. py:data:: BLOCK_SIZE :value: 16384 .. py:data:: CATALOG_BLOCK_SIZE :value: 16384 .. py:data:: CATALOG_ENTRY_SIZE :value: 128 .. py:data:: STORE_BLOCK_SIZE :value: 16384 .. py:data:: STORE_BLOCKLIST_ENTRY_SIZE :value: 32 .. py:data:: STORE_RANGELIST_ENTRY_SIZE :value: 24 .. py:class:: VSS(fh: BinaryIO) .. py:attribute:: fh .. py:attribute:: header .. py:attribute:: catalog .. py:method:: __repr__() -> str .. py:property:: volume_identifier :type: uuid.UUID .. py:property:: store_volume_identifier :type: uuid.UUID .. py:class:: Catalog(vss: VSS, offset: int) .. py:attribute:: vss .. py:attribute:: fh .. py:attribute:: entries :value: [] .. py:attribute:: stores :value: [] .. py:method:: __repr__() -> str .. py:data:: DEBUG :value: False .. py:class:: Store(catalog: Catalog, descriptors: list) .. py:attribute:: catalog .. py:attribute:: fh .. py:attribute:: descriptors .. py:attribute:: previous_store :value: None .. py:attribute:: next_store :value: None .. py:attribute:: index :value: None .. py:attribute:: has_store_data :value: False .. py:attribute:: volume_size .. py:attribute:: size .. py:attribute:: creation_time .. py:attribute:: header .. py:attribute:: information .. py:attribute:: copy_identifier .. py:attribute:: copy_set_identifier .. py:method:: open() -> StoreStream .. py:property:: block_list :type: BlockList .. py:property:: range_list :type: RangeList .. py:property:: bitmap :type: StoreBitmap .. py:property:: previous_bitmap :type: StoreBitmap .. py:method:: read_block(block: int, active_store: Store | None = None) -> bytes .. py:class:: StoreStream(store: Store) Bases: :py:obj:`dissect.util.stream.AlignedStream` Basic buffered stream that provides aligned reads. Must be subclassed for various stream implementations. Subclasses can implement: - :meth:`~AlignedStream._read` - :meth:`~AlignedStream._seek` The offset and length for ``_read`` are guaranteed to be aligned for streams of a known size. If your stream has an unknown size (i.e. ``size == None``), reads of length ``-1`` (i.e. read until EOF) will be passed through to your implementation of ``_read``. The only time that overriding ``_seek`` would make sense is if there's no known size of your stream, but still want to provide ``SEEK_END`` functionality. Most subclasses of ``AlignedStream`` take one or more file-like objects as source. Operations on these subclasses, like reading, will modify the source file-like object as a side effect. :param size: The size of the stream. This is used in read and seek operations. ``None`` if unknown. :param align: The alignment size. Read operations are aligned on this boundary. Also determines buffer size. .. automethod:: _read .. automethod:: _seek .. py:attribute:: store .. py:class:: BlockList(store: Store, offset: int) .. py:attribute:: store .. py:attribute:: offset .. py:attribute:: map .. py:class:: RangeList(store: Store, offset: int) .. py:attribute:: store .. py:attribute:: offset .. py:attribute:: entries :value: [] .. py:class:: StoreBitmap(store: Store, offset: int) .. py:attribute:: store .. py:attribute:: offset .. py:attribute:: test :value: [] .. py:method:: has_offset(offset: int) -> bool .. py:method:: in_use(block: int) -> bool .. py:method:: is_set(block: int) -> bool .. py:method:: __getitem__(block: int) -> bool .. py:class:: BlockMap .. py:attribute:: map .. py:attribute:: reverse .. py:method:: add(descriptor: BlockDescriptor) -> None .. py:method:: get_descriptor(offset: int) -> None .. py:method:: __getitem__(block: int) -> BlockMap .. py:class:: BlockDescriptor(buf: bytes) .. py:attribute:: __slots__ :value: ('bitmap', 'flags', 'is_forwarder', 'is_overlay', 'is_used', 'original_offset', 'overlay',... .. py:attribute:: original_offset .. py:attribute:: relative_offset .. py:attribute:: store_offset .. py:attribute:: flags .. py:attribute:: bitmap .. py:attribute:: overlay :value: None .. py:attribute:: is_used .. py:attribute:: is_overlay .. py:attribute:: is_forwarder .. py:method:: __eq__(other: object) -> bool .. py:method:: __repr__() -> str .. py:function:: read_block(fh: BinaryIO, offset: int, struct: type[dissect.cstruct.Structure]) -> tuple[dissect.cstruct.Structure, bytes] .. py:function:: read_block_data(fh: BinaryIO, offset: int, struct: type[dissect.cstruct.Structure]) -> tuple[dissect.cstruct.Structure, bytes]