diff --git a/docs/source/projects/dissect.hypervisor/index.rst b/docs/source/projects/dissect.hypervisor/index.rst index 4c248cc..49b6685 100644 --- a/docs/source/projects/dissect.hypervisor/index.rst +++ b/docs/source/projects/dissect.hypervisor/index.rst @@ -57,6 +57,49 @@ a VMDK for reading: Many of the parsers in this package behave in a very similar way, so check the API reference to see how to utilize the parser you need. +Open QCOW2 snapshots +~~~~~~~~~~~~~~~~~~~~ + +For `qcow2` images there is support for backing-files and it can either be automatically loaded when opening a target. +The backing-file will automatically be read from the `qcow2` headers and dissect will attempt to load it. + +.. code-block:: python + target = Target.open(target_path) + print(target.users()) + +Or, for more control, the path to the backing file can be passed when initializing a `qcow2` disk: + +.. code-block:: python + def open_qcow2_with_backing_file(snapshot_path: Path, backing_path: Path): + # Open base QCOW2 image + backing_fh = backing_path.open("rb") + base_qcow2 = qcow2.QCow2(backing_fh) + base_stream = base_qcow2.open() + + # Open snapshot QCOW2 image with base as backing file + snapshot_fh = snapshot_path.open("rb") + snapshot_qcow2 = qcow2.QCow2( + snapshot_fh, + backing_file=base_stream + ) + snapshot_stream = snapshot_qcow2.open() + + return snapshot_stream, snapshot_fh, backing_fh, base_stream + + def analyze_image(snapshot_path: Path, backing_path: Path): + # Open the QCOW2 snapshot along with its backing file and get file/stream handles + snapshot_stream, snapshot_fh, backing_fh, base_stream = open_qcow2_with_backing_file(snapshot_path, backing_path) + + # Create a new Dissect target to analyze the disk image + target = Target() + # Add the snapshot stream to the target’s disks + target.disks.add(snapshot_stream) + # Resolve all disks, volumes and filesystems and load an operating system on the current + target.apply() + + # Collect data from the snapshot + print(target.users()) + Tools -----