dissect.target 3.20.dev39__py3-none-any.whl → 3.20.dev40__py3-none-any.whl
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/target/helpers/record.py +21 -0
- dissect/target/helpers/regutil.py +10 -1
- dissect/target/plugins/os/unix/applications.py +78 -0
- dissect/target/plugins/os/unix/linux/debian/snap.py +79 -0
- dissect/target/plugins/os/unix/packagemanager.py +1 -1
- dissect/target/plugins/os/windows/regf/applications.py +62 -0
- {dissect.target-3.20.dev39.dist-info → dissect.target-3.20.dev40.dist-info}/METADATA +1 -1
- {dissect.target-3.20.dev39.dist-info → dissect.target-3.20.dev40.dist-info}/RECORD +13 -10
- {dissect.target-3.20.dev39.dist-info → dissect.target-3.20.dev40.dist-info}/COPYRIGHT +0 -0
- {dissect.target-3.20.dev39.dist-info → dissect.target-3.20.dev40.dist-info}/LICENSE +0 -0
- {dissect.target-3.20.dev39.dist-info → dissect.target-3.20.dev40.dist-info}/WHEEL +0 -0
- {dissect.target-3.20.dev39.dist-info → dissect.target-3.20.dev40.dist-info}/entry_points.txt +0 -0
- {dissect.target-3.20.dev39.dist-info → dissect.target-3.20.dev40.dist-info}/top_level.txt +0 -0
dissect/target/helpers/record.py
CHANGED
@@ -185,3 +185,24 @@ MacInterfaceRecord = TargetRecordDescriptor(
|
|
185
185
|
("boolean", "dhcp"),
|
186
186
|
],
|
187
187
|
)
|
188
|
+
|
189
|
+
|
190
|
+
COMMON_APPLICATION_FIELDS = [
|
191
|
+
("datetime", "ts_modified"),
|
192
|
+
("datetime", "ts_installed"),
|
193
|
+
("string", "name"),
|
194
|
+
("string", "version"),
|
195
|
+
("string", "author"),
|
196
|
+
("string", "type"),
|
197
|
+
("path", "path"),
|
198
|
+
]
|
199
|
+
|
200
|
+
UnixApplicationRecord = TargetRecordDescriptor(
|
201
|
+
"unix/application",
|
202
|
+
COMMON_APPLICATION_FIELDS,
|
203
|
+
)
|
204
|
+
|
205
|
+
WindowsApplicationRecord = TargetRecordDescriptor(
|
206
|
+
"windows/application",
|
207
|
+
COMMON_APPLICATION_FIELDS,
|
208
|
+
)
|
@@ -310,6 +310,7 @@ class VirtualKey(RegistryKey):
|
|
310
310
|
self._class_name = class_name
|
311
311
|
self._values: dict[str, RegistryValue] = {}
|
312
312
|
self._subkeys: dict[str, RegistryKey] = {}
|
313
|
+
self._timestamp: datetime = None
|
313
314
|
self.top: RegistryKey = None
|
314
315
|
super().__init__(hive=hive)
|
315
316
|
|
@@ -339,11 +340,19 @@ class VirtualKey(RegistryKey):
|
|
339
340
|
return self._path
|
340
341
|
|
341
342
|
@property
|
342
|
-
def timestamp(self) -> datetime:
|
343
|
+
def timestamp(self) -> datetime | None:
|
343
344
|
if self.top:
|
344
345
|
return self.top.timestamp
|
346
|
+
|
347
|
+
if self._timestamp:
|
348
|
+
return self._timestamp
|
349
|
+
|
345
350
|
return None
|
346
351
|
|
352
|
+
@timestamp.setter
|
353
|
+
def timestamp(self, ts: datetime) -> None:
|
354
|
+
self._timestamp = ts
|
355
|
+
|
347
356
|
def subkey(self, subkey: str) -> RegistryKey:
|
348
357
|
try:
|
349
358
|
return self._subkeys[subkey.lower()]
|
@@ -0,0 +1,78 @@
|
|
1
|
+
from typing import Iterator
|
2
|
+
|
3
|
+
from dissect.target.exceptions import UnsupportedPluginError
|
4
|
+
from dissect.target.helpers import configutil
|
5
|
+
from dissect.target.helpers.fsutil import TargetPath
|
6
|
+
from dissect.target.helpers.record import UnixApplicationRecord
|
7
|
+
from dissect.target.plugin import Plugin, export
|
8
|
+
from dissect.target.target import Target
|
9
|
+
|
10
|
+
|
11
|
+
class UnixApplicationsPlugin(Plugin):
|
12
|
+
"""Unix Applications plugin."""
|
13
|
+
|
14
|
+
SYSTEM_PATHS = [
|
15
|
+
"/usr/share/applications/",
|
16
|
+
"/usr/local/share/applications/",
|
17
|
+
"/var/lib/snapd/desktop/applications/",
|
18
|
+
"/var/lib/flatpak/exports/share/applications/",
|
19
|
+
]
|
20
|
+
|
21
|
+
USER_PATHS = [
|
22
|
+
".local/share/applications/",
|
23
|
+
]
|
24
|
+
|
25
|
+
SYSTEM_APPS = ("org.gnome.",)
|
26
|
+
|
27
|
+
def __init__(self, target: Target):
|
28
|
+
super().__init__(target)
|
29
|
+
self.desktop_files = list(self._find_desktop_files())
|
30
|
+
|
31
|
+
def _find_desktop_files(self) -> Iterator[TargetPath]:
|
32
|
+
for dir in self.SYSTEM_PATHS:
|
33
|
+
for file in self.target.fs.path(dir).glob("*.desktop"):
|
34
|
+
yield file
|
35
|
+
|
36
|
+
for user_details in self.target.user_details.all_with_home():
|
37
|
+
for dir in self.USER_PATHS:
|
38
|
+
for file in user_details.home_path.joinpath(dir).glob("*.desktop"):
|
39
|
+
yield file
|
40
|
+
|
41
|
+
def check_compatible(self) -> None:
|
42
|
+
if not self.desktop_files:
|
43
|
+
raise UnsupportedPluginError("No application .desktop files found")
|
44
|
+
|
45
|
+
@export(record=UnixApplicationRecord)
|
46
|
+
def applications(self) -> Iterator[UnixApplicationRecord]:
|
47
|
+
"""Yield installed Unix GUI applications from GNOME and XFCE.
|
48
|
+
|
49
|
+
Resources:
|
50
|
+
- https://wiki.archlinux.org/title/Desktop_entries
|
51
|
+
- https://specifications.freedesktop.org/desktop-entry-spec/latest/
|
52
|
+
- https://unix.stackexchange.com/questions/582928/where-gnome-apps-are-installed
|
53
|
+
|
54
|
+
Yields ``UnixApplicationRecord`` records with the following fields:
|
55
|
+
|
56
|
+
.. code-block:: text
|
57
|
+
|
58
|
+
ts_modified (datetime): timestamp when the installation was modified
|
59
|
+
ts_installed (datetime): timestamp when the application was installed on the system
|
60
|
+
name (string): name of the application
|
61
|
+
version (string): version of the application
|
62
|
+
author (string): author of the application
|
63
|
+
type (string): type of the application, either user or system
|
64
|
+
path (string): path to the desktop file entry of the application
|
65
|
+
"""
|
66
|
+
for file in self.desktop_files:
|
67
|
+
config = configutil.parse(file, hint="ini").get("Desktop Entry") or {}
|
68
|
+
stat = file.lstat()
|
69
|
+
|
70
|
+
yield UnixApplicationRecord(
|
71
|
+
ts_modified=stat.st_mtime,
|
72
|
+
ts_installed=stat.st_btime if hasattr(stat, "st_btime") else None,
|
73
|
+
name=config.get("Name"),
|
74
|
+
version=config.get("Version"),
|
75
|
+
path=config.get("Exec"),
|
76
|
+
type="system" if config.get("Icon", "").startswith(self.SYSTEM_APPS) else "user",
|
77
|
+
_target=self.target,
|
78
|
+
)
|
@@ -0,0 +1,79 @@
|
|
1
|
+
from typing import Iterator
|
2
|
+
|
3
|
+
from dissect.target.exceptions import UnsupportedPluginError
|
4
|
+
from dissect.target.filesystems.squashfs import SquashFSFilesystem
|
5
|
+
from dissect.target.helpers import configutil
|
6
|
+
from dissect.target.helpers.fsutil import TargetPath
|
7
|
+
from dissect.target.helpers.record import UnixApplicationRecord
|
8
|
+
from dissect.target.plugin import Plugin, alias, export
|
9
|
+
from dissect.target.target import Target
|
10
|
+
|
11
|
+
|
12
|
+
class SnapPlugin(Plugin):
|
13
|
+
"""Canonical Linux Snapcraft plugin."""
|
14
|
+
|
15
|
+
PATHS = [
|
16
|
+
"/var/lib/snapd/snaps",
|
17
|
+
]
|
18
|
+
|
19
|
+
def __init__(self, target: Target):
|
20
|
+
super().__init__(target)
|
21
|
+
self.installs = list(self._find_installs())
|
22
|
+
|
23
|
+
def check_compatible(self) -> None:
|
24
|
+
if not configutil.HAS_YAML:
|
25
|
+
raise UnsupportedPluginError("Missing required dependency ruamel.yaml")
|
26
|
+
|
27
|
+
if not self.installs:
|
28
|
+
raise UnsupportedPluginError("No snapd install folder(s) found")
|
29
|
+
|
30
|
+
def _find_installs(self) -> Iterator[TargetPath]:
|
31
|
+
for str_path in self.PATHS:
|
32
|
+
if (path := self.target.fs.path(str_path)).exists():
|
33
|
+
yield path
|
34
|
+
|
35
|
+
@export(record=UnixApplicationRecord)
|
36
|
+
@alias("snaps")
|
37
|
+
def snap(self) -> Iterator[UnixApplicationRecord]:
|
38
|
+
"""Yields installed Canonical Linux Snapcraft (snaps) applications on the target system.
|
39
|
+
|
40
|
+
Reads information from installed SquashFS ``*.snap`` files found in ``/var/lib/snapd/snaps``.
|
41
|
+
Logs of the ``snapd`` daemon can be parsed using the ``journal`` or ``syslog`` plugins.
|
42
|
+
|
43
|
+
Resources:
|
44
|
+
- https://github.com/canonical/snapcraft
|
45
|
+
- https://en.wikipedia.org/wiki/Snap_(software)
|
46
|
+
|
47
|
+
Yields ``UnixApplicationRecord`` records with the following fields:
|
48
|
+
|
49
|
+
.. code-block:: text
|
50
|
+
|
51
|
+
ts_modified (datetime): timestamp when the installation was modified
|
52
|
+
name (string): name of the application
|
53
|
+
version (string): version of the application
|
54
|
+
path (string): path to the application snap file
|
55
|
+
"""
|
56
|
+
|
57
|
+
for install_path in self.installs:
|
58
|
+
for snap in install_path.glob("*.snap"):
|
59
|
+
try:
|
60
|
+
squashfs = SquashFSFilesystem(snap.open())
|
61
|
+
|
62
|
+
except (ValueError, NotImplementedError) as e:
|
63
|
+
self.target.log.warning("Unable to open snap file %s", snap)
|
64
|
+
self.target.log.debug("", exc_info=e)
|
65
|
+
continue
|
66
|
+
|
67
|
+
if not (meta := squashfs.path("meta/snap.yaml")).exists():
|
68
|
+
self.target.log.warning("Snap %s has no meta/snap.yaml file")
|
69
|
+
continue
|
70
|
+
|
71
|
+
meta_data = configutil.parse(meta, hint="yaml")
|
72
|
+
|
73
|
+
yield UnixApplicationRecord(
|
74
|
+
ts_modified=meta.lstat().st_mtime,
|
75
|
+
name=meta_data.get("name"),
|
76
|
+
version=meta_data.get("version"),
|
77
|
+
path=snap,
|
78
|
+
_target=self.target,
|
79
|
+
)
|
@@ -6,7 +6,7 @@ from dissect.target.helpers.record import TargetRecordDescriptor
|
|
6
6
|
from dissect.target.plugin import NamespacePlugin
|
7
7
|
|
8
8
|
PackageManagerLogRecord = TargetRecordDescriptor(
|
9
|
-
"unix/log
|
9
|
+
"unix/packagemanager/log",
|
10
10
|
[
|
11
11
|
("datetime", "ts"),
|
12
12
|
("string", "package_manager"),
|
@@ -0,0 +1,62 @@
|
|
1
|
+
from datetime import datetime
|
2
|
+
from typing import Iterator
|
3
|
+
|
4
|
+
from dissect.target.exceptions import UnsupportedPluginError
|
5
|
+
from dissect.target.helpers.record import WindowsApplicationRecord
|
6
|
+
from dissect.target.plugin import Plugin, export
|
7
|
+
from dissect.target.target import Target
|
8
|
+
|
9
|
+
|
10
|
+
class WindowsApplicationsPlugin(Plugin):
|
11
|
+
"""Windows Applications plugin."""
|
12
|
+
|
13
|
+
def __init__(self, target: Target):
|
14
|
+
super().__init__(target)
|
15
|
+
self.keys = list(self.target.registry.keys("HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"))
|
16
|
+
|
17
|
+
def check_compatible(self) -> None:
|
18
|
+
if not self.target.has_function("registry"):
|
19
|
+
raise UnsupportedPluginError("No Windows registry found")
|
20
|
+
|
21
|
+
if not self.keys:
|
22
|
+
raise UnsupportedPluginError("No 'Uninstall' registry keys found")
|
23
|
+
|
24
|
+
@export(record=WindowsApplicationRecord)
|
25
|
+
def applications(self) -> Iterator[WindowsApplicationRecord]:
|
26
|
+
"""Yields currently installed applications from the Windows registry.
|
27
|
+
|
28
|
+
Use the Windows eventlog plugin (``evtx``, ``evt``) to parse install and uninstall events
|
29
|
+
of applications and services (e.g. ``4697``, ``110707``, ``1034`` and ``11724``).
|
30
|
+
|
31
|
+
Resources:
|
32
|
+
- https://learn.microsoft.com/en-us/windows/win32/msi/uninstall-registry-key
|
33
|
+
|
34
|
+
Yields ``WindowsApplicationRecord`` records with the following fields:
|
35
|
+
|
36
|
+
.. code-block:: text
|
37
|
+
|
38
|
+
ts_modified (datetime): timestamp when the installation was modified according to the registry
|
39
|
+
ts_installed (datetime): timestamp when the application was installed according to the application
|
40
|
+
name (string): name of the application
|
41
|
+
version (string): version of the application
|
42
|
+
author (string): author of the application
|
43
|
+
type (string): type of the application, either user or system
|
44
|
+
path (string): path to the installed location or installer of the application
|
45
|
+
"""
|
46
|
+
for uninstall in self.keys:
|
47
|
+
for app in uninstall.subkeys():
|
48
|
+
values = {value.name: value.value for value in app.values()}
|
49
|
+
|
50
|
+
if install_date := values.get("InstallDate"):
|
51
|
+
install_date = datetime.strptime(install_date, "%Y%m%d")
|
52
|
+
|
53
|
+
yield WindowsApplicationRecord(
|
54
|
+
ts_modified=app.ts,
|
55
|
+
ts_installed=install_date,
|
56
|
+
name=values.get("DisplayName") or app.name,
|
57
|
+
version=values.get("DisplayVersion"),
|
58
|
+
author=values.get("Publisher"),
|
59
|
+
type="system" if values.get("SystemComponent") or not values else "user",
|
60
|
+
path=values.get("DisplayIcon") or values.get("InstallLocation") or values.get("InstallSource"),
|
61
|
+
_target=self.target,
|
62
|
+
)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: dissect.target
|
3
|
-
Version: 3.20.
|
3
|
+
Version: 3.20.dev40
|
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
|
@@ -60,9 +60,9 @@ dissect/target/helpers/mount.py,sha256=7Y4B0uY2c00p23hmuMKSgwAwxkKcY4spyAMO1kdcV
|
|
60
60
|
dissect/target/helpers/mui.py,sha256=i-7XoHbu4WO2fYapK9yGAMW04rFlgRispknc1KQIS5Q,22258
|
61
61
|
dissect/target/helpers/polypath.py,sha256=h8p7m_OCNiQljGwoZh5Aflr9H2ot6CZr6WKq1OSw58o,2175
|
62
62
|
dissect/target/helpers/protobuf.py,sha256=b4DsnqrRLrefcDjx7rQno-_LBcwtJXxuKf5RdOegzfE,1537
|
63
|
-
dissect/target/helpers/record.py,sha256=
|
63
|
+
dissect/target/helpers/record.py,sha256=TxG1lwW5N0V-7kuq4s2vnQh-hAbT7rVwwZLf4sIDNjM,6334
|
64
64
|
dissect/target/helpers/record_modifier.py,sha256=cRNDhUYMmx4iEKyEr5Pqy9xiFgxr_GBNJPp_omkQsEU,4094
|
65
|
-
dissect/target/helpers/regutil.py,sha256=
|
65
|
+
dissect/target/helpers/regutil.py,sha256=dnmpceitwTeS-9L8HU_HG5OXMzCcH58o8uhj5olDWyg,28383
|
66
66
|
dissect/target/helpers/shell_application_ids.py,sha256=hYxrP-YtHK7ZM0ectJFHfoMB8QUXLbYNKmKXMWLZRlA,38132
|
67
67
|
dissect/target/helpers/shell_folder_ids.py,sha256=Behhb8oh0kMxrEk6YYKYigCDZe8Hw5QS6iK_d2hTs2Y,24978
|
68
68
|
dissect/target/helpers/utils.py,sha256=K3xVq9D0FwIhTBAuiWN8ph7Pq2GABgG3hOz-3AmKuEA,4244
|
@@ -195,12 +195,13 @@ dissect/target/plugins/general/users.py,sha256=yy9gvRXfN9BT71v4Xqo5hpwfgN9he9Otu
|
|
195
195
|
dissect/target/plugins/os/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
196
196
|
dissect/target/plugins/os/unix/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
197
197
|
dissect/target/plugins/os/unix/_os.py,sha256=I-waC7Hn9rMJRI2JUDreLnU_LS54Zj3hix7BfJLV-xg,14651
|
198
|
+
dissect/target/plugins/os/unix/applications.py,sha256=AUgZRP35FzswGyFyChj2o4dfGO34Amc6nqHgiMEaqdI,3129
|
198
199
|
dissect/target/plugins/os/unix/cronjobs.py,sha256=tgWQ3BUZpfyvRzodMwGtwFUdPjZ17k7ZRbZ9Q8wmXPk,3393
|
199
200
|
dissect/target/plugins/os/unix/datetime.py,sha256=gKfBdPyUirt3qmVYfOJ1oZXRPn8wRzssbZxR_ARrtk8,1518
|
200
201
|
dissect/target/plugins/os/unix/generic.py,sha256=qC4zQiqpm8ilc-d1ITsccOQbbUUM8HylWB4dsFKJjAw,2171
|
201
202
|
dissect/target/plugins/os/unix/history.py,sha256=95EXJrD5ko7iFLsYhAwvR-2wDbVBSNsyXsfZKEWMJq8,6533
|
202
203
|
dissect/target/plugins/os/unix/locale.py,sha256=l42abqG1nGk90SDRt1DmkvqPvO5L-1GtaEwg6dj89qI,4323
|
203
|
-
dissect/target/plugins/os/unix/packagemanager.py,sha256=
|
204
|
+
dissect/target/plugins/os/unix/packagemanager.py,sha256=xmisH9vMY7uR2d6lFVNuWrZrbVnKa6mYk6C3sbcLtlc,1279
|
204
205
|
dissect/target/plugins/os/unix/shadow.py,sha256=TVQQcGhPFYV685ouqOagk4P1AsqAHseFN5lWYHPf3tI,4172
|
205
206
|
dissect/target/plugins/os/unix/trash.py,sha256=Z-1r5VQorLauj_85TgURRLQI7ns1Q1N_922Vq8q_v18,6106
|
206
207
|
dissect/target/plugins/os/unix/bsd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -240,6 +241,7 @@ dissect/target/plugins/os/unix/linux/debian/__init__.py,sha256=47DEQpj8HBSa-_TIm
|
|
240
241
|
dissect/target/plugins/os/unix/linux/debian/_os.py,sha256=GI19ZqcyfZ1mUYg2NCx93HkZje9MWMU8FYNKQv-G6go,498
|
241
242
|
dissect/target/plugins/os/unix/linux/debian/apt.py,sha256=uKfW77pbgxYSe9g6hpih19-xfgvCB954Ygx21j-ydzk,4388
|
242
243
|
dissect/target/plugins/os/unix/linux/debian/dpkg.py,sha256=6A3mb77NREdDWDTFrmcfCF_XxHMmD4_5eHqHEl_7Vqg,5816
|
244
|
+
dissect/target/plugins/os/unix/linux/debian/snap.py,sha256=YVz1N54eQsj2_22LUJIj6Gg-huwT4xDEcOAZn9Tvgw4,3023
|
243
245
|
dissect/target/plugins/os/unix/linux/debian/vyos/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
244
246
|
dissect/target/plugins/os/unix/linux/debian/vyos/_os.py,sha256=TPjcfv1n68RCe3Er4aCVQwQDCZwJT-NLvje3kPjDfhk,1744
|
245
247
|
dissect/target/plugins/os/unix/linux/fortios/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -324,6 +326,7 @@ dissect/target/plugins/os/windows/log/pfro.py,sha256=d53Mm7ovZa9crSwVRPwjMVxTd_j
|
|
324
326
|
dissect/target/plugins/os/windows/log/schedlgu.py,sha256=JaP8H8eTEypWXhx2aFSR_IMam6rQiksbLKhMr_U4fz8,5570
|
325
327
|
dissect/target/plugins/os/windows/regf/7zip.py,sha256=Ox8cLyQtbyYQS7m4eY3onNv1K8N2IkS5wexrC55Urd4,3444
|
326
328
|
dissect/target/plugins/os/windows/regf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
329
|
+
dissect/target/plugins/os/windows/regf/applications.py,sha256=AZwaLXsVmqMjoZYI3dhYLvJL_8s1k1aRjSgjvqC2AxI,2898
|
327
330
|
dissect/target/plugins/os/windows/regf/appxdebugkeys.py,sha256=X8MYLcD76pIZoIWwS_DgUp6q6pi2WO7jhZeoc4uGLak,3966
|
328
331
|
dissect/target/plugins/os/windows/regf/auditpol.py,sha256=vTqWw0_vu9p_emWC8FuYcYQpOXhEFQQDLV0K6-18i9c,5208
|
329
332
|
dissect/target/plugins/os/windows/regf/bam.py,sha256=jJ0i-82uteBU0hPgs81f8NV8NCeRtIklK82Me2S_ro0,2131
|
@@ -370,10 +373,10 @@ dissect/target/volumes/luks.py,sha256=OmCMsw6rCUXG1_plnLVLTpsvE1n_6WtoRUGQbpmu1z
|
|
370
373
|
dissect/target/volumes/lvm.py,sha256=wwQVR9I3G9YzmY6UxFsH2Y4MXGBcKL9aayWGCDTiWMU,2269
|
371
374
|
dissect/target/volumes/md.py,sha256=7ShPtusuLGaIv27SvEETtgsuoQyAa4iAAeOR1NEaajI,1689
|
372
375
|
dissect/target/volumes/vmfs.py,sha256=-LoUbn9WNwTtLi_4K34uV_-wDw2W5hgaqxZNj4UmqAQ,1730
|
373
|
-
dissect.target-3.20.
|
374
|
-
dissect.target-3.20.
|
375
|
-
dissect.target-3.20.
|
376
|
-
dissect.target-3.20.
|
377
|
-
dissect.target-3.20.
|
378
|
-
dissect.target-3.20.
|
379
|
-
dissect.target-3.20.
|
376
|
+
dissect.target-3.20.dev40.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
|
377
|
+
dissect.target-3.20.dev40.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
|
378
|
+
dissect.target-3.20.dev40.dist-info/METADATA,sha256=sfc-H38qJzXkx1449zv0Y7SgicuUfJeki3JFiC6EJ4c,12897
|
379
|
+
dissect.target-3.20.dev40.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
|
380
|
+
dissect.target-3.20.dev40.dist-info/entry_points.txt,sha256=BWuxAb_6AvUAQpIQOQU0IMTlaF6TDht2AIZK8bHd-zE,492
|
381
|
+
dissect.target-3.20.dev40.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
|
382
|
+
dissect.target-3.20.dev40.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
{dissect.target-3.20.dev39.dist-info → dissect.target-3.20.dev40.dist-info}/entry_points.txt
RENAMED
File without changes
|
File without changes
|