dissect.hypervisor.descriptor.hyperv#

Module Contents#

Classes#

HyperVFile

HyperVFile implementation.

HyperVStorageReplayLog

The replay log tracks changes in the file.

HyperVStorageObjectTable

The object table tracks all "objects".

HyperVStorageKeyTable

The key table stores key value pairs and their relation to parent keys.

HyperVStorageKeyTableEntry

Entry in a key table.

HyperVStorageFileObject

File object from the object table.

class dissect.hypervisor.descriptor.hyperv.HyperVFile(fh: BinaryIO)#

HyperVFile implementation.

I think, technically, the underlying container is called HyperVStorage, and the HyperVFile adds some features on top of that. We just call it HyperVFile for convenience.

A HyperVFile has 2 headers, one at 0x0000 and one at 0x1000. The active header is determined by a sequence number.

A replay log is located at an offset specified in the header. This replay log functions as a journal for changes made to the file. A file is dirty if it contains outstanding entries in the replay log, and replaying the specified log entries is necessary. This is not currently implemented.

An object table seems to be located at 0x2000, but it’s unclear if this is always the case. The offset might be related to the header size, log size or data alignment. This will need some more research. This table contains entries that describe the various “objects” contained within this file. The available types are listed in the ObjectEntryType enum.

HyperVFile’s have a version number, and it looks like there are some slight differences between different versions. The key tables are at least stored in a different manner, because there’s code to handle loading them differently, and also to update them to the new format if an old version is encountered. However, I haven’t seen any files with older versions yet, so we guard this implementation to only version 0x0400 at this time.

property version: int#
__getitem__(key: str) HyperVStorageKeyTableEntry#
keys() collections.abc.KeysView[str]#
items() collections.abc.ItemsView[str, HyperVStorageKeyTableEntry]#
values() collections.abc.ValuesView[HyperVStorageKeyTableEntry]#
as_dict() dict#
class dissect.hypervisor.descriptor.hyperv.HyperVStorageReplayLog(hyperv_file: HyperVFile, offset: int)#

The replay log tracks changes in the file.

Old changes are actually still resident in the log, but not counted in the num_entries field.

class dissect.hypervisor.descriptor.hyperv.HyperVStorageObjectTable(hyperv_file: HyperVFile, offset: int)#

The object table tracks all “objects”.

Objects are specific blocks in the file that have been designated a specific type. For example, the object table can list one or more key tables.

class dissect.hypervisor.descriptor.hyperv.HyperVStorageKeyTable(hyperv_file: HyperVFile, offset: int, size: int)#

The key table stores key value pairs and their relation to parent keys.

A table has a specific table index and one or more key entries.

property index: int#

Return the table index.

property sequence_number: int#

Return the table sequence number.

class dissect.hypervisor.descriptor.hyperv.HyperVStorageKeyTableEntry(table: HyperVStorageKeyTable, offset: int)#

Entry in a key table.

The first 16 bytes are a combined flag and type field. The high 8 bits are flags, the low 8 bits are type.

Only one flag is currently known, which we’ve called FileObjectPointer. It’s the lowest bit of the flag bits. If this flag is set, it means the value of this entry is located in a file object. File objects pointers are 12 bytes and consist of a uint32 size and a uint64 offset value. The offset is the absolute offset into the file. This method is similar to how parent keys are referenced.

Values are stored in a file object if their size >= 0x800. As only strings and “arrays” are of variable size, these are the only data types that can be stored in file objects.

Data type summary:

  • KeyDataType.Free:
    • Allocated but free.

  • KeyDataType.Unknown:
    • Unknown entry type. Anything greater than 9 and exactly 2 is unknown.

  • KeyDataType.Int:
    • Signed 64 bit integer.

  • KeyDataType.UInt:
    • Unsigned 64 bit integer.

  • KeyDataType.Double:
    • 64 bit double.

  • KeyDataType.String:
    • UTF-16-LE encoded string

  • KeyDataType.Array:
    • Bytes?

  • KeyDataType.Bool:
    • Boolean encoded as 32 bit integer.

  • KeyDataType.Node:
    • Tree nodes. Value size is coded as 8, but actual size is 12.

    • First 8 bytes are unknown, but latter 4 bytes is the insertion sequence number.

property parent: HyperVStorageKeyTableEntry | None#

Return the entry parent, if there is any.

Requires that all key tables are loaded.

property flags: int#

Return the entry flags.

property type: dissect.hypervisor.descriptor.c_hyperv.KeyDataType#

Return the entry type.

property size: int#

Return the entry size.

property is_file_object_pointer: bool#

Return whether the value is a file object pointer.

property file_object_pointer: tuple[int, int]#

Return the file object pointer information.

property raw: memoryview#

Returns the raw data for this entry.

property data: memoryview#

Returns the data portion for this entry.

property key: str#

Returns the key name for this entry.

property value: int | bytes | str#

Return a Python native value for this entry.

property data_size: int#

Return the total amount of data bytes, including the key name.

Reference:
  • HyperVStorageKeyTableEntry::GetDataSizeInBytes

property value_size: int#

Return the amount of bytes a value occupies.

Reference:
  • HyperVStorageKeyTableEntry::GetValueSizeInBytes

__getitem__(key: str) HyperVStorageKeyTableEntry#
__repr__() str#

Return repr(self).

keys() collections.abc.KeysView[int]#
items() collections.abc.ItemsView[int, HyperVStorageKeyTableEntry]#
values() collections.abc.ValuesView[HyperVStorageKeyTableEntry]#
as_dict() dict#
get_file_object() HyperVStorageFileObject#
class dissect.hypervisor.descriptor.hyperv.HyperVStorageFileObject(hyperv_file: HyperVFile, offset: int, size: int)#

File object from the object table.

File objects are referenced by their absolute offset in the file. The object table also stores a size, but this size will always be aligned with the data alignment of the Hyper-V file. The actual size of the data stored is located in the data portion of the HyperVStorageKeyTableEntry that references that file object.

read(n: int = -1) bytes#
open(size: int | None = None) BinaryIO#