Containers¶
Containers in dissect.target are the abstraction layer for anything that looks (or should look) like a raw disk.
For example, VMware VMDK or Microsoft Hyper-V VHD(X) files may be custom file formats, but in the end these are merely containers of the raw disk(s) inside.
The container abstraction layer in dissect.target makes working with these different disk containers easy. Once
opened, all containers behave as a binary file-like object. This means that there’s no special API for working with
containers, if you know how to read from a file in Python, you’ll know how to read from a container.
See also
To see how to open a container in Python, continue reading here.
View all available container implementations at dissect.target.containers.
Writing your own¶
There are a few methods of using your own container implementation in dissect.target:
Specify the path to your implementation(s) using the
DISSECT_PLUGINSenvironment variable.Specify the path to your implementation(s) using the
--plugin-pathargument with the various Dissect Tools.Add a new implementation in the
dissect.targetsource tree atdissect/target/containers.
The last method requires you to have a source checkout and working development setup of dissect.target.
This is the recommended method if you intend to contribute your container back to the project.
See also
Read more about using your own modules in dissect.target at Loading your own modules.
Interested in developing for Dissect? Read more at Developing for Dissect.
Regardless of which method you use, you can use the boilerplate below. Do keep in mind that the final line is only
required if you’re using either of the DISSECT_PLUGINS or --plugin-path options!
import io
from pathlib import Path
from typing import BinaryIO, Union
from dissect.target.container import Container, register
class MyContainer(Container):
def __init__(self, fh: Union[BinaryIO, Path], *args, **kwargs):
# Do your initialization here, for example, initialize a parser:
# self.vmdk = VMDK(fh)
# Call ``super().__init__`` with the original file-like object(s) and the container size
super().__init__(fh, size, *args, **kwargs)
@staticmethod
def detect_fh(fh: BinaryIO, original: Union[list, BinaryIO]) -> bool:
# Perform detection for your container from a binary file-like object here
# For example, check a specific magic header value
raise NotImplementedError()
@staticmethod
def detect_path(path: Path, original: Union[list, BinaryIO]) -> bool:
# Perform detection for your container from a Path object here
# For example, check a specific file extension
raise NotImplementedError()
def read(self, length: int) -> bytes:
# Perform a file read for ``length`` amount of bytes
raise NotImplementedError()
def seek(self, offset: int, whence: int = io.SEEK_SET) -> int:
# Perform a file seek here
raise NotImplementedError()
def tell(self) -> int:
# Perform a file tell here
raise NotImplementedError()
def close(self) -> None:
# Perform any close actions here
pass
# This line is necessary if your container is outside the ``dissect.target`` source tree!
register(__name__, MyContainer.__name__, internal=False)
See also
You can refer to the API documentation of the Container class for more
documentation on the methods referenced here.
If you are placing your implementation in the dissect.target source tree, you’ll need to register your implementation.
Do this by opening dissect/target/container.py and add your implementation to the bottom by using
register():
register("mycontainer", "MyContainer")