:py:mod:`dissect.hypervisor.descriptor.hyperv` ============================================== .. py:module:: dissect.hypervisor.descriptor.hyperv Module Contents --------------- Classes ~~~~~~~ .. autoapisummary:: dissect.hypervisor.descriptor.hyperv.HyperVFile dissect.hypervisor.descriptor.hyperv.HyperVStorageReplayLog dissect.hypervisor.descriptor.hyperv.HyperVStorageObjectTable dissect.hypervisor.descriptor.hyperv.HyperVStorageKeyTable dissect.hypervisor.descriptor.hyperv.HyperVStorageKeyTableEntry dissect.hypervisor.descriptor.hyperv.HyperVStorageFileObject .. py:class:: 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. .. py:property:: version :type: int .. py:method:: __getitem__(key: str) -> HyperVStorageKeyTableEntry .. py:method:: keys() -> collections.abc.KeysView[str] .. py:method:: items() -> collections.abc.ItemsView[str, HyperVStorageKeyTableEntry] .. py:method:: values() -> collections.abc.ValuesView[HyperVStorageKeyTableEntry] .. py:method:: as_dict() -> dict .. py:class:: 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. .. py:class:: 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. .. py:class:: 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. .. py:property:: index :type: int Return the table index. .. py:property:: sequence_number :type: int Return the table sequence number. .. py:class:: 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. .. py:property:: parent :type: Optional[HyperVStorageKeyTableEntry] Return the entry parent, if there is any. Requires that all key tables are loaded. .. py:property:: flags :type: int Return the entry flags. .. py:property:: type :type: dissect.hypervisor.descriptor.c_hyperv.KeyDataType Return the entry type. .. py:property:: size :type: int Return the entry size. .. py:property:: is_file_object_pointer :type: bool Return whether the value is a file object pointer. .. py:property:: file_object_pointer :type: tuple[int, int] Return the file object pointer information. .. py:property:: raw :type: memoryview Returns the raw data for this entry. .. py:property:: data :type: memoryview Returns the data portion for this entry. .. py:property:: key :type: str Returns the key name for this entry. .. py:property:: value :type: Union[int, bytes, str] Return a Python native value for this entry. .. py:property:: data_size :type: int Return the total amount of data bytes, including the key name. Reference: - ``HyperVStorageKeyTableEntry::GetDataSizeInBytes`` .. py:property:: value_size :type: int Return the amount of bytes a value occupies. Reference: - ``HyperVStorageKeyTableEntry::GetValueSizeInBytes`` .. py:method:: __getitem__(key: str) -> HyperVStorageKeyTableEntry .. py:method:: __repr__() -> str Return repr(self). .. py:method:: keys() -> collections.abc.KeysView[int] .. py:method:: items() -> collections.abc.ItemsView[int, HyperVStorageKeyTableEntry] .. py:method:: values() -> collections.abc.ValuesView[HyperVStorageKeyTableEntry] .. py:method:: as_dict() -> dict .. py:method:: get_file_object() -> HyperVStorageFileObject .. py:class:: 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. .. py:method:: read(n: int = -1) -> bytes .. py:method:: open(size: Optional[int] = None) -> BinaryIO