dissect.target 3.9.dev24__py3-none-any.whl → 3.9.dev26__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -183,7 +183,7 @@ def open(item: Union[list, str, BinaryIO, Path], *args, **kwargs):
183
183
  first_fh = first
184
184
  else:
185
185
  first_path = first
186
- if first_path.exists():
186
+ if first_path.is_file():
187
187
  first_fh = first.open("rb")
188
188
  first_fh_opened = True
189
189
 
@@ -213,4 +213,6 @@ register("vhdx", "VhdxContainer")
213
213
  register("vhd", "VhdContainer")
214
214
  register("qcow2", "QCow2Container")
215
215
  register("vdi", "VdiContainer")
216
+ register("hdd", "HddContainer")
217
+ register("hds", "HdsContainer")
216
218
  register("split", "SplitContainer")
@@ -0,0 +1,37 @@
1
+ import io
2
+ from pathlib import Path
3
+ from typing import BinaryIO, Union
4
+
5
+ from dissect.hypervisor import hdd
6
+
7
+ from dissect.target.container import Container
8
+
9
+
10
+ class HddContainer(Container):
11
+ def __init__(self, fh: Path, *args, **kwargs):
12
+ if hasattr(fh, "read"):
13
+ raise TypeError("HddContainer can only be opened by path")
14
+
15
+ self.hdd = hdd.HDD(fh)
16
+ self.stream = self.hdd.open()
17
+ super().__init__(fh, self.stream.size, *args, **kwargs)
18
+
19
+ @staticmethod
20
+ def detect_fh(fh: BinaryIO, original: Union[list, BinaryIO]) -> bool:
21
+ return False
22
+
23
+ @staticmethod
24
+ def detect_path(path: Path, original: Union[list, BinaryIO]) -> bool:
25
+ return path.suffix.lower() == ".hdd"
26
+
27
+ def read(self, length: int) -> bytes:
28
+ return self.stream.read(length)
29
+
30
+ def seek(self, offset: int, whence: int = io.SEEK_SET) -> int:
31
+ return self.stream.seek(offset, whence)
32
+
33
+ def tell(self) -> int:
34
+ return self.stream.tell()
35
+
36
+ def close(self) -> None:
37
+ self.stream.close()
@@ -0,0 +1,41 @@
1
+ import io
2
+ from pathlib import Path
3
+ from typing import BinaryIO, Union
4
+
5
+ from dissect.hypervisor.disk import hdd
6
+ from dissect.hypervisor.disk.c_hdd import c_hdd
7
+
8
+ from dissect.target.container import Container
9
+
10
+
11
+ class HdsContainer(Container):
12
+ def __init__(self, fh: Union[BinaryIO, Path], *args, **kwargs):
13
+ f = fh
14
+ if not hasattr(fh, "read"):
15
+ f = fh.open("rb")
16
+
17
+ self.hds = hdd.HDS(f)
18
+ super().__init__(fh, self.hds.size, *args, **kwargs)
19
+
20
+ @staticmethod
21
+ def detect_fh(fh: BinaryIO, original: Union[list, BinaryIO]) -> bool:
22
+ sig = fh.read(16)
23
+ fh.seek(-16, io.SEEK_CUR)
24
+
25
+ return sig in (c_hdd.SIGNATURE_STRUCTURED_DISK_V1, c_hdd.SIGNATURE_STRUCTURED_DISK_V2)
26
+
27
+ @staticmethod
28
+ def detect_path(path: Path, original: Union[list, BinaryIO]) -> bool:
29
+ return path.suffix.lower() == ".hds"
30
+
31
+ def read(self, length: int) -> bytes:
32
+ return self.hds.read(length)
33
+
34
+ def seek(self, offset: int, whence: int = io.SEEK_SET) -> int:
35
+ return self.hds.seek(offset, whence)
36
+
37
+ def tell(self) -> int:
38
+ return self.hds.tell()
39
+
40
+ def close(self) -> None:
41
+ self.hds.close()
dissect/target/loader.py CHANGED
@@ -182,6 +182,8 @@ register("tar", "TarLoader")
182
182
  register("vmx", "VmxLoader")
183
183
  register("vmwarevm", "VmwarevmLoader")
184
184
  register("hyperv", "HyperVLoader")
185
+ register("pvs", "PvsLoader")
186
+ register("pvm", "PvmLoader")
185
187
  register("ovf", "OvfLoader")
186
188
  register("vbox", "VBoxLoader")
187
189
  register("ewf", "EwfLoader")
@@ -0,0 +1,14 @@
1
+ from pathlib import Path
2
+
3
+ from dissect.target.loaders.pvs import PvsLoader
4
+
5
+
6
+ class PvmLoader(PvsLoader):
7
+ """Parallels VM directory (.pvm)."""
8
+
9
+ def __init__(self, path: Path, **kwargs):
10
+ super().__init__(path.joinpath("config.pvs"))
11
+
12
+ @staticmethod
13
+ def detect(path: Path) -> bool:
14
+ return path.is_dir() and path.suffix.lower() == ".pvm" and path.joinpath("config.pvs").exists()
@@ -0,0 +1,35 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+ from typing import TYPE_CHECKING
5
+
6
+ from dissect.hypervisor import pvs
7
+
8
+ from dissect.target.containers.hdd import HddContainer
9
+ from dissect.target.loader import Loader
10
+
11
+ if TYPE_CHECKING:
12
+ from dissect.target import Target
13
+
14
+
15
+ class PvsLoader(Loader):
16
+ """Parallels VM configuration file (config.pvs)."""
17
+
18
+ def __init__(self, path: Path, **kwargs):
19
+ path = path.resolve()
20
+
21
+ super().__init__(path)
22
+ self.pvs = pvs.PVS(path.open("rt"))
23
+ self.base_dir = path.parent
24
+
25
+ @staticmethod
26
+ def detect(path: Path) -> bool:
27
+ return path.suffix.lower() == ".pvs"
28
+
29
+ def map(self, target: Target) -> None:
30
+ for disk in self.pvs.disks():
31
+ path = self.base_dir.joinpath(disk)
32
+ try:
33
+ target.disks.add(HddContainer(path))
34
+ except Exception:
35
+ target.log.exception("Failed to load HDD: %s", disk)
@@ -4,7 +4,7 @@ import logging
4
4
  import re
5
5
  import uuid
6
6
  from struct import unpack
7
- from typing import Iterator, Optional, Tuple, Union
7
+ from typing import Iterator, Optional, Union
8
8
 
9
9
  from dissect.target.filesystem import Filesystem
10
10
  from dissect.target.helpers.fsutil import TargetPath
@@ -277,7 +277,7 @@ class UnixPlugin(OSPlugin):
277
277
  def parse_fstab(
278
278
  fstab: TargetPath,
279
279
  log: logging.Logger = log,
280
- ) -> Iterator[Tuple[Union[uuid.UUID, str], str, str, str]]:
280
+ ) -> Iterator[tuple[Union[uuid.UUID, str], str, str, str]]:
281
281
  """Parse fstab file and return a generator that streams the details of entries,
282
282
  with unsupported FS types and block devices filtered away.
283
283
  """
@@ -315,7 +315,9 @@ def parse_fstab(
315
315
  if dev.startswith(("/dev/mapper", "/dev/gpt")):
316
316
  volume_name = dev.rsplit("/")[-1]
317
317
  elif dev.startswith("/dev/") and dev.count("/") == 3:
318
- volume_name = "-".join(dev.rsplit("/")[-2:])
318
+ # When composing a vg-lv name, LVM2 replaces hyphens with double hyphens in the vg and lv names
319
+ # Emulate that here when combining the vg and lv names
320
+ volume_name = "-".join(part.replace("-", "--") for part in dev.rsplit("/")[-2:])
319
321
  elif dev.startswith("UUID="):
320
322
  dev_id = dev.split("=")[1]
321
323
  try:
@@ -48,5 +48,7 @@ class LvmVolumeSystem(LogicalVolumeSystem):
48
48
 
49
49
  def _volumes(self) -> Iterator[Volume]:
50
50
  for num, lv in enumerate(self.lvm.volume_group.logical_volumes):
51
- name = f"{lv.vg.name}-{lv.metadata.name}"
51
+ # When composing a vg-lv name, LVM2 replaces hyphens with double hyphens in the vg and lv names
52
+ # Emulate that here for the volume name
53
+ name = f"{lv.vg.name.replace('-', '--')}-{lv.metadata.name.replace('-', '--')}"
52
54
  yield Volume(lv, num, None, lv.size, None, name, raw=lv, vs=self)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dissect.target
3
- Version: 3.9.dev24
3
+ Version: 3.9.dev26
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
@@ -1,8 +1,8 @@
1
1
  dissect/target/__init__.py,sha256=Oc7ounTgq2hE4nR6YcNabetc7SQA40ldSa35VEdZcQU,63
2
- dissect/target/container.py,sha256=PPL9YFQXgKkT7PL1dIwhkg35S7PcupZLDebDt4U1Omk,7665
2
+ dissect/target/container.py,sha256=R8M9EE7DqKq8DeMuekcpR1nxtZ827zuqmTmO4s7PYkg,7730
3
3
  dissect/target/exceptions.py,sha256=w3qNa4dtGpxUkOCfmAQtvseQrpQq9qmO9wIbztRlIDQ,2273
4
4
  dissect/target/filesystem.py,sha256=YJfuRzd37DIm91cVPlMZK-XjiJ1UCZG93htaYcSUrIk,46276
5
- dissect/target/loader.py,sha256=74FWz2CC75LmovE38obeOghVyUhys0ttpxgXCNsCBwQ,6985
5
+ dissect/target/loader.py,sha256=Rg4X-4Lr2EtTzBA04WFWtPESF2iR1JNahKccMBImLZ0,7043
6
6
  dissect/target/plugin.py,sha256=qF0okKg7TxYfiLVxpCWhb18gvDsNtr9nCYD7kSeaYIU,31955
7
7
  dissect/target/report.py,sha256=06uiP4MbNI8cWMVrC1SasNS-Yg6ptjVjckwj8Yhe0Js,7958
8
8
  dissect/target/target.py,sha256=TgDY-yAsReOQOG-Phz_m1vdNucdbk9fUI_RMZpMeYG8,28334
@@ -10,6 +10,8 @@ dissect/target/volume.py,sha256=vHBXdDttpiu-Q_oWycNM7fdJ5N8Ob7-i_UBJK9DEs24,1502
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=VEzjFH7R5GQB7ywKKyarYn9b9QdrBPxQ667Xh5WNmdQ,1370
13
+ dissect/target/containers/hdd.py,sha256=CenRlMNDmevCqccGPbSzOIPbdKIl0rHCtQ5kThOZQAU,1046
14
+ dissect/target/containers/hds.py,sha256=0nh9qoJ0SH0ADCEykpUrIU2tGt9xsksNAxs7ocILtdA,1175
13
15
  dissect/target/containers/qcow2.py,sha256=RWmFeXfxAkU3OMGo7vfnOQTRlcWBH5-96LP37JB2o3o,1159
14
16
  dissect/target/containers/raw.py,sha256=7fRHA5zIxBcBuGlACIJWvaSivjH98meNkyVLaR1Mi7k,1064
15
17
  dissect/target/containers/split.py,sha256=dYibfeVddm-ux_ORjIAQxhqbWc9LKws3b8gYIXnINj4,2377
@@ -64,6 +66,8 @@ dissect/target/loaders/local.py,sha256=JEZN17wg4Tmw7nxQp2_6z97UuDx8ORxNLsgFs4rQh
64
66
  dissect/target/loaders/ovf.py,sha256=3nd9ZinRRH71Qp0_r-lZURafNdXiKjyMw1zsgZRwjgo,924
65
67
  dissect/target/loaders/phobos.py,sha256=r9mkITM8iuO60BHzDt-GkPMOFn4YWH0ahPRLSyEXAmA,1864
66
68
  dissect/target/loaders/profile.py,sha256=73BlV0zAAPWBYY0tZAaX154kf7TZmwAwZhwCY4E43_A,1633
69
+ dissect/target/loaders/pvm.py,sha256=b-PvHNTbRVdOnf7-OR5dbikbDTCFlW85b-9Z8PEL2Cs,406
70
+ dissect/target/loaders/pvs.py,sha256=dMqdYSBQtH9QLM3tdu0mokLBcn73edg_HUtYtqrdi6E,955
67
71
  dissect/target/loaders/raw.py,sha256=03OXVlvkqwR29XYu7WPg3pmGtYd_4QJEGnkAuvIrdPs,355
68
72
  dissect/target/loaders/remote.py,sha256=AoI7-RxH2UMjNWnuHbNaieZycApTY3YZmk4wkQAwFt0,8820
69
73
  dissect/target/loaders/res.py,sha256=2IAm-f83fvMUeK5J0g5jNVy2-24k8qKYijimcFvZ47I,8832
@@ -135,7 +139,7 @@ dissect/target/plugins/general/scrape.py,sha256=eBcFv6Po4FJ9HV829U3Bc5eWPtsuqFpd
135
139
  dissect/target/plugins/general/users.py,sha256=qCXXsNOf3-IBgMUJjeH56RVhFeAsTSkXXaxWX-irYvU,2140
136
140
  dissect/target/plugins/os/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
137
141
  dissect/target/plugins/os/unix/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
138
- dissect/target/plugins/os/unix/_os.py,sha256=3ZlOoo3Gg3yLq9TDgS6fY66aXI0qNsgWrEJoUQ8xLU0,12132
142
+ dissect/target/plugins/os/unix/_os.py,sha256=VUxsf3DzZlMhBsPrKKn3U5Wd4I4WyrwlEnyTeFoMi5s,12336
139
143
  dissect/target/plugins/os/unix/cronjobs.py,sha256=3g2_EoXmRIvqwhASnn6p-iN3c8g70bLMWfzyN38znbA,3508
140
144
  dissect/target/plugins/os/unix/datetime.py,sha256=21OyCR1g6wa6q5sGZTK3Kv4Jduoxj3o4A8GsdqK9JDQ,1510
141
145
  dissect/target/plugins/os/unix/generic.py,sha256=R9fi1qNDaY5_l5g0XVLuXv1jOSz9wpb6zPVmWY3rczk,1835
@@ -254,12 +258,12 @@ dissect/target/tools/dump/utils.py,sha256=nYcLQvPpDgzckM62hokGBh4z32DNH6d6oA8Kel
254
258
  dissect/target/volumes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
255
259
  dissect/target/volumes/bde.py,sha256=gYGg5yF9MNARwNzEkrEfZmKkxyZW4rhLkpdnPJCbhGk,3662
256
260
  dissect/target/volumes/disk.py,sha256=95grSsPt1BLVpKwTclwQYzPFGKTkFFqapIk0RoGWf38,968
257
- dissect/target/volumes/lvm.py,sha256=zXAfszxNR6tOGrKAtAa_E-JhjI-sXQyR4VYLXD-kqCw,1616
261
+ dissect/target/volumes/lvm.py,sha256=_kIB1mdRs1OFhRgoT4VEP5Fv8imQnI7oQ_ie4x710tQ,1814
258
262
  dissect/target/volumes/vmfs.py,sha256=mlAJ8278tYaoRjk1u6tFFlCaDQUrVu5ZZE4ikiFvxi8,1707
259
- dissect.target-3.9.dev24.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
260
- dissect.target-3.9.dev24.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
261
- dissect.target-3.9.dev24.dist-info/METADATA,sha256=vU6b1BQzZW0wqrloCcyyO2P8Yaw8f9PMmJYd3_os_UE,9984
262
- dissect.target-3.9.dev24.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
263
- dissect.target-3.9.dev24.dist-info/entry_points.txt,sha256=tvFPa-Ap-gakjaPwRc6Fl6mxHzxEZ_arAVU-IUYeo_s,447
264
- dissect.target-3.9.dev24.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
265
- dissect.target-3.9.dev24.dist-info/RECORD,,
263
+ dissect.target-3.9.dev26.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
264
+ dissect.target-3.9.dev26.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
265
+ dissect.target-3.9.dev26.dist-info/METADATA,sha256=KCYCb5u-wp6D3lF6nmSnDg9Qudwq5ktMBIs_I4OgxtI,9984
266
+ dissect.target-3.9.dev26.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
267
+ dissect.target-3.9.dev26.dist-info/entry_points.txt,sha256=tvFPa-Ap-gakjaPwRc6Fl6mxHzxEZ_arAVU-IUYeo_s,447
268
+ dissect.target-3.9.dev26.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
269
+ dissect.target-3.9.dev26.dist-info/RECORD,,