dissect.volume.vss

Module Contents

Classes

VSS

Catalog

Store

StoreStream

Basic buffered stream that provides easy aligned reads.

BlockList

RangeList

StoreBitmap

BlockMap

BlockDescriptor

Functions

Attributes

dissect.volume.vss.log
dissect.volume.vss.vss_def = Multiline-String
Show Value
"""
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;
};
"""
dissect.volume.vss.c_vss
dissect.volume.vss.RECORD_TYPE
dissect.volume.vss.BLOCK_FLAG
dissect.volume.vss.VSS_IDENTIFIER = b'k\x87\x088v\xc1HN\xb7\xae\x04\x04nl\xc7R'
dissect.volume.vss.VOLUME_HEADER_OFFSET = 7680
dissect.volume.vss.BLOCK_SIZE = 16384
dissect.volume.vss.CATALOG_BLOCK_SIZE = 16384
dissect.volume.vss.CATALOG_ENTRY_SIZE = 128
dissect.volume.vss.STORE_BLOCK_SIZE = 16384
dissect.volume.vss.STORE_BLOCKLIST_ENTRY_SIZE = 32
dissect.volume.vss.STORE_RANGELIST_ENTRY_SIZE = 24
class dissect.volume.vss.VSS(fh: BinaryIO)
fh
header
catalog
__repr__() str
property volume_identifier: uuid.UUID
property store_volume_identifier: uuid.UUID
class dissect.volume.vss.Catalog(vss: VSS, offset: int)
vss
fh
entries = []
stores = []
__repr__() str
dissect.volume.vss.DEBUG = False
class dissect.volume.vss.Store(catalog: Catalog, descriptors: list)
catalog
fh
descriptors
previous_store = None
next_store = None
index = None
has_store_data = False
volume_size
size
creation_time
header
information
copy_identifier
copy_set_identifier
open() StoreStream
property block_list: BlockList
property range_list: RangeList
property bitmap: StoreBitmap
property previous_bitmap: StoreBitmap
read_block(block: int, active_store: Store | None = None) bytes
class dissect.volume.vss.StoreStream(store: Store)

Bases: dissect.util.stream.AlignedStream

Basic buffered stream that provides easy aligned reads.

Must be subclassed for various stream implementations. Subclasses can implement:
  • _read(offset, length)

  • _seek(pos, whence=io.SEEK_SET)

The offset and length for _read are guaranteed to be aligned. 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.

Parameters:
  • size – The size of the stream. This is used in read and seek operations. None if unknown.

  • align – The alignment size. Read operations are aligned on this boundary. Also determines buffer size.

store
class dissect.volume.vss.BlockList(store: Store, offset: int)
store
offset
map
class dissect.volume.vss.RangeList(store: Store, offset: int)
store
offset
entries = []
class dissect.volume.vss.StoreBitmap(store: Store, offset: int)
store
offset
test = []
has_offset(offset: int) bool
in_use(block: int) bool
is_set(block: int) bool
__getitem__(block: int) bool
class dissect.volume.vss.BlockMap
map
reverse
add(descriptor: BlockDescriptor) None
get_descriptor(offset: int) None
__getitem__(block: int) BlockMap
class dissect.volume.vss.BlockDescriptor(buf: bytes)
__slots__ = ('bitmap', 'flags', 'is_forwarder', 'is_overlay', 'is_used', 'original_offset', 'overlay',...
original_offset
relative_offset
store_offset
flags
bitmap
overlay = None
is_used
is_overlay
is_forwarder
__eq__(other: object) bool
__repr__() str
dissect.volume.vss.read_block(fh: BinaryIO, offset: int, struct: type[dissect.cstruct.Structure]) tuple[dissect.cstruct.Structure, bytes]
dissect.volume.vss.read_block_data(fh: BinaryIO, offset: int, struct: type[dissect.cstruct.Structure]) tuple[dissect.cstruct.Structure, bytes]