dissect.hypervisor 3.17.dev3__tar.gz → 3.18.dev1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/PKG-INFO +3 -2
- dissect_hypervisor-3.18.dev1/dissect/hypervisor/tools/vmtar.py +20 -0
- dissect_hypervisor-3.18.dev1/dissect/hypervisor/util/vmtar.py +122 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect.hypervisor.egg-info/PKG-INFO +3 -2
- dissect_hypervisor-3.18.dev1/dissect.hypervisor.egg-info/SOURCES.txt +86 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect.hypervisor.egg-info/entry_points.txt +1 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/pyproject.toml +3 -2
- {dissect_hypervisor-3.17.dev3/tests/docs → dissect_hypervisor-3.18.dev1/tests/_docs}/conf.py +2 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/tests/conftest.py +15 -15
- dissect_hypervisor-3.18.dev1/tests/descriptor/__init__.py +0 -0
- dissect_hypervisor-3.18.dev1/tests/disk/__init__.py +0 -0
- dissect_hypervisor-3.18.dev1/tests/util/__init__.py +0 -0
- dissect_hypervisor-3.18.dev1/tests/util/test_vmtar.py +80 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/tox.ini +8 -6
- dissect_hypervisor-3.17.dev3/dissect/hypervisor/util/vmtar.py +0 -57
- dissect_hypervisor-3.17.dev3/dissect.hypervisor.egg-info/SOURCES.txt +0 -82
- dissect_hypervisor-3.17.dev3/tests/test_vmtar.py +0 -27
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/.git-blame-ignore-revs +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/COPYRIGHT +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/LICENSE +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/MANIFEST.in +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/README.md +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/__init__.py +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/descriptor/__init__.py +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/descriptor/c_hyperv.py +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/descriptor/hyperv.py +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/descriptor/ovf.py +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/descriptor/pvs.py +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/descriptor/vbox.py +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/descriptor/vmx.py +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/disk/__init__.py +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/disk/c_hdd.py +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/disk/c_qcow2.py +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/disk/c_vdi.py +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/disk/c_vhd.py +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/disk/c_vhdx.py +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/disk/c_vmdk.py +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/disk/hdd.py +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/disk/qcow2.py +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/disk/vdi.py +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/disk/vhd.py +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/disk/vhdx.py +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/disk/vmdk.py +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/exceptions.py +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/tools/__init__.py +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/tools/envelope.py +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/util/__init__.py +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/util/envelope.py +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect.hypervisor.egg-info/dependency_links.txt +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect.hypervisor.egg-info/requires.txt +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect.hypervisor.egg-info/top_level.txt +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/setup.cfg +0 -0
- {dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/tests/__init__.py +0 -0
- {dissect_hypervisor-3.17.dev3/tests/data → dissect_hypervisor-3.18.dev1/tests/_data/descriptor/hyperv}/test.VMRS +0 -0
- {dissect_hypervisor-3.17.dev3/tests/data → dissect_hypervisor-3.18.dev1/tests/_data/descriptor/hyperv}/test.vmcx +0 -0
- {dissect_hypervisor-3.17.dev3/tests/data → dissect_hypervisor-3.18.dev1/tests/_data/descriptor/vmx}/encrypted.vmx +0 -0
- {dissect_hypervisor-3.17.dev3/tests/data → dissect_hypervisor-3.18.dev1/tests/_data/disk/hdd}/expanding.hdd/DiskDescriptor.xml +0 -0
- {dissect_hypervisor-3.17.dev3/tests/data → dissect_hypervisor-3.18.dev1/tests/_data/disk/hdd}/expanding.hdd/expanding.hdd +0 -0
- {dissect_hypervisor-3.17.dev3/tests/data → dissect_hypervisor-3.18.dev1/tests/_data/disk/hdd}/expanding.hdd/expanding.hdd.0.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz +0 -0
- {dissect_hypervisor-3.17.dev3/tests/data → dissect_hypervisor-3.18.dev1/tests/_data/disk/hdd}/plain.hdd/DiskDescriptor.xml +0 -0
- {dissect_hypervisor-3.17.dev3/tests/data → dissect_hypervisor-3.18.dev1/tests/_data/disk/hdd}/plain.hdd/plain.hdd +0 -0
- {dissect_hypervisor-3.17.dev3/tests/data → dissect_hypervisor-3.18.dev1/tests/_data/disk/hdd}/plain.hdd/plain.hdd.0.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz +0 -0
- {dissect_hypervisor-3.17.dev3/tests/data → dissect_hypervisor-3.18.dev1/tests/_data/disk/hdd}/split.hdd/DiskDescriptor.xml +0 -0
- {dissect_hypervisor-3.17.dev3/tests/data → dissect_hypervisor-3.18.dev1/tests/_data/disk/hdd}/split.hdd/split.hdd +0 -0
- {dissect_hypervisor-3.17.dev3/tests/data → dissect_hypervisor-3.18.dev1/tests/_data/disk/hdd}/split.hdd/split.hdd.0.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz +0 -0
- {dissect_hypervisor-3.17.dev3/tests/data → dissect_hypervisor-3.18.dev1/tests/_data/disk/hdd}/split.hdd/split.hdd.1.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz +0 -0
- {dissect_hypervisor-3.17.dev3/tests/data → dissect_hypervisor-3.18.dev1/tests/_data/disk/hdd}/split.hdd/split.hdd.2.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz +0 -0
- {dissect_hypervisor-3.17.dev3/tests/data → dissect_hypervisor-3.18.dev1/tests/_data/disk/hdd}/split.hdd/split.hdd.3.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz +0 -0
- {dissect_hypervisor-3.17.dev3/tests/data → dissect_hypervisor-3.18.dev1/tests/_data/disk/hdd}/split.hdd/split.hdd.4.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz +0 -0
- {dissect_hypervisor-3.17.dev3/tests/data → dissect_hypervisor-3.18.dev1/tests/_data/disk/hdd}/split.hdd/split.hdd.5.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz +0 -0
- {dissect_hypervisor-3.17.dev3/tests/data → dissect_hypervisor-3.18.dev1/tests/_data/disk/vhd}/dynamic.vhd.gz +0 -0
- {dissect_hypervisor-3.17.dev3/tests/data → dissect_hypervisor-3.18.dev1/tests/_data/disk/vhd}/fixed.vhd.gz +0 -0
- {dissect_hypervisor-3.17.dev3/tests/data → dissect_hypervisor-3.18.dev1/tests/_data/disk/vhdx}/differencing.avhdx.gz +0 -0
- {dissect_hypervisor-3.17.dev3/tests/data → dissect_hypervisor-3.18.dev1/tests/_data/disk/vhdx}/dynamic.vhdx.gz +0 -0
- {dissect_hypervisor-3.17.dev3/tests/data → dissect_hypervisor-3.18.dev1/tests/_data/disk/vhdx}/fixed.vhdx.gz +0 -0
- {dissect_hypervisor-3.17.dev3/tests/data → dissect_hypervisor-3.18.dev1/tests/_data/disk/vmdk}/sesparse.vmdk.gz +0 -0
- {dissect_hypervisor-3.17.dev3/tests/data → dissect_hypervisor-3.18.dev1/tests/_data/util/envelope}/encryption.info +0 -0
- {dissect_hypervisor-3.17.dev3/tests/data → dissect_hypervisor-3.18.dev1/tests/_data/util/envelope}/local.tgz.ve +0 -0
- {dissect_hypervisor-3.17.dev3/tests/data → dissect_hypervisor-3.18.dev1/tests/_data/util/vmtar}/test.vgz +0 -0
- {dissect_hypervisor-3.17.dev3/tests/docs → dissect_hypervisor-3.18.dev1/tests/_docs}/Makefile +0 -0
- {dissect_hypervisor-3.17.dev3/tests/docs → dissect_hypervisor-3.18.dev1/tests/_docs}/index.rst +0 -0
- {dissect_hypervisor-3.17.dev3/tests → dissect_hypervisor-3.18.dev1/tests/descriptor}/test_hyperv.py +0 -0
- {dissect_hypervisor-3.17.dev3/tests → dissect_hypervisor-3.18.dev1/tests/descriptor}/test_ovf.py +0 -0
- {dissect_hypervisor-3.17.dev3/tests → dissect_hypervisor-3.18.dev1/tests/descriptor}/test_pvs.py +0 -0
- {dissect_hypervisor-3.17.dev3/tests → dissect_hypervisor-3.18.dev1/tests/descriptor}/test_vbox.py +0 -0
- {dissect_hypervisor-3.17.dev3/tests → dissect_hypervisor-3.18.dev1/tests/descriptor}/test_vmx.py +0 -0
- {dissect_hypervisor-3.17.dev3/tests → dissect_hypervisor-3.18.dev1/tests/disk}/test_hdd.py +0 -0
- {dissect_hypervisor-3.17.dev3/tests → dissect_hypervisor-3.18.dev1/tests/disk}/test_vhd.py +0 -0
- {dissect_hypervisor-3.17.dev3/tests → dissect_hypervisor-3.18.dev1/tests/disk}/test_vhdx.py +0 -0
- {dissect_hypervisor-3.17.dev3/tests → dissect_hypervisor-3.18.dev1/tests/disk}/test_vmdk.py +0 -0
- {dissect_hypervisor-3.17.dev3/tests → dissect_hypervisor-3.18.dev1/tests/util}/test_envelope.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: dissect.hypervisor
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.18.dev1
|
|
4
4
|
Summary: A Dissect module implementing parsers for various hypervisor disk, backup and configuration files
|
|
5
5
|
Author-email: Dissect Team <dissect@fox-it.com>
|
|
6
6
|
License: Affero General Public License v3
|
|
@@ -31,6 +31,7 @@ Provides-Extra: dev
|
|
|
31
31
|
Requires-Dist: dissect.hypervisor[full]; extra == "dev"
|
|
32
32
|
Requires-Dist: dissect.cstruct<5.0.dev,>=4.0.dev; extra == "dev"
|
|
33
33
|
Requires-Dist: dissect.util<4.0.dev,>=3.0.dev; extra == "dev"
|
|
34
|
+
Dynamic: license-file
|
|
34
35
|
|
|
35
36
|
# dissect.hypervisor
|
|
36
37
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import tarfile
|
|
2
|
+
|
|
3
|
+
from dissect.hypervisor.util import vmtar
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def main() -> None:
|
|
7
|
+
# We just want to run the main function of the tarfile module, but with our VisorTarFile and is_tarfile functions
|
|
8
|
+
type(tarfile.main)(
|
|
9
|
+
tarfile.main.__code__,
|
|
10
|
+
tarfile.main.__globals__
|
|
11
|
+
| {
|
|
12
|
+
"TarFile": vmtar.VisorTarFile,
|
|
13
|
+
"is_tarfile": vmtar.is_tarfile,
|
|
14
|
+
"open": vmtar.open,
|
|
15
|
+
},
|
|
16
|
+
)()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
if __name__ == "__main__":
|
|
20
|
+
main()
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# References:
|
|
2
|
+
# - /bin/vmtar
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import struct
|
|
7
|
+
import tarfile
|
|
8
|
+
from io import BytesIO
|
|
9
|
+
from typing import BinaryIO, Final
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class VisorTarInfo(tarfile.TarInfo):
|
|
13
|
+
"""Implements TarInfo for use with Visor Tar files (vmtar).
|
|
14
|
+
|
|
15
|
+
The main difference is that file data is located at the end of the tar file, on
|
|
16
|
+
an offset specified in the header.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
is_visor: bool
|
|
20
|
+
offset_data: int | None
|
|
21
|
+
textPgs: int | None
|
|
22
|
+
fixUpPgs: int | None
|
|
23
|
+
|
|
24
|
+
@classmethod
|
|
25
|
+
def frombuf(cls, buf: bytes, encoding: str, errors: str) -> VisorTarInfo:
|
|
26
|
+
obj = super().frombuf(buf, encoding, errors)
|
|
27
|
+
|
|
28
|
+
obj.is_visor = buf[257:264] == b"visor "
|
|
29
|
+
if obj.is_visor:
|
|
30
|
+
obj.offset_data = struct.unpack("<I", buf[496:500])[0]
|
|
31
|
+
obj.textPgs = struct.unpack("<I", buf[504:508])[0]
|
|
32
|
+
obj.fixUpPgs = struct.unpack("<I", buf[508:512])[0]
|
|
33
|
+
else:
|
|
34
|
+
obj.offset_data = None
|
|
35
|
+
obj.textPgs = None
|
|
36
|
+
obj.fixUpPgs = None
|
|
37
|
+
|
|
38
|
+
return obj
|
|
39
|
+
|
|
40
|
+
def _proc_member(self, tarfile: tarfile.TarFile) -> VisorTarInfo | tarfile.TarInfo:
|
|
41
|
+
if self.is_visor and self.offset_data:
|
|
42
|
+
# Don't advance the offset with the filesize
|
|
43
|
+
tarfile.offset = tarfile.fileobj.tell()
|
|
44
|
+
|
|
45
|
+
# Patch the TarInfo object with saved global
|
|
46
|
+
# header information.
|
|
47
|
+
self._apply_pax_info(tarfile.pax_headers, tarfile.encoding, tarfile.errors)
|
|
48
|
+
|
|
49
|
+
return self
|
|
50
|
+
|
|
51
|
+
return super()._proc_member(tarfile)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class VisorTarFile(tarfile.TarFile):
|
|
55
|
+
def __init__(self, *args, **kwargs) -> None:
|
|
56
|
+
super().__init__(*args, **kwargs, tarinfo=VisorTarInfo)
|
|
57
|
+
|
|
58
|
+
@classmethod
|
|
59
|
+
def visoropen(cls, name: str, mode: str = "r", fileobj: BinaryIO | None = None, **kwargs) -> VisorTarFile:
|
|
60
|
+
"""Open a visor tar file for reading. Supports gzip and lzma compression."""
|
|
61
|
+
if mode not in ("r",):
|
|
62
|
+
raise tarfile.TarError("visor currently only supports read mode")
|
|
63
|
+
|
|
64
|
+
try:
|
|
65
|
+
from gzip import GzipFile
|
|
66
|
+
except ImportError:
|
|
67
|
+
raise tarfile.CompressionError("gzip module is not available") from None
|
|
68
|
+
|
|
69
|
+
try:
|
|
70
|
+
from lzma import LZMAError, LZMAFile
|
|
71
|
+
except ImportError:
|
|
72
|
+
raise tarfile.CompressionError("lzma module is not available") from None
|
|
73
|
+
|
|
74
|
+
compressed = False
|
|
75
|
+
|
|
76
|
+
try:
|
|
77
|
+
t = cls.taropen(name, mode, fileobj, **kwargs)
|
|
78
|
+
except Exception:
|
|
79
|
+
try:
|
|
80
|
+
fileobj = GzipFile(name, mode + "b", fileobj=fileobj)
|
|
81
|
+
except OSError as e:
|
|
82
|
+
if fileobj is not None and mode == "r":
|
|
83
|
+
raise tarfile.ReadError("not a visor file") from e
|
|
84
|
+
raise
|
|
85
|
+
|
|
86
|
+
try:
|
|
87
|
+
t = cls.taropen(name, mode, fileobj, **kwargs)
|
|
88
|
+
except Exception:
|
|
89
|
+
fileobj.seek(0)
|
|
90
|
+
fileobj = LZMAFile(fileobj or name, mode) # noqa: SIM115
|
|
91
|
+
|
|
92
|
+
try:
|
|
93
|
+
t = cls.taropen(name, mode, fileobj, **kwargs)
|
|
94
|
+
except (LZMAError, EOFError, OSError) as e:
|
|
95
|
+
fileobj.close()
|
|
96
|
+
if mode == "r":
|
|
97
|
+
raise tarfile.ReadError("not a visor file") from e
|
|
98
|
+
raise
|
|
99
|
+
except:
|
|
100
|
+
fileobj.close()
|
|
101
|
+
raise
|
|
102
|
+
|
|
103
|
+
compressed = True
|
|
104
|
+
|
|
105
|
+
# If we get here, we have a valid visor tar file
|
|
106
|
+
if fileobj is not None and compressed:
|
|
107
|
+
# Just read the entire file into memory, it's probably small
|
|
108
|
+
fileobj.seek(0)
|
|
109
|
+
fileobj = BytesIO(fileobj.read())
|
|
110
|
+
|
|
111
|
+
t = cls.taropen(name, mode, fileobj, **kwargs)
|
|
112
|
+
|
|
113
|
+
t._extfileobj = False
|
|
114
|
+
return t
|
|
115
|
+
|
|
116
|
+
# Only allow opening visor tar files
|
|
117
|
+
OPEN_METH: Final[dict[str, str]] = {"visor": "visoropen"}
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
open = VisorTarFile.open
|
|
121
|
+
|
|
122
|
+
is_tarfile = type(tarfile.is_tarfile)(tarfile.is_tarfile.__code__, tarfile.is_tarfile.__globals__ | {"open": open})
|
{dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect.hypervisor.egg-info/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: dissect.hypervisor
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.18.dev1
|
|
4
4
|
Summary: A Dissect module implementing parsers for various hypervisor disk, backup and configuration files
|
|
5
5
|
Author-email: Dissect Team <dissect@fox-it.com>
|
|
6
6
|
License: Affero General Public License v3
|
|
@@ -31,6 +31,7 @@ Provides-Extra: dev
|
|
|
31
31
|
Requires-Dist: dissect.hypervisor[full]; extra == "dev"
|
|
32
32
|
Requires-Dist: dissect.cstruct<5.0.dev,>=4.0.dev; extra == "dev"
|
|
33
33
|
Requires-Dist: dissect.util<4.0.dev,>=3.0.dev; extra == "dev"
|
|
34
|
+
Dynamic: license-file
|
|
34
35
|
|
|
35
36
|
# dissect.hypervisor
|
|
36
37
|
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
.git-blame-ignore-revs
|
|
2
|
+
COPYRIGHT
|
|
3
|
+
LICENSE
|
|
4
|
+
MANIFEST.in
|
|
5
|
+
README.md
|
|
6
|
+
pyproject.toml
|
|
7
|
+
tox.ini
|
|
8
|
+
dissect.hypervisor.egg-info/PKG-INFO
|
|
9
|
+
dissect.hypervisor.egg-info/SOURCES.txt
|
|
10
|
+
dissect.hypervisor.egg-info/dependency_links.txt
|
|
11
|
+
dissect.hypervisor.egg-info/entry_points.txt
|
|
12
|
+
dissect.hypervisor.egg-info/requires.txt
|
|
13
|
+
dissect.hypervisor.egg-info/top_level.txt
|
|
14
|
+
dissect/hypervisor/__init__.py
|
|
15
|
+
dissect/hypervisor/exceptions.py
|
|
16
|
+
dissect/hypervisor/descriptor/__init__.py
|
|
17
|
+
dissect/hypervisor/descriptor/c_hyperv.py
|
|
18
|
+
dissect/hypervisor/descriptor/hyperv.py
|
|
19
|
+
dissect/hypervisor/descriptor/ovf.py
|
|
20
|
+
dissect/hypervisor/descriptor/pvs.py
|
|
21
|
+
dissect/hypervisor/descriptor/vbox.py
|
|
22
|
+
dissect/hypervisor/descriptor/vmx.py
|
|
23
|
+
dissect/hypervisor/disk/__init__.py
|
|
24
|
+
dissect/hypervisor/disk/c_hdd.py
|
|
25
|
+
dissect/hypervisor/disk/c_qcow2.py
|
|
26
|
+
dissect/hypervisor/disk/c_vdi.py
|
|
27
|
+
dissect/hypervisor/disk/c_vhd.py
|
|
28
|
+
dissect/hypervisor/disk/c_vhdx.py
|
|
29
|
+
dissect/hypervisor/disk/c_vmdk.py
|
|
30
|
+
dissect/hypervisor/disk/hdd.py
|
|
31
|
+
dissect/hypervisor/disk/qcow2.py
|
|
32
|
+
dissect/hypervisor/disk/vdi.py
|
|
33
|
+
dissect/hypervisor/disk/vhd.py
|
|
34
|
+
dissect/hypervisor/disk/vhdx.py
|
|
35
|
+
dissect/hypervisor/disk/vmdk.py
|
|
36
|
+
dissect/hypervisor/tools/__init__.py
|
|
37
|
+
dissect/hypervisor/tools/envelope.py
|
|
38
|
+
dissect/hypervisor/tools/vmtar.py
|
|
39
|
+
dissect/hypervisor/util/__init__.py
|
|
40
|
+
dissect/hypervisor/util/envelope.py
|
|
41
|
+
dissect/hypervisor/util/vmtar.py
|
|
42
|
+
tests/__init__.py
|
|
43
|
+
tests/conftest.py
|
|
44
|
+
tests/_data/descriptor/hyperv/test.VMRS
|
|
45
|
+
tests/_data/descriptor/hyperv/test.vmcx
|
|
46
|
+
tests/_data/descriptor/vmx/encrypted.vmx
|
|
47
|
+
tests/_data/disk/hdd/expanding.hdd/DiskDescriptor.xml
|
|
48
|
+
tests/_data/disk/hdd/expanding.hdd/expanding.hdd
|
|
49
|
+
tests/_data/disk/hdd/expanding.hdd/expanding.hdd.0.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz
|
|
50
|
+
tests/_data/disk/hdd/plain.hdd/DiskDescriptor.xml
|
|
51
|
+
tests/_data/disk/hdd/plain.hdd/plain.hdd
|
|
52
|
+
tests/_data/disk/hdd/plain.hdd/plain.hdd.0.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz
|
|
53
|
+
tests/_data/disk/hdd/split.hdd/DiskDescriptor.xml
|
|
54
|
+
tests/_data/disk/hdd/split.hdd/split.hdd
|
|
55
|
+
tests/_data/disk/hdd/split.hdd/split.hdd.0.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz
|
|
56
|
+
tests/_data/disk/hdd/split.hdd/split.hdd.1.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz
|
|
57
|
+
tests/_data/disk/hdd/split.hdd/split.hdd.2.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz
|
|
58
|
+
tests/_data/disk/hdd/split.hdd/split.hdd.3.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz
|
|
59
|
+
tests/_data/disk/hdd/split.hdd/split.hdd.4.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz
|
|
60
|
+
tests/_data/disk/hdd/split.hdd/split.hdd.5.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz
|
|
61
|
+
tests/_data/disk/vhd/dynamic.vhd.gz
|
|
62
|
+
tests/_data/disk/vhd/fixed.vhd.gz
|
|
63
|
+
tests/_data/disk/vhdx/differencing.avhdx.gz
|
|
64
|
+
tests/_data/disk/vhdx/dynamic.vhdx.gz
|
|
65
|
+
tests/_data/disk/vhdx/fixed.vhdx.gz
|
|
66
|
+
tests/_data/disk/vmdk/sesparse.vmdk.gz
|
|
67
|
+
tests/_data/util/envelope/encryption.info
|
|
68
|
+
tests/_data/util/envelope/local.tgz.ve
|
|
69
|
+
tests/_data/util/vmtar/test.vgz
|
|
70
|
+
tests/_docs/Makefile
|
|
71
|
+
tests/_docs/conf.py
|
|
72
|
+
tests/_docs/index.rst
|
|
73
|
+
tests/descriptor/__init__.py
|
|
74
|
+
tests/descriptor/test_hyperv.py
|
|
75
|
+
tests/descriptor/test_ovf.py
|
|
76
|
+
tests/descriptor/test_pvs.py
|
|
77
|
+
tests/descriptor/test_vbox.py
|
|
78
|
+
tests/descriptor/test_vmx.py
|
|
79
|
+
tests/disk/__init__.py
|
|
80
|
+
tests/disk/test_hdd.py
|
|
81
|
+
tests/disk/test_vhd.py
|
|
82
|
+
tests/disk/test_vhdx.py
|
|
83
|
+
tests/disk/test_vmdk.py
|
|
84
|
+
tests/util/__init__.py
|
|
85
|
+
tests/util/test_envelope.py
|
|
86
|
+
tests/util/test_vmtar.py
|
|
@@ -48,10 +48,11 @@ dev = [
|
|
|
48
48
|
|
|
49
49
|
[project.scripts]
|
|
50
50
|
envelope-decrypt = "dissect.hypervisor.tools.envelope:main"
|
|
51
|
+
vmtar = "dissect.hypervisor.tools.vmtar:main"
|
|
51
52
|
|
|
52
53
|
[tool.ruff]
|
|
53
54
|
line-length = 120
|
|
54
|
-
required-version = ">=0.
|
|
55
|
+
required-version = ">=0.11.0"
|
|
55
56
|
|
|
56
57
|
[tool.ruff.format]
|
|
57
58
|
docstring-code-format = true
|
|
@@ -94,7 +95,7 @@ select = [
|
|
|
94
95
|
ignore = ["E203", "B904", "UP024", "ANN002", "ANN003", "ANN204", "ANN401", "SIM105", "TRY003"]
|
|
95
96
|
|
|
96
97
|
[tool.ruff.lint.per-file-ignores]
|
|
97
|
-
"tests/
|
|
98
|
+
"tests/_docs/**" = ["INP001"]
|
|
98
99
|
|
|
99
100
|
[tool.ruff.lint.isort]
|
|
100
101
|
known-first-party = ["dissect.hypervisor"]
|
|
@@ -26,74 +26,74 @@ def open_file_gz(name: str, mode: str = "rb") -> Iterator[BinaryIO]:
|
|
|
26
26
|
|
|
27
27
|
@pytest.fixture
|
|
28
28
|
def encrypted_vmx() -> Iterator[BinaryIO]:
|
|
29
|
-
yield from open_file("
|
|
29
|
+
yield from open_file("_data/descriptor/vmx/encrypted.vmx")
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
@pytest.fixture
|
|
33
33
|
def vmcx() -> Iterator[BinaryIO]:
|
|
34
|
-
yield from open_file("
|
|
34
|
+
yield from open_file("_data/descriptor/hyperv/test.vmcx")
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
@pytest.fixture
|
|
38
38
|
def vmrs() -> Iterator[BinaryIO]:
|
|
39
|
-
yield from open_file("
|
|
39
|
+
yield from open_file("_data/descriptor/hyperv/test.VMRS")
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
@pytest.fixture
|
|
43
43
|
def fixed_vhd() -> Iterator[BinaryIO]:
|
|
44
|
-
yield from open_file_gz("
|
|
44
|
+
yield from open_file_gz("_data/disk/vhd/fixed.vhd.gz")
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
@pytest.fixture
|
|
48
48
|
def dynamic_vhd() -> Iterator[BinaryIO]:
|
|
49
|
-
yield from open_file_gz("
|
|
49
|
+
yield from open_file_gz("_data/disk/vhd/dynamic.vhd.gz")
|
|
50
50
|
|
|
51
51
|
|
|
52
52
|
@pytest.fixture
|
|
53
53
|
def fixed_vhdx() -> Iterator[BinaryIO]:
|
|
54
|
-
yield from open_file_gz("
|
|
54
|
+
yield from open_file_gz("_data/disk/vhdx/fixed.vhdx.gz")
|
|
55
55
|
|
|
56
56
|
|
|
57
57
|
@pytest.fixture
|
|
58
58
|
def dynamic_vhdx() -> Iterator[BinaryIO]:
|
|
59
|
-
yield from open_file_gz("
|
|
59
|
+
yield from open_file_gz("_data/disk/vhdx/dynamic.vhdx.gz")
|
|
60
60
|
|
|
61
61
|
|
|
62
62
|
@pytest.fixture
|
|
63
63
|
def differencing_vhdx() -> Iterator[BinaryIO]:
|
|
64
|
-
yield from open_file_gz("
|
|
64
|
+
yield from open_file_gz("_data/disk/vhdx/differencing.avhdx.gz")
|
|
65
65
|
|
|
66
66
|
|
|
67
67
|
@pytest.fixture
|
|
68
68
|
def sesparse_vmdk() -> Iterator[BinaryIO]:
|
|
69
|
-
yield from open_file_gz("
|
|
69
|
+
yield from open_file_gz("_data/disk/vmdk/sesparse.vmdk.gz")
|
|
70
70
|
|
|
71
71
|
|
|
72
72
|
@pytest.fixture
|
|
73
73
|
def plain_hdd() -> Iterator[str]:
|
|
74
|
-
return absolute_path("
|
|
74
|
+
return absolute_path("_data/disk/hdd/plain.hdd")
|
|
75
75
|
|
|
76
76
|
|
|
77
77
|
@pytest.fixture
|
|
78
78
|
def expanding_hdd() -> Iterator[str]:
|
|
79
|
-
return absolute_path("
|
|
79
|
+
return absolute_path("_data/disk/hdd/expanding.hdd")
|
|
80
80
|
|
|
81
81
|
|
|
82
82
|
@pytest.fixture
|
|
83
83
|
def split_hdd() -> Iterator[str]:
|
|
84
|
-
return absolute_path("
|
|
84
|
+
return absolute_path("_data/disk/hdd/split.hdd")
|
|
85
85
|
|
|
86
86
|
|
|
87
87
|
@pytest.fixture
|
|
88
88
|
def envelope() -> Iterator[BinaryIO]:
|
|
89
|
-
yield from open_file("
|
|
89
|
+
yield from open_file("_data/util/envelope/local.tgz.ve")
|
|
90
90
|
|
|
91
91
|
|
|
92
92
|
@pytest.fixture
|
|
93
93
|
def keystore() -> Iterator[TextIO]:
|
|
94
|
-
yield from open_file("
|
|
94
|
+
yield from open_file("_data/util/envelope/encryption.info", "r")
|
|
95
95
|
|
|
96
96
|
|
|
97
97
|
@pytest.fixture
|
|
98
98
|
def vgz() -> Iterator[BinaryIO]:
|
|
99
|
-
yield from open_file("
|
|
99
|
+
yield from open_file("_data/util/vmtar/test.vgz")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, BinaryIO
|
|
4
|
+
|
|
5
|
+
from dissect.hypervisor.tools.vmtar import main as vmtar_main
|
|
6
|
+
from dissect.hypervisor.util import vmtar
|
|
7
|
+
from tests.conftest import absolute_path
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
import pytest
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def test_vmtar(vgz: BinaryIO) -> None:
|
|
16
|
+
tar = vmtar.open(fileobj=vgz)
|
|
17
|
+
|
|
18
|
+
members = {member.name: member for member in tar.getmembers()}
|
|
19
|
+
|
|
20
|
+
# The test file has no textPgs/fixUpPgs
|
|
21
|
+
assert all(member.is_visor for member in members.values())
|
|
22
|
+
assert set(members.keys()) == {
|
|
23
|
+
"test/file1",
|
|
24
|
+
"test/file2",
|
|
25
|
+
"test/file3",
|
|
26
|
+
"test/subdir",
|
|
27
|
+
"test/subdir/file4",
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
assert tar.extractfile(members["test/file1"]).read() == (b"a" * 512) + b"\n"
|
|
31
|
+
assert tar.extractfile(members["test/file2"]).read() == (b"b" * 1024) + b"\n"
|
|
32
|
+
assert tar.extractfile(members["test/file3"]).read() == (b"c" * 2048) + b"\n"
|
|
33
|
+
assert tar.extractfile(members["test/subdir/file4"]).read() == (b"f" * 2048) + b"\n"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def test_vmtar_tool(tmp_path: Path, monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture) -> None:
|
|
37
|
+
vgz_path = absolute_path("_data/util/vmtar/test.vgz")
|
|
38
|
+
|
|
39
|
+
with monkeypatch.context() as m:
|
|
40
|
+
m.setattr("sys.argv", ["vmtar", "-l", str(vgz_path)])
|
|
41
|
+
|
|
42
|
+
vmtar_main()
|
|
43
|
+
|
|
44
|
+
out, _ = capsys.readouterr()
|
|
45
|
+
assert out.splitlines() == [
|
|
46
|
+
"test/ ",
|
|
47
|
+
"test/file3 ",
|
|
48
|
+
"test/file2 ",
|
|
49
|
+
"test/subdir/ ",
|
|
50
|
+
"test/subdir/file4 ",
|
|
51
|
+
"test/file1 ",
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
with monkeypatch.context() as m:
|
|
55
|
+
m.setattr("sys.argv", ["vmtar", "-t", str(vgz_path)])
|
|
56
|
+
|
|
57
|
+
vmtar_main()
|
|
58
|
+
|
|
59
|
+
_, err = capsys.readouterr()
|
|
60
|
+
assert err.startswith("[<VisorTarInfo 'test'")
|
|
61
|
+
|
|
62
|
+
with monkeypatch.context() as m:
|
|
63
|
+
m.setattr("sys.argv", ["vmtar", "-e", str(vgz_path), str(tmp_path)])
|
|
64
|
+
|
|
65
|
+
vmtar_main()
|
|
66
|
+
|
|
67
|
+
for path in (
|
|
68
|
+
"test",
|
|
69
|
+
"test/file1",
|
|
70
|
+
"test/file2",
|
|
71
|
+
"test/file3",
|
|
72
|
+
"test/subdir",
|
|
73
|
+
"test/subdir/file4",
|
|
74
|
+
):
|
|
75
|
+
assert tmp_path.joinpath(path).exists()
|
|
76
|
+
|
|
77
|
+
assert tmp_path.joinpath("test/file1").read_text() == (b"a" * 512).decode() + "\n"
|
|
78
|
+
assert tmp_path.joinpath("test/file2").read_text() == (b"b" * 1024).decode() + "\n"
|
|
79
|
+
assert tmp_path.joinpath("test/file3").read_text() == (b"c" * 2048).decode() + "\n"
|
|
80
|
+
assert tmp_path.joinpath("test/subdir/file4").read_text() == (b"f" * 2048).decode() + "\n"
|
|
@@ -32,16 +32,18 @@ commands =
|
|
|
32
32
|
[testenv:fix]
|
|
33
33
|
package = skip
|
|
34
34
|
deps =
|
|
35
|
-
ruff==0.
|
|
35
|
+
ruff==0.11.10
|
|
36
36
|
commands =
|
|
37
37
|
ruff format dissect tests
|
|
38
|
+
ruff check --fix dissect tests
|
|
38
39
|
|
|
39
40
|
[testenv:lint]
|
|
40
41
|
package = skip
|
|
41
42
|
deps =
|
|
42
|
-
ruff==0.
|
|
43
|
+
ruff==0.11.10
|
|
43
44
|
vermin
|
|
44
45
|
commands =
|
|
46
|
+
ruff format --check dissect tests
|
|
45
47
|
ruff check dissect tests
|
|
46
48
|
vermin -t=3.9- --no-tips --lint dissect tests
|
|
47
49
|
|
|
@@ -55,12 +57,12 @@ deps =
|
|
|
55
57
|
sphinx-design
|
|
56
58
|
furo
|
|
57
59
|
commands =
|
|
58
|
-
make -C tests/
|
|
59
|
-
make -C tests/
|
|
60
|
+
make -C tests/_docs clean
|
|
61
|
+
make -C tests/_docs html
|
|
60
62
|
|
|
61
63
|
[testenv:docs-linkcheck]
|
|
62
64
|
allowlist_externals = make
|
|
63
65
|
deps = {[testenv:docs-build]deps}
|
|
64
66
|
commands =
|
|
65
|
-
make -C tests/
|
|
66
|
-
make -C tests/
|
|
67
|
+
make -C tests/_docs clean
|
|
68
|
+
make -C tests/_docs linkcheck
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
# References:
|
|
2
|
-
# - /bin/vmtar
|
|
3
|
-
|
|
4
|
-
from __future__ import annotations
|
|
5
|
-
|
|
6
|
-
import struct
|
|
7
|
-
import tarfile
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class VisorTarInfo(tarfile.TarInfo):
|
|
11
|
-
"""Implements TarInfo for use with Visor Tar files (vmtar).
|
|
12
|
-
|
|
13
|
-
The main difference is that file data is located at the end of the tar file, on
|
|
14
|
-
an offset specified in the header.
|
|
15
|
-
"""
|
|
16
|
-
|
|
17
|
-
is_visor: bool
|
|
18
|
-
offset_data: int | None
|
|
19
|
-
textPgs: int | None
|
|
20
|
-
fixUpPgs: int | None
|
|
21
|
-
|
|
22
|
-
@classmethod
|
|
23
|
-
def frombuf(cls, buf: bytes, encoding: str, errors: str) -> VisorTarInfo:
|
|
24
|
-
obj = super().frombuf(buf, encoding, errors)
|
|
25
|
-
|
|
26
|
-
obj.is_visor = buf[257:264] == b"visor "
|
|
27
|
-
if obj.is_visor:
|
|
28
|
-
obj.offset_data = struct.unpack("<I", buf[496:500])[0]
|
|
29
|
-
obj.textPgs = struct.unpack("<I", buf[504:508])[0]
|
|
30
|
-
obj.fixUpPgs = struct.unpack("<I", buf[508:512])[0]
|
|
31
|
-
else:
|
|
32
|
-
obj.offset_data = None
|
|
33
|
-
obj.textPgs = None
|
|
34
|
-
obj.fixUpPgs = None
|
|
35
|
-
|
|
36
|
-
return obj
|
|
37
|
-
|
|
38
|
-
def _proc_member(self, tarfile: tarfile.TarFile) -> VisorTarInfo | tarfile.TarInfo:
|
|
39
|
-
if self.is_visor and self.offset_data:
|
|
40
|
-
# Don't advance the offset with the filesize
|
|
41
|
-
tarfile.offset = tarfile.fileobj.tell()
|
|
42
|
-
|
|
43
|
-
# Patch the TarInfo object with saved global
|
|
44
|
-
# header information.
|
|
45
|
-
self._apply_pax_info(tarfile.pax_headers, tarfile.encoding, tarfile.errors)
|
|
46
|
-
|
|
47
|
-
return self
|
|
48
|
-
|
|
49
|
-
return super()._proc_member(tarfile)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
def VisorTarFile(*args, **kwargs) -> tarfile.TarFile:
|
|
53
|
-
return tarfile.TarFile(*args, **kwargs, tarinfo=VisorTarInfo)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
def open(*args, **kwargs) -> tarfile.TarFile:
|
|
57
|
-
return tarfile.open(*args, **kwargs, tarinfo=VisorTarInfo)
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
.git-blame-ignore-revs
|
|
2
|
-
COPYRIGHT
|
|
3
|
-
LICENSE
|
|
4
|
-
MANIFEST.in
|
|
5
|
-
README.md
|
|
6
|
-
pyproject.toml
|
|
7
|
-
tox.ini
|
|
8
|
-
dissect.hypervisor.egg-info/PKG-INFO
|
|
9
|
-
dissect.hypervisor.egg-info/SOURCES.txt
|
|
10
|
-
dissect.hypervisor.egg-info/dependency_links.txt
|
|
11
|
-
dissect.hypervisor.egg-info/entry_points.txt
|
|
12
|
-
dissect.hypervisor.egg-info/requires.txt
|
|
13
|
-
dissect.hypervisor.egg-info/top_level.txt
|
|
14
|
-
dissect/hypervisor/__init__.py
|
|
15
|
-
dissect/hypervisor/exceptions.py
|
|
16
|
-
dissect/hypervisor/descriptor/__init__.py
|
|
17
|
-
dissect/hypervisor/descriptor/c_hyperv.py
|
|
18
|
-
dissect/hypervisor/descriptor/hyperv.py
|
|
19
|
-
dissect/hypervisor/descriptor/ovf.py
|
|
20
|
-
dissect/hypervisor/descriptor/pvs.py
|
|
21
|
-
dissect/hypervisor/descriptor/vbox.py
|
|
22
|
-
dissect/hypervisor/descriptor/vmx.py
|
|
23
|
-
dissect/hypervisor/disk/__init__.py
|
|
24
|
-
dissect/hypervisor/disk/c_hdd.py
|
|
25
|
-
dissect/hypervisor/disk/c_qcow2.py
|
|
26
|
-
dissect/hypervisor/disk/c_vdi.py
|
|
27
|
-
dissect/hypervisor/disk/c_vhd.py
|
|
28
|
-
dissect/hypervisor/disk/c_vhdx.py
|
|
29
|
-
dissect/hypervisor/disk/c_vmdk.py
|
|
30
|
-
dissect/hypervisor/disk/hdd.py
|
|
31
|
-
dissect/hypervisor/disk/qcow2.py
|
|
32
|
-
dissect/hypervisor/disk/vdi.py
|
|
33
|
-
dissect/hypervisor/disk/vhd.py
|
|
34
|
-
dissect/hypervisor/disk/vhdx.py
|
|
35
|
-
dissect/hypervisor/disk/vmdk.py
|
|
36
|
-
dissect/hypervisor/tools/__init__.py
|
|
37
|
-
dissect/hypervisor/tools/envelope.py
|
|
38
|
-
dissect/hypervisor/util/__init__.py
|
|
39
|
-
dissect/hypervisor/util/envelope.py
|
|
40
|
-
dissect/hypervisor/util/vmtar.py
|
|
41
|
-
tests/__init__.py
|
|
42
|
-
tests/conftest.py
|
|
43
|
-
tests/test_envelope.py
|
|
44
|
-
tests/test_hdd.py
|
|
45
|
-
tests/test_hyperv.py
|
|
46
|
-
tests/test_ovf.py
|
|
47
|
-
tests/test_pvs.py
|
|
48
|
-
tests/test_vbox.py
|
|
49
|
-
tests/test_vhd.py
|
|
50
|
-
tests/test_vhdx.py
|
|
51
|
-
tests/test_vmdk.py
|
|
52
|
-
tests/test_vmtar.py
|
|
53
|
-
tests/test_vmx.py
|
|
54
|
-
tests/data/differencing.avhdx.gz
|
|
55
|
-
tests/data/dynamic.vhd.gz
|
|
56
|
-
tests/data/dynamic.vhdx.gz
|
|
57
|
-
tests/data/encrypted.vmx
|
|
58
|
-
tests/data/encryption.info
|
|
59
|
-
tests/data/fixed.vhd.gz
|
|
60
|
-
tests/data/fixed.vhdx.gz
|
|
61
|
-
tests/data/local.tgz.ve
|
|
62
|
-
tests/data/sesparse.vmdk.gz
|
|
63
|
-
tests/data/test.VMRS
|
|
64
|
-
tests/data/test.vgz
|
|
65
|
-
tests/data/test.vmcx
|
|
66
|
-
tests/data/expanding.hdd/DiskDescriptor.xml
|
|
67
|
-
tests/data/expanding.hdd/expanding.hdd
|
|
68
|
-
tests/data/expanding.hdd/expanding.hdd.0.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz
|
|
69
|
-
tests/data/plain.hdd/DiskDescriptor.xml
|
|
70
|
-
tests/data/plain.hdd/plain.hdd
|
|
71
|
-
tests/data/plain.hdd/plain.hdd.0.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz
|
|
72
|
-
tests/data/split.hdd/DiskDescriptor.xml
|
|
73
|
-
tests/data/split.hdd/split.hdd
|
|
74
|
-
tests/data/split.hdd/split.hdd.0.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz
|
|
75
|
-
tests/data/split.hdd/split.hdd.1.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz
|
|
76
|
-
tests/data/split.hdd/split.hdd.2.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz
|
|
77
|
-
tests/data/split.hdd/split.hdd.3.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz
|
|
78
|
-
tests/data/split.hdd/split.hdd.4.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz
|
|
79
|
-
tests/data/split.hdd/split.hdd.5.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz
|
|
80
|
-
tests/docs/Makefile
|
|
81
|
-
tests/docs/conf.py
|
|
82
|
-
tests/docs/index.rst
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from typing import BinaryIO
|
|
4
|
-
|
|
5
|
-
from dissect.hypervisor.util import vmtar
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def test_vmtar(vgz: BinaryIO) -> None:
|
|
9
|
-
tar = vmtar.open(fileobj=vgz)
|
|
10
|
-
|
|
11
|
-
members = {member.name: member for member in tar.getmembers()}
|
|
12
|
-
|
|
13
|
-
# The test file has no textPgs/fixUpPgs
|
|
14
|
-
assert all(member.is_visor for member in members.values())
|
|
15
|
-
assert set(members.keys()) == {
|
|
16
|
-
"test",
|
|
17
|
-
"test/file1",
|
|
18
|
-
"test/file2",
|
|
19
|
-
"test/file3",
|
|
20
|
-
"test/subdir",
|
|
21
|
-
"test/subdir/file4",
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
assert tar.extractfile(members["test/file1"]).read() == (b"a" * 512) + b"\n"
|
|
25
|
-
assert tar.extractfile(members["test/file2"]).read() == (b"b" * 1024) + b"\n"
|
|
26
|
-
assert tar.extractfile(members["test/file3"]).read() == (b"c" * 2048) + b"\n"
|
|
27
|
-
assert tar.extractfile(members["test/subdir/file4"]).read() == (b"f" * 2048) + b"\n"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/descriptor/ovf.py
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/descriptor/pvs.py
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/descriptor/vbox.py
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/descriptor/vmx.py
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/disk/__init__.py
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/disk/c_hdd.py
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/disk/c_qcow2.py
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/disk/c_vdi.py
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/disk/c_vhd.py
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/disk/c_vhdx.py
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/disk/c_vmdk.py
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/disk/hdd.py
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/disk/qcow2.py
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/disk/vdi.py
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/disk/vhd.py
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/disk/vhdx.py
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/disk/vmdk.py
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/exceptions.py
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/tools/__init__.py
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/tools/envelope.py
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/util/__init__.py
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3 → dissect_hypervisor-3.18.dev1}/dissect/hypervisor/util/envelope.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dissect_hypervisor-3.17.dev3/tests/docs → dissect_hypervisor-3.18.dev1/tests/_docs}/Makefile
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3/tests/docs → dissect_hypervisor-3.18.dev1/tests/_docs}/index.rst
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3/tests → dissect_hypervisor-3.18.dev1/tests/descriptor}/test_hyperv.py
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3/tests → dissect_hypervisor-3.18.dev1/tests/descriptor}/test_ovf.py
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3/tests → dissect_hypervisor-3.18.dev1/tests/descriptor}/test_pvs.py
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3/tests → dissect_hypervisor-3.18.dev1/tests/descriptor}/test_vbox.py
RENAMED
|
File without changes
|
{dissect_hypervisor-3.17.dev3/tests → dissect_hypervisor-3.18.dev1/tests/descriptor}/test_vmx.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dissect_hypervisor-3.17.dev3/tests → dissect_hypervisor-3.18.dev1/tests/util}/test_envelope.py
RENAMED
|
File without changes
|