Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ dependencies = [
"dissect.cstruct>=4,<5",
"dissect.database>=1.1.dev3,<2", # TODO: update on release!
"dissect.eventlog>=3,<4",
"dissect.evidence>=3.13.dev2,<4", # TODO: update on release!
"dissect.evidence>=3.13.dev3,<4", # TODO: update on release!
"dissect.hypervisor>=3.20,<4",
"dissect.ntfs>=3.16.dev,<4",
"dissect.regf>=3.13,<4",
Expand Down
3 changes: 3 additions & 0 deletions tests/_data/containers/ewf/small.E01
Git LFS file not shown
3 changes: 3 additions & 0 deletions tests/_data/containers/ewf/split.E01
Git LFS file not shown
3 changes: 3 additions & 0 deletions tests/_data/containers/ewf/split.E02
Git LFS file not shown
3 changes: 3 additions & 0 deletions tests/_data/containers/qcow2/small.qcow2
Git LFS file not shown
3 changes: 3 additions & 0 deletions tests/_data/containers/vdi/small.vdi.gz
Git LFS file not shown
3 changes: 3 additions & 0 deletions tests/_data/containers/vhd/small.vhd.gz
Git LFS file not shown
3 changes: 3 additions & 0 deletions tests/_data/containers/vhdx/small.vhdx.gz
Git LFS file not shown
3 changes: 3 additions & 0 deletions tests/_data/containers/vmdk/small.vmdk
Git LFS file not shown
3 changes: 3 additions & 0 deletions tests/_data/containers/vmdk/small.vmdk.gz
Git LFS file not shown
75 changes: 75 additions & 0 deletions tests/containers/test_ewf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
from __future__ import annotations

import io

from dissect.target import container
from dissect.target.containers.ewf import EwfContainer
from dissect.target.filesystem import VirtualFilesystem
from tests._utils import absolute_path


def test_ewf_container() -> None:
"""Test that EWF containers are properly opened.

```
echo "testdissecte01" | ewfacquirestream -t small
```
"""
path = absolute_path("_data/containers/ewf/small.E01")

fh = container.open(path)
assert isinstance(fh, EwfContainer)
a = fh.read(20)
assert a == b"testdissecte01\n"
assert fh.tell() == 15
fh.seek(0, whence=io.SEEK_SET)
assert fh.read(20) == b"testdissecte01\n"
fh.close()


def test_ewf_detect_path() -> None:
"""Test that EWF containers are properly opened, when using the extension based matching."""
vfs = VirtualFilesystem()
vfs.map_file("small.E01", absolute_path("_data/containers/ewf/small.E01"))
fh = container.open(vfs.path("small.E01"))
assert isinstance(fh, EwfContainer)
a = fh.read(20)
assert a == b"testdissecte01\n"
assert fh.tell() == 15
fh.seek(0, whence=io.SEEK_SET)
assert fh.read(20) == b"testdissecte01\n"


def test_ewf_container_splitted() -> None:
"""Test that EWF containers are properly opened when container is split among multiple files.

```
# ewfacquire has a minimum 1mb split size, we generate a bit more than 1Mb of compressed data
dd if=/dev/urandom bs=512 count=2100 of=random
cat random | ewfacquirestream -t split -S 1048576
```
"""
path = absolute_path("_data/containers/ewf/split.E01")

fh = container.open(path)
assert isinstance(fh, EwfContainer)
assert fh.read(20) == b'T\x0e\xf4x\x9eT\x17\xda\xca\xbfV\xbb\xda\x99"\xe7S\xa8J\xe7'
fh.seek(0, whence=io.SEEK_END)
assert fh.tell() == 1075200
fh.seek(-15, whence=io.SEEK_CUR)
assert fh.read(20) == b"L5\x089\x8c\xe4\x91~\x9a4\xbcG@\xb4\x11"
fh.close()


def test_ewf_split_detect_path() -> None:
"""Test that EWF containers are properly opened, when using the extension based matching on multiple files."""
vfs = VirtualFilesystem()
vfs.map_file("split.E01", absolute_path("_data/containers/ewf/split.E01"))
vfs.map_file("split.E02", absolute_path("_data/containers/ewf/split.E02"))
fh = container.open(vfs.path("split.E01"))
assert isinstance(fh, EwfContainer)
assert fh.read(20) == b'T\x0e\xf4x\x9eT\x17\xda\xca\xbfV\xbb\xda\x99"\xe7S\xa8J\xe7'
fh.seek(0, whence=io.SEEK_END)
assert fh.tell() == 1075200
fh.seek(-15, whence=io.SEEK_CUR)
assert fh.read(20) == b"L5\x089\x8c\xe4\x91~\x9a4\xbcG@\xb4\x11"
43 changes: 43 additions & 0 deletions tests/containers/test_qcow2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from __future__ import annotations

import io

from dissect.target import container
from dissect.target.containers.qcow2 import QCow2Container
from dissect.target.filesystem import VirtualFilesystem
from tests._utils import absolute_path


def test_qcow2_container() -> None:
"""Test that QCOW2 containers are properly opened.

```
echo "testdissecteqcow2" > small.txt
qemu-img convert -f raw -O qcow2 small.txt small.qcow2
```
"""
path = absolute_path("_data/containers/qcow2/small.qcow2")

fh = container.open(path)
assert isinstance(fh, QCow2Container)
a = fh.read(20)
# trailing \x00 are expected. This is the same when using qemu-nbd
assert a == b"testdissecteqcow2\n\x00\x00"
assert fh.tell() == 20
fh.seek(0, whence=io.SEEK_SET)
assert fh.read(20) == b"testdissecteqcow2\n\x00\x00"
fh.close()


def test_qcow2_detect_path() -> None:
"""Test that QCOW2 containers are properly opened, when using the extension based matching."""
vfs = VirtualFilesystem()
vfs.map_file("small.qcow2", absolute_path("_data/containers/qcow2/small.qcow2"))
fh = container.open(vfs.path("small.qcow2"))
assert isinstance(fh, QCow2Container)
a = fh.read(20)
# trailing \x00 are expected. This is the same when using qemu-nbd
assert a == b"testdissecteqcow2\n\x00\x00"
assert fh.tell() == 20
fh.seek(0, whence=io.SEEK_SET)
assert fh.read(20) == b"testdissecteqcow2\n\x00\x00"
10 changes: 9 additions & 1 deletion tests/containers/test_split.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import io
from io import BytesIO
from typing import TYPE_CHECKING, BinaryIO

Expand All @@ -14,7 +15,6 @@

def _assert_split_container(fh: SplitContainer) -> None:
assert isinstance(fh, SplitContainer)
assert fh.read(4096) == (b"A" * 512) + (b"B" * 512) + (b"C" * 512) + (b"D" * 512)


@pytest.fixture
Expand Down Expand Up @@ -54,3 +54,11 @@ def split_symlink(tmp_path: Path, split_paths: list[Path]) -> Path:
def test_split_container(obj: str, request: pytest.FixtureRequest) -> None:
fh = container.open(request.getfixturevalue(obj))
_assert_split_container(fh)
assert fh.read(4096) == (b"A" * 512) + (b"B" * 512) + (b"C" * 512) + (b"D" * 512)
fh.seek(0, whence=io.SEEK_SET)
assert fh.read(4) == b"AAAA"
assert fh.tell() == 4
fh.seek(508, whence=io.SEEK_CUR)
assert fh.read(4) == b"BBBB"
fh.seek(-4, whence=io.SEEK_END)
assert fh.read(4) == b"DDDD"
43 changes: 43 additions & 0 deletions tests/containers/test_vdi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from __future__ import annotations

import gzip
import io

from dissect.target import container
from dissect.target.containers.vdi import VdiContainer
from dissect.target.filesystem import VirtualFilesystem
from tests._utils import absolute_path


def test_vdi_container() -> None:
"""Test that VDI containers are properly opened.

```
VBoxManage createmedium disk --filename "./tests/small.vdi" --size 2 --format=VDI
```
"""
path = absolute_path("_data/containers/vdi/small.vdi.gz")
gz_file = gzip.GzipFile(path)
fh = container.open(gz_file)
assert isinstance(fh, VdiContainer)
a = fh.read(20)
assert a == b"\x00" * 20
assert fh.tell() == 20
fh.seek(0, whence=io.SEEK_END)
assert fh.tell() == 2097152
fh.close()
gz_file.close()


def test_vdi_detect_path() -> None:
"""Test that VDI containers are properly opened, when using the extension based matching."""
vfs = VirtualFilesystem()
vfs.map_file("small.vdi", absolute_path("_data/containers/vdi/small.vdi.gz"), compression="gzip")
fh = container.open(vfs.path("small.vdi"))
assert isinstance(fh, VdiContainer)
a = fh.read(20)
assert a == b"\x00" * 20
assert fh.tell() == 20
fh.seek(0, whence=io.SEEK_END)
assert fh.tell() == 2097152
fh.close()
43 changes: 43 additions & 0 deletions tests/containers/test_vhd.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from __future__ import annotations

import gzip
import io

from dissect.target import container
from dissect.target.containers.vhd import VhdContainer
from dissect.target.filesystem import VirtualFilesystem
from tests._utils import absolute_path


def test_vhd_container() -> None:
"""
Test that VHD containers are properly opened.

```
VBoxManage createmedium disk --filename "./small.vhd" --size 2 --format=VHD
```
"""
path = absolute_path("_data/containers/vhd/small.vhd.gz")
gz_file = gzip.GzipFile(path)
fh = container.open(gz_file)
assert isinstance(fh, VhdContainer)
a = fh.read(20)
assert a == b"\x00" * 20
assert fh.tell() == 20
fh.seek(0, whence=io.SEEK_END)
assert fh.tell() == 2097152
fh.close()
gz_file.close()


def test_VHD_detect_path() -> None:
"""Test that VDI containers are properly opened, when using the extension based matching."""
vfs = VirtualFilesystem()
vfs.map_file("small.vhd", absolute_path("_data/containers/vhd/small.vhd.gz"), compression="gzip")
fh = container.open(vfs.path("small.vhd"))
assert isinstance(fh, VhdContainer)
a = fh.read(20)
assert a == b"\x00" * 20
assert fh.tell() == 20
fh.seek(0, whence=io.SEEK_END)
assert fh.tell() == 2097152
43 changes: 43 additions & 0 deletions tests/containers/test_vhdx.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from __future__ import annotations

import gzip
import io

from dissect.target import container
from dissect.target.containers.vhdx import VhdxContainer
from dissect.target.filesystem import VirtualFilesystem
from tests._utils import absolute_path


def test_vhdx_container() -> None:
"""Test that VHDX containers are properly opened.

VBoxManage does not allow to create vhdx. We convert a previously generated vdi to vhdx
```
qemu-img convert -f vdi -O vhdx small.vdi small.vhdx
````
"""
path = absolute_path("_data/containers/vhdx/small.vhdx.gz")
gz_file = gzip.GzipFile(path)
fh = container.open(gz_file)
assert isinstance(fh, VhdxContainer)
a = fh.read(20)
assert a == b"\x00" * 20
assert fh.tell() == 20
fh.seek(0, whence=io.SEEK_END)
assert fh.tell() == 2097152
fh.close()
gz_file.close()


def test_vhdx_detect_path() -> None:
"""Test that VHDX containers are properly opened, when using the extension based matching."""
vfs = VirtualFilesystem()
vfs.map_file("small.vhdx", absolute_path("_data/containers/vhdx/small.vhdx.gz"), compression="gzip")
fh = container.open(vfs.path("small.vhdx"))
assert isinstance(fh, VhdxContainer)
a = fh.read(20)
assert a == b"\x00" * 20
assert fh.tell() == 20
fh.seek(0, whence=io.SEEK_END)
assert fh.tell() == 2097152
43 changes: 43 additions & 0 deletions tests/containers/test_vmdk.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from __future__ import annotations

import gzip
import io

from dissect.target import container
from dissect.target.containers.vmdk import VmdkContainer
from dissect.target.filesystem import VirtualFilesystem
from tests._utils import absolute_path


def test_vmdk_container() -> None:
"""
Test that VMDK containers are properly opened.

```
VBoxManage createmedium disk --filename "./small.vmdk" --size 2 --format=VMDK
```
"""
path = absolute_path("_data/containers/vmdk/small.vmdk.gz")
gz_file = gzip.GzipFile(path)
fh = container.open(gz_file)
assert isinstance(fh, VmdkContainer)
a = fh.read(20)
assert a == b"\x00" * 20
assert fh.tell() == 20
fh.seek(0, whence=io.SEEK_END)
assert fh.tell() == 2097152
fh.close()
gz_file.close()


def test_vmdk_detect_path() -> None:
"""Test that VMDK containers are properly opened, when using the extension based matching."""
vfs = VirtualFilesystem()
vfs.map_file("small.vmdk", absolute_path("_data/containers/vmdk/small.vmdk.gz"), compression="gzip")
fh = container.open(vfs.path("small.vmdk"))
assert isinstance(fh, VmdkContainer)
a = fh.read(20)
assert a == b"\x00" * 20
assert fh.tell() == 20
fh.seek(0, whence=io.SEEK_END)
assert fh.tell() == 2097152