Skip to content

Conversation

@andreia-oca
Copy link

Add a section on how to use the QCOW2 module to load
images that are based on backing files.

This is related to changes on: fox-it/dissect.hypervisor#64

Add a section on how to use QCOW2 module to load
images that are based on backing files.

This is related to changes on: fox-it/dissect.hypervisor#64

Signed-off-by: Andreia Ocanoaia <andreia.ocanoaia@gmail.com>
@Horofic Horofic self-requested a review October 2, 2025 14:46
Comment on lines +60 to +101
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())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @andreia-oca thank you for writing some documentation! I suggested some changes. Let me know what you think.

Suggested change
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())
Opening QCOW2 disks & backing-files
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The QCOW2 parser provided by this library can be used to open QCOW2 disk images, including snapshots and backing-files.
When opening a QCOW2 image as a target, any backing-files are automatically loaded and resolved.
For example, to open a QCOW2 image along with its backing-file:
.. code-block:: python
from dissect.hypervisor.disk.qcow2 import QCow2
with open("/path/to/base-image.qcow2", "rb") as base_image, \
open("/path/to/backing-file.qcow2", "rb") as backing_file:
qcow2 = QCow2(base_image, backing_file=backing_file)
print(qcow2.open().read(512))
print(qcow2.backing_file.read(512))
When opening a QCOW2 image using the dissect.target :class:`~dissect.target.target.Target` class, any backing-files
are automatically loaded and resolved. For example:
.. code-block:: python
from dissect.target import Target
target = Target("/path/to/base-image.qcow2") # Automatically resolves backing-files
print(target.hostname)

Comment on lines +89 to +101
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())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With regards to the previous suggestion. I deliberately removed this from here. I think this would be nicer suited in the /usage/use-cases.rst page.

Comment on lines +73 to +87
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
Copy link
Member

@Horofic Horofic Oct 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made this more concise in the suggestion comment. Would you mind checking if it still works?

Copy link
Member

@Horofic Horofic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, I meant to click "Request changes"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add documentation for loading QCOW2 snapshots

2 participants