Skip to content

Commit

Permalink
Add support for anon filesystems
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthijs Vos committed Jan 8, 2025
1 parent 5ae9fec commit 00a606b
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 41 deletions.
2 changes: 1 addition & 1 deletion dissect/target/loaders/acquire.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
FILESYSTEMS_LEGACY_ROOT = "sysvol"


def _get_root(path: Path) -> Path | None:
def _get_root(path: Path) -> Path | None:
if path.is_file():
fh = path.open("rb")
if TarFilesystem._detect(fh):
Expand Down
18 changes: 14 additions & 4 deletions dissect/target/loaders/dir.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import re
import zipfile
from collections import defaultdict
from pathlib import Path
Expand All @@ -17,7 +18,7 @@
from dissect.target import Target

PREFIXES = ["", "fs"]

ANON_FS_RE = re.compile(r"^fs[0-9]+$")

class DirLoader(Loader):
"""Load a directory as a filesystem."""
Expand Down Expand Up @@ -91,7 +92,10 @@ def map_dirs(
vfs = dfs[0]

fs_to_add.append(vfs)
target.fs.mount(drive_letter.lower() + ":", vfs)
mount_letter = drive_letter.lower()
if mount_letter != "$fs$":
mount_letter += ":"
target.fs.mount(mount_letter, vfs)
else:
fs_to_add.extend(dfs)

Expand Down Expand Up @@ -138,12 +142,18 @@ def find_dirs(path: Path) -> tuple[str, list[Path]]:
if p.name == "sysvol":
dirs.append(('c', p))
else:
dirs.append(p)
dirs.append((p.name[0], p))

if not os_type:
os_type = os_type_from_path(p)

if not os_type:
if p.name == "$fs$":
dirs.append(('$fs$', p))
for anon_fs in p.iterdir():
if ANON_FS_RE.match(anon_fs.name):
dirs.append(anon_fs)

if len(dirs) == 0:
os_type = os_type_from_path(path)
dirs = [path]

Expand Down
70 changes: 34 additions & 36 deletions tests/loaders/test_acquire.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,32 @@

from dissect.target import Target
from dissect.target.loaders.acquire import AcquireLoader
from dissect.target.loaders.tar import TarLoader
from dissect.target.plugins.os.windows._os import WindowsPlugin
from tests._utils import absolute_path



# def test_tar_sensitive_drive_letter(target_bare: Target) -> None:
# # TODO: determine if we need this test
# tar_file = absolute_path("_data/loaders/acquire/uppercase_driveletter.tar")
#
# loader = AcquireLoader(Path(tar_file))
# loader.map(target_bare)
#
# # mounts = / and c:
# assert sorted(target_bare.fs.mounts.keys()) == ["/", "c:"]
# assert "C:" not in target_bare.fs.mounts.keys()
#
# # Initialize our own WindowsPlugin to override the detection
# target_bare._os_plugin = WindowsPlugin.create(target_bare, target_bare.fs.mounts["c:"])
# target_bare._init_os()
#
# # sysvol is now added
# assert sorted(target_bare.fs.mounts.keys()) == ["/", "c:", "sysvol"]
#
# # WindowsPlugin sets the case sensitivity to False
# assert target_bare.fs.get("C:/test.file").open().read() == b"hello_world"
# assert target_bare.fs.get("c:/test.file").open().read() == b"hello_world"
def test_tar_sensitive_drive_letter(target_bare: Target) -> None:
tar_file = absolute_path("_data/loaders/acquire/uppercase_driveletter.tar")

loader = AcquireLoader(Path(tar_file))
assert loader.detect(Path(tar_file))
loader.map(target_bare)

# mounts = c:
assert sorted(target_bare.fs.mounts.keys()) == ["c:"]

# Initialize our own WindowsPlugin to override the detection
target_bare._os_plugin = WindowsPlugin.create(target_bare, target_bare.fs.mounts["c:"])
target_bare._init_os()

# sysvol is now added
assert sorted(target_bare.fs.mounts.keys()) == ["c:", "sysvol"]

# WindowsPlugin sets the case sensitivity to False
assert target_bare.fs.get("C:/test.file").open().read() == b"hello_world"
assert target_bare.fs.get("c:/test.file").open().read() == b"hello_world"


@pytest.mark.parametrize(
Expand All @@ -44,7 +44,10 @@
],
)
def test_tar_loader_windows_sysvol_formats(target_default: Target, archive: str, expected_drive_letter: str) -> None:
loader = AcquireLoader(Path(absolute_path(archive)))
path = Path(absolute_path(archive))
assert AcquireLoader.detect(path)

loader = AcquireLoader(path)
loader.map(target_default)

assert WindowsPlugin.detect(target_default)
Expand All @@ -53,17 +56,12 @@ def test_tar_loader_windows_sysvol_formats(target_default: Target, archive: str,
assert target_default.fs.get(f"{expected_drive_letter}/Windows/System32/foo.txt")


# TODO check this one
# def test_tar_anonymous_filesystems(target_default: Target) -> None:
# tar_file = absolute_path("_data/loaders/tar/test-anon-filesystems.tar")
#
# loader = AcquireLoader(Path(tar_file))
# loader.map(target_default)
#
# # mounts = $fs$/fs0, $fs$/fs1 and /
# assert len(target_default.fs.mounts) == 3
# assert "$fs$/fs0" in target_default.fs.mounts.keys()
# assert "$fs$/fs1" in target_default.fs.mounts.keys()
# assert "/" in target_default.fs.mounts.keys()
# assert target_default.fs.get("$fs$/fs0/foo").open().read() == b"hello world\n"
# assert target_default.fs.get("$fs$/fs1/bar").open().read() == b"hello world\n"
def test_tar_anonymous_filesystems(target_default: Target) -> None:
tar_file = Path(absolute_path("_data/loaders/acquire/test-anon-filesystems.tar"))
assert AcquireLoader.detect(tar_file)

loader = AcquireLoader(tar_file)
loader.map(target_default)

assert target_default.fs.get("$fs$/fs0/foo").open().read() == b"hello world\n"
assert target_default.fs.get("$fs$/fs1/bar").open().read() == b"hello world\n"

0 comments on commit 00a606b

Please sign in to comment.