dissect.target 3.13.dev17__py3-none-any.whl → 3.13.dev18__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- dissect/target/target.py +26 -2
- dissect/target/volume.py +3 -0
- dissect/target/volumes/ddf.py +51 -0
- {dissect.target-3.13.dev17.dist-info → dissect.target-3.13.dev18.dist-info}/METADATA +1 -1
- {dissect.target-3.13.dev17.dist-info → dissect.target-3.13.dev18.dist-info}/RECORD +10 -9
- {dissect.target-3.13.dev17.dist-info → dissect.target-3.13.dev18.dist-info}/COPYRIGHT +0 -0
- {dissect.target-3.13.dev17.dist-info → dissect.target-3.13.dev18.dist-info}/LICENSE +0 -0
- {dissect.target-3.13.dev17.dist-info → dissect.target-3.13.dev18.dist-info}/WHEEL +0 -0
- {dissect.target-3.13.dev17.dist-info → dissect.target-3.13.dev18.dist-info}/entry_points.txt +0 -0
- {dissect.target-3.13.dev17.dist-info → dissect.target-3.13.dev18.dist-info}/top_level.txt +0 -0
dissect/target/target.py
CHANGED
@@ -15,6 +15,7 @@ from dissect.target.exceptions import (
|
|
15
15
|
PluginNotFoundError,
|
16
16
|
TargetError,
|
17
17
|
UnsupportedPluginError,
|
18
|
+
VolumeSystemError,
|
18
19
|
)
|
19
20
|
from dissect.target.helpers import config
|
20
21
|
from dissect.target.helpers.loaderutil import extract_path_info
|
@@ -693,11 +694,16 @@ class DiskCollection(Collection[container.Container]):
|
|
693
694
|
disk.vs = volume.open(disk)
|
694
695
|
self.target.log.debug("Opened volume system: %s on %s", disk.vs, disk)
|
695
696
|
|
697
|
+
if not len(disk.vs.volumes):
|
698
|
+
raise VolumeSystemError("Volume system has no volumes")
|
699
|
+
|
696
700
|
for vol in disk.vs.volumes:
|
697
701
|
self.target.volumes.add(vol)
|
698
702
|
continue
|
699
703
|
except Exception as e:
|
700
|
-
self.target.log.warning(
|
704
|
+
self.target.log.warning(
|
705
|
+
"Can't identify volume system or no volumes found, adding as raw volume instead: %s", disk
|
706
|
+
)
|
701
707
|
self.target.log.debug("", exc_info=e)
|
702
708
|
|
703
709
|
# Fallthrough case for error and if we're part of a logical volume set
|
@@ -730,7 +736,25 @@ class VolumeCollection(Collection[volume.Volume]):
|
|
730
736
|
elif volume.is_encrypted(vol):
|
731
737
|
encrypted_volumes.append(vol)
|
732
738
|
else:
|
733
|
-
|
739
|
+
# We could be getting "regular" volume systems out of LVM or encrypted volumes
|
740
|
+
# Try to open each volume as a regular volume system, or add as a filesystem if it fails
|
741
|
+
try:
|
742
|
+
vs = volume.open(vol)
|
743
|
+
except Exception:
|
744
|
+
# If opening a volume system fails, there's likely none, so open as a filesystem instead
|
745
|
+
self.open(vol)
|
746
|
+
continue
|
747
|
+
|
748
|
+
if not len(vs.volumes):
|
749
|
+
self.open(vol)
|
750
|
+
continue
|
751
|
+
|
752
|
+
for new_vol in vs.volumes:
|
753
|
+
if new_vol.offset == 0:
|
754
|
+
self.target.log.info("Found volume with offset 0, opening as raw volume instead")
|
755
|
+
self.open(new_vol)
|
756
|
+
continue
|
757
|
+
new_volumes.append(new_vol)
|
734
758
|
|
735
759
|
self.target.log.debug("LVM volumes found: %s", lvm_volumes)
|
736
760
|
self.target.log.debug("Encrypted volumes found: %s", encrypted_volumes)
|
dissect/target/volume.py
CHANGED
@@ -22,6 +22,8 @@ vmfs = import_lazy("dissect.target.volumes.vmfs")
|
|
22
22
|
"""A lazy import of :mod:`dissect.target.volumes.vmfs`."""
|
23
23
|
md = import_lazy("dissect.target.volumes.md")
|
24
24
|
"""A lazy import of :mod:`dissect.target.volumes.md`."""
|
25
|
+
ddf = import_lazy("dissect.target.volumes.ddf")
|
26
|
+
"""A lazy import of :mod:`dissect.target.volumes.ddf`."""
|
25
27
|
bde = import_lazy("dissect.target.volumes.bde")
|
26
28
|
"""A lazy import of :mod:`dissect.target.volumes.bde`."""
|
27
29
|
luks = import_lazy("dissect.target.volumes.luks")
|
@@ -34,6 +36,7 @@ LOGICAL_VOLUME_MANAGERS: list[type[LogicalVolumeSystem]] = [
|
|
34
36
|
lvm.LvmVolumeSystem,
|
35
37
|
vmfs.VmfsVolumeSystem,
|
36
38
|
md.MdVolumeSystem,
|
39
|
+
ddf.DdfVolumeSystem,
|
37
40
|
]
|
38
41
|
"""All available :class:`LogicalVolumeSystem` classes."""
|
39
42
|
ENCRYPTED_VOLUME_MANAGERS: list[type[EncryptedVolumeSystem]] = [bde.BitlockerVolumeSystem, luks.LUKSVolumeSystem]
|
@@ -0,0 +1,51 @@
|
|
1
|
+
import io
|
2
|
+
from collections import defaultdict
|
3
|
+
from typing import BinaryIO, Iterator, Union
|
4
|
+
|
5
|
+
from dissect.volume.ddf.ddf import DDF, DEFAULT_SECTOR_SIZE, DDFPhysicalDisk
|
6
|
+
|
7
|
+
from dissect.target.volume import LogicalVolumeSystem, Volume
|
8
|
+
|
9
|
+
|
10
|
+
class DdfVolumeSystem(LogicalVolumeSystem):
|
11
|
+
def __init__(self, fh: Union[BinaryIO, list[BinaryIO]], *args, **kwargs):
|
12
|
+
self.ddf = DDF(fh)
|
13
|
+
super().__init__(fh, *args, **kwargs)
|
14
|
+
|
15
|
+
@classmethod
|
16
|
+
def open_all(cls, volumes: list[BinaryIO]) -> Iterator[LogicalVolumeSystem]:
|
17
|
+
sets = defaultdict(list)
|
18
|
+
|
19
|
+
for vol in volumes:
|
20
|
+
if not cls.detect_volume(vol):
|
21
|
+
continue
|
22
|
+
|
23
|
+
disk = DDFPhysicalDisk(vol)
|
24
|
+
sets[disk.anchor.DDF_Header_GUID].append(disk)
|
25
|
+
|
26
|
+
for devs in sets.values():
|
27
|
+
try:
|
28
|
+
yield cls(devs)
|
29
|
+
except Exception:
|
30
|
+
continue
|
31
|
+
|
32
|
+
@staticmethod
|
33
|
+
def _detect(fh: BinaryIO) -> bool:
|
34
|
+
vols = [fh] if not isinstance(fh, list) else fh
|
35
|
+
for vol in vols:
|
36
|
+
if DdfVolumeSystem.detect_volume(vol):
|
37
|
+
return True
|
38
|
+
return False
|
39
|
+
|
40
|
+
@staticmethod
|
41
|
+
def _detect_volume(fh: BinaryIO) -> bool:
|
42
|
+
fh.seek(-DEFAULT_SECTOR_SIZE, io.SEEK_END)
|
43
|
+
return int.from_bytes(fh.read(4), "big") == 0xDE11DE11
|
44
|
+
|
45
|
+
def _volumes(self) -> Iterator[Volume]:
|
46
|
+
# MD only supports one configuration and virtual disk but doing this as a loop
|
47
|
+
# makes it automatically safe for empty configurations
|
48
|
+
for conf in self.ddf.configurations:
|
49
|
+
for vd in conf.virtual_disks:
|
50
|
+
fh = vd.open()
|
51
|
+
yield Volume(fh, 1, None, vd.size, None, vd.name, vd.uuid, raw=self.ddf, vs=self)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: dissect.target
|
3
|
-
Version: 3.13.
|
3
|
+
Version: 3.13.dev18
|
4
4
|
Summary: This module ties all other Dissect modules together, it provides a programming API and command line tools which allow easy access to various data sources inside disk images or file collections (a.k.a. targets)
|
5
5
|
Author-email: Dissect Team <dissect@fox-it.com>
|
6
6
|
License: Affero General Public License v3
|
@@ -5,8 +5,8 @@ dissect/target/filesystem.py,sha256=A_KZbBBrj-aAjVkAvjreSsk0uX7MkJYMt9pHJjC3aw4,
|
|
5
5
|
dissect/target/loader.py,sha256=4ZdX-QJY83NPswTyNG31LUwYXdV1tuByrR2vKKg7d5k,7214
|
6
6
|
dissect/target/plugin.py,sha256=7Gss9pofcWKemwwfeAJ7E6nmJSNnZkBkxTcxUY2wzmk,40526
|
7
7
|
dissect/target/report.py,sha256=06uiP4MbNI8cWMVrC1SasNS-Yg6ptjVjckwj8Yhe0Js,7958
|
8
|
-
dissect/target/target.py,sha256=
|
9
|
-
dissect/target/volume.py,sha256=
|
8
|
+
dissect/target/target.py,sha256=FVCQYMgb0fo4R6x5O3lSPuDJzVQxnIcWCqFtdQMdgTg,30504
|
9
|
+
dissect/target/volume.py,sha256=WuwT6AvGJPrlA-r5-oLHjBI4OuyFyv_2aSnUK_1q5DA,15512
|
10
10
|
dissect/target/containers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
11
11
|
dissect/target/containers/asdf.py,sha256=g8omgyCvXBPd6ZZ1TKmaHNfzfs7W1HqmAsEAdDaXYLk,1398
|
12
12
|
dissect/target/containers/ewf.py,sha256=waG6_VOXFis8d9bxyHJCBXFbLWUfkTshHRAEqoiQEqo,1425
|
@@ -297,15 +297,16 @@ dissect/target/tools/dump/state.py,sha256=ZBNz4ou2Xk20K1H8R83S1gq6qcqPvPPVAaPWzp
|
|
297
297
|
dissect/target/tools/dump/utils.py,sha256=nYcLQvPpDgzckM62hokGBh4z32DNH6d6oA8KelvoPMU,7564
|
298
298
|
dissect/target/volumes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
299
299
|
dissect/target/volumes/bde.py,sha256=wUdFtzr55vLm6biDxOa65byh7zJxgXdqHaey7B_jVKw,3659
|
300
|
+
dissect/target/volumes/ddf.py,sha256=E4K1iLOXh7cUqyT9VJqHGu7aSQjzNPxonb9RmZZ-ct0,1727
|
300
301
|
dissect/target/volumes/disk.py,sha256=95grSsPt1BLVpKwTclwQYzPFGKTkFFqapIk0RoGWf38,968
|
301
302
|
dissect/target/volumes/luks.py,sha256=mgxZPDrryMZlhq1jiEWtft8rFjESq5_3HLYNsM84dT4,4110
|
302
303
|
dissect/target/volumes/lvm.py,sha256=Yj54NlD4dExkSupY56F_K3nNuleqj87phy-V09GR3QU,2247
|
303
304
|
dissect/target/volumes/md.py,sha256=N-rxdAeTWR-f5LpwnP4RQZSHP4rzZSo45JMHn8F6Cp8,1652
|
304
305
|
dissect/target/volumes/vmfs.py,sha256=mlAJ8278tYaoRjk1u6tFFlCaDQUrVu5ZZE4ikiFvxi8,1707
|
305
|
-
dissect.target-3.13.
|
306
|
-
dissect.target-3.13.
|
307
|
-
dissect.target-3.13.
|
308
|
-
dissect.target-3.13.
|
309
|
-
dissect.target-3.13.
|
310
|
-
dissect.target-3.13.
|
311
|
-
dissect.target-3.13.
|
306
|
+
dissect.target-3.13.dev18.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
|
307
|
+
dissect.target-3.13.dev18.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
|
308
|
+
dissect.target-3.13.dev18.dist-info/METADATA,sha256=-hfPY54YoeRrjNIVFKc5zW1sccqHSp6eXq9Kc9cBwbQ,10976
|
309
|
+
dissect.target-3.13.dev18.dist-info/WHEEL,sha256=Xo9-1PvkuimrydujYJAjF7pCkriuXBpUPEjma1nZyJ0,92
|
310
|
+
dissect.target-3.13.dev18.dist-info/entry_points.txt,sha256=tvFPa-Ap-gakjaPwRc6Fl6mxHzxEZ_arAVU-IUYeo_s,447
|
311
|
+
dissect.target-3.13.dev18.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
|
312
|
+
dissect.target-3.13.dev18.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
{dissect.target-3.13.dev17.dist-info → dissect.target-3.13.dev18.dist-info}/entry_points.txt
RENAMED
File without changes
|
File without changes
|