Skip to content

Commit 954d9b1

Browse files
authored
Add test for virtual ntfs filesystem mount to test_mount.py
1 parent 6b21bdf commit 954d9b1

File tree

1 file changed

+77
-1
lines changed

1 file changed

+77
-1
lines changed

tests/tools/test_mount.py

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,42 @@
44
from typing import TYPE_CHECKING
55
from unittest.mock import patch
66

7+
import pytest
8+
from dissect.ntfs import NTFS
9+
710
from dissect.target.filesystem import VirtualFilesystem
11+
from dissect.target.filesystems.dir import DirectoryFilesystem
12+
from dissect.target.helpers import loaderutil
813
from dissect.target.tools.mount import main as target_mount
914
from dissect.target.volume import Volume
15+
from tests._utils import absolute_path
1016

1117
if TYPE_CHECKING:
12-
import pytest
18+
from pathlib import Path
1319

1420
from dissect.target.target import Target
1521

1622

23+
@pytest.fixture
24+
def mock_ntfs_dirfs(tmp_path: Path) -> Path:
25+
root = tmp_path
26+
27+
# Cleanup first (conftest creates a MockTarget- tempfile)
28+
for item in root.iterdir():
29+
item.unlink()
30+
31+
# Create files
32+
(root / "$Boot").touch()
33+
(root / "$Extend_$Usnjrnl_$J").touch()
34+
(root / "$Secure_$SDS").touch()
35+
36+
# Only need this to exist up until the root directory record to make dissect.ntfs happy
37+
with absolute_path("_data/plugins/filesystem/ntfs/mft/mft.raw").open("rb") as fh:
38+
(root / "$MFT").write_bytes(fh.read(10 * 1024))
39+
40+
return root
41+
42+
1743
def test_duplicate_volume_name(target_bare: Target, monkeypatch: pytest.MonkeyPatch) -> None:
1844
with monkeypatch.context() as m:
1945
m.setattr("sys.argv", ["target-mount", "mock-target", "mock-mount"])
@@ -78,3 +104,53 @@ def test_mounting_multi_volume_filesystem(target_bare: Target, monkeypatch: pyte
78104
vfs = MockDissectMount.call_args[0][0]
79105

80106
assert vfs.listdir("/filesystems") == ["first", "second"]
107+
108+
109+
def test_mounting_virtual_ntfs_filesystem(
110+
target_bare: Target,
111+
monkeypatch: pytest.MonkeyPatch,
112+
mock_ntfs_dirfs: Path,
113+
) -> None:
114+
with monkeypatch.context() as m:
115+
m.setattr("sys.argv", ["target-mount", "mock-target", "mock-mount"])
116+
m.setattr("dissect.target.tools.mount.HAS_FUSE", True)
117+
118+
with (
119+
patch("dissect.target.tools.mount.open_target", return_value=target_bare),
120+
patch("dissect.target.tools.mount.FUSE", create=True) as MockFUSE,
121+
patch("dissect.target.tools.mount.DissectMount", create=True) as MockDissectMount,
122+
):
123+
# Use the mock_ntfs_dirfs fixture for the NTFS files
124+
dir_fs = DirectoryFilesystem(mock_ntfs_dirfs)
125+
virtual_fs = VirtualFilesystem()
126+
virtual_fs.map_fs("", dir_fs)
127+
128+
# Add the VirtualFileSystem
129+
target_bare.filesystems.add(virtual_fs)
130+
# Mount the VirtualFileSystem as c:
131+
target_bare.fs.mount("c:", virtual_fs)
132+
133+
loaderutil.add_virtual_ntfs_filesystem(
134+
target_bare,
135+
virtual_fs,
136+
usnjrnl_path="$Extend_$Usnjrnl_$J",
137+
sds_path="$Secure_$SDS",
138+
)
139+
140+
# The loaderutil should now have made a mock NTFS
141+
ntfs_obj = getattr(virtual_fs, "ntfs", None)
142+
assert isinstance(ntfs_obj, NTFS)
143+
144+
target_mount()
145+
146+
MockFUSE.assert_called_once()
147+
MockDissectMount.assert_called_once()
148+
vfs = MockDissectMount.call_args[0][0]
149+
150+
# Only the VirtualFileSystem should be available in /filesystems, not the mock NTFS
151+
assert vfs.listdir("/filesystems") == ["fs_0"]
152+
# The VirtualFileSystem should have the NTFS files
153+
required_ntfs_files = ["$Extend_$Usnjrnl_$J", "$MFT", "$Secure_$SDS", "$Boot"]
154+
assert all(file in required_ntfs_files for file in vfs.listdir("/filesystems/fs_0"))
155+
# The c: volume should be mounted, and should be the only mount
156+
assert vfs.listdir("/fs") == ["c:"]

0 commit comments

Comments
 (0)