dissect.target 3.19.dev46__py3-none-any.whl → 3.19.dev47__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/filesystem.py +36 -22
- dissect/target/helpers/fsutil.py +15 -0
- dissect/target/plugins/filesystem/unix/capability.py +102 -87
- dissect/target/plugins/filesystem/walkfs.py +32 -21
- {dissect.target-3.19.dev46.dist-info → dissect.target-3.19.dev47.dist-info}/METADATA +1 -1
- {dissect.target-3.19.dev46.dist-info → dissect.target-3.19.dev47.dist-info}/RECORD +11 -11
- {dissect.target-3.19.dev46.dist-info → dissect.target-3.19.dev47.dist-info}/WHEEL +1 -1
- {dissect.target-3.19.dev46.dist-info → dissect.target-3.19.dev47.dist-info}/COPYRIGHT +0 -0
- {dissect.target-3.19.dev46.dist-info → dissect.target-3.19.dev47.dist-info}/LICENSE +0 -0
- {dissect.target-3.19.dev46.dist-info → dissect.target-3.19.dev47.dist-info}/entry_points.txt +0 -0
- {dissect.target-3.19.dev46.dist-info → dissect.target-3.19.dev47.dist-info}/top_level.txt +0 -0
dissect/target/filesystem.py
CHANGED
@@ -228,10 +228,9 @@ class Filesystem:
|
|
228
228
|
topdown: bool = True,
|
229
229
|
onerror: Optional[Callable] = None,
|
230
230
|
followlinks: bool = False,
|
231
|
-
) -> Iterator[str]:
|
232
|
-
"""
|
233
|
-
|
234
|
-
It walks across all the files inside ``path`` recursively.
|
231
|
+
) -> Iterator[tuple[str, list[str], list[str]]]:
|
232
|
+
"""Recursively walk a directory pointed to by ``path``, returning the string representation of both files
|
233
|
+
and directories.
|
235
234
|
|
236
235
|
Args:
|
237
236
|
path: The path to walk on the filesystem.
|
@@ -250,10 +249,9 @@ class Filesystem:
|
|
250
249
|
topdown: bool = True,
|
251
250
|
onerror: Optional[Callable] = None,
|
252
251
|
followlinks: bool = False,
|
253
|
-
) -> Iterator[FilesystemEntry]:
|
254
|
-
"""
|
255
|
-
|
256
|
-
It walks across all the files inside ``path`` recursively.
|
252
|
+
) -> Iterator[tuple[list[FilesystemEntry], list[FilesystemEntry], list[FilesystemEntry]]]:
|
253
|
+
"""Recursively walk a directory pointed to by ``path``, returning :class:`FilesystemEntry` of files
|
254
|
+
and directories.
|
257
255
|
|
258
256
|
Args:
|
259
257
|
path: The path to walk on the filesystem.
|
@@ -266,6 +264,19 @@ class Filesystem:
|
|
266
264
|
"""
|
267
265
|
return self.get(path).walk_ext(topdown, onerror, followlinks)
|
268
266
|
|
267
|
+
def recurse(self, path: str) -> Iterator[FilesystemEntry]:
|
268
|
+
"""Recursively walk a directory and yield contents as :class:`FilesystemEntry`.
|
269
|
+
|
270
|
+
Does not follow symbolic links.
|
271
|
+
|
272
|
+
Args:
|
273
|
+
path: The path to recursively walk on the target filesystem.
|
274
|
+
|
275
|
+
Returns:
|
276
|
+
An iterator of :class:`FilesystemEntry`.
|
277
|
+
"""
|
278
|
+
return self.get(path).recurse()
|
279
|
+
|
269
280
|
def glob(self, pattern: str) -> Iterator[str]:
|
270
281
|
"""Iterate over the directory part of ``pattern``, returning entries matching ``pattern`` as strings.
|
271
282
|
|
@@ -578,10 +589,9 @@ class FilesystemEntry:
|
|
578
589
|
topdown: bool = True,
|
579
590
|
onerror: Optional[Callable] = None,
|
580
591
|
followlinks: bool = False,
|
581
|
-
) -> Iterator[str]:
|
582
|
-
"""
|
583
|
-
|
584
|
-
It walks across all the files inside the entry recursively.
|
592
|
+
) -> Iterator[tuple[str, list[str], list[str]]]:
|
593
|
+
"""Recursively walk a directory and yield its contents as strings split in a tuple
|
594
|
+
of lists of files, directories and symlinks.
|
585
595
|
|
586
596
|
These contents include::
|
587
597
|
- files
|
@@ -603,15 +613,9 @@ class FilesystemEntry:
|
|
603
613
|
topdown: bool = True,
|
604
614
|
onerror: Optional[Callable] = None,
|
605
615
|
followlinks: bool = False,
|
606
|
-
) -> Iterator[FilesystemEntry]:
|
607
|
-
"""
|
608
|
-
|
609
|
-
It walks across all the files inside the entry recursively.
|
610
|
-
|
611
|
-
These contents include::
|
612
|
-
- files
|
613
|
-
- directories
|
614
|
-
- symboliclinks
|
616
|
+
) -> Iterator[tuple[list[FilesystemEntry], list[FilesystemEntry], list[FilesystemEntry]]]:
|
617
|
+
"""Recursively walk a directory and yield its contents as :class:`FilesystemEntry` split in a tuple of
|
618
|
+
lists of files, directories and symlinks.
|
615
619
|
|
616
620
|
Args:
|
617
621
|
topdown: ``True`` puts this entry at the top of the list, ``False`` puts this entry at the bottom.
|
@@ -619,10 +623,20 @@ class FilesystemEntry:
|
|
619
623
|
followlinks: ``True`` if we want to follow any symbolic link
|
620
624
|
|
621
625
|
Returns:
|
622
|
-
An iterator of :class:`FilesystemEntry`.
|
626
|
+
An iterator of tuples :class:`FilesystemEntry`.
|
623
627
|
"""
|
624
628
|
yield from fsutil.walk_ext(self, topdown, onerror, followlinks)
|
625
629
|
|
630
|
+
def recurse(self) -> Iterator[FilesystemEntry]:
|
631
|
+
"""Recursively walk a directory and yield its contents as :class:`FilesystemEntry`.
|
632
|
+
|
633
|
+
Does not follow symbolic links.
|
634
|
+
|
635
|
+
Returns:
|
636
|
+
An iterator of :class:`FilesystemEntry`.
|
637
|
+
"""
|
638
|
+
yield from fsutil.recurse(self)
|
639
|
+
|
626
640
|
def glob(self, pattern: str) -> Iterator[str]:
|
627
641
|
"""Iterate over this directory part of ``patern``, returning entries matching ``pattern`` as strings.
|
628
642
|
|
dissect/target/helpers/fsutil.py
CHANGED
@@ -96,6 +96,7 @@ __all__ = [
|
|
96
96
|
"TargetPath",
|
97
97
|
"walk_ext",
|
98
98
|
"walk",
|
99
|
+
"recurse",
|
99
100
|
]
|
100
101
|
|
101
102
|
|
@@ -291,6 +292,20 @@ def walk_ext(path_entry, topdown=True, onerror=None, followlinks=False):
|
|
291
292
|
yield [path_entry], dirs, files
|
292
293
|
|
293
294
|
|
295
|
+
def recurse(path_entry: filesystem.FilesystemEntry) -> Iterator[filesystem.FilesystemEntry]:
|
296
|
+
"""Recursively walk the given :class:`FilesystemEntry`, yields :class:`FilesystemEntry` instances."""
|
297
|
+
yield path_entry
|
298
|
+
|
299
|
+
if not path_entry.is_dir():
|
300
|
+
return
|
301
|
+
|
302
|
+
for child_entry in path_entry.scandir():
|
303
|
+
if child_entry.is_dir() and not child_entry.is_symlink():
|
304
|
+
yield from recurse(child_entry)
|
305
|
+
else:
|
306
|
+
yield child_entry
|
307
|
+
|
308
|
+
|
294
309
|
def glob_split(pattern: str, alt_separator: str = "") -> tuple[str, str]:
|
295
310
|
"""Split a pattern on path part boundaries on the first path part with a glob pattern.
|
296
311
|
|
@@ -1,20 +1,20 @@
|
|
1
|
-
import struct
|
2
1
|
from enum import IntEnum
|
3
2
|
from io import BytesIO
|
3
|
+
from typing import Iterator
|
4
4
|
|
5
|
-
from dissect.target.exceptions import
|
5
|
+
from dissect.target.exceptions import UnsupportedPluginError
|
6
6
|
from dissect.target.helpers.record import TargetRecordDescriptor
|
7
7
|
from dissect.target.plugin import Plugin, export
|
8
|
-
from dissect.target.plugins.filesystem.walkfs import generate_record
|
9
8
|
|
10
9
|
CapabilityRecord = TargetRecordDescriptor(
|
11
10
|
"filesystem/unix/capability",
|
12
11
|
[
|
13
|
-
("
|
12
|
+
("datetime", "ts_mtime"),
|
13
|
+
("path", "path"),
|
14
14
|
("string[]", "permitted"),
|
15
15
|
("string[]", "inheritable"),
|
16
16
|
("boolean", "effective"),
|
17
|
-
("uint32", "
|
17
|
+
("uint32", "root_id"),
|
18
18
|
],
|
19
19
|
)
|
20
20
|
|
@@ -82,88 +82,103 @@ class CapabilityPlugin(Plugin):
|
|
82
82
|
"""Plugin to yield files with capabilites set."""
|
83
83
|
|
84
84
|
def check_compatible(self) -> None:
|
85
|
-
if not self.target.has_function("walkfs")
|
86
|
-
raise UnsupportedPluginError("
|
85
|
+
if not self.target.has_function("walkfs"):
|
86
|
+
raise UnsupportedPluginError("Need walkfs plugin")
|
87
|
+
|
88
|
+
if not any(fs.__type__ in ("extfs", "xfs") for fs in self.target.filesystems):
|
89
|
+
raise UnsupportedPluginError("Capability plugin only works on EXT and XFS filesystems")
|
87
90
|
|
88
91
|
@export(record=CapabilityRecord)
|
89
|
-
def capability_binaries(self):
|
90
|
-
"""Find all files that have capabilities set.
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
92
|
+
def capability_binaries(self) -> Iterator[CapabilityRecord]:
|
93
|
+
"""Find all files that have capabilities set on files.
|
94
|
+
|
95
|
+
Resources:
|
96
|
+
- https://github.com/torvalds/linux/blob/master/include/uapi/linux/capability.h
|
97
|
+
"""
|
98
|
+
|
99
|
+
for entry in self.target.fs.recurse("/"):
|
100
|
+
if not entry.is_file() or entry.is_symlink():
|
101
|
+
continue
|
102
|
+
|
103
|
+
try:
|
104
|
+
attrs = [attr for attr in entry.lattr() if attr.name == "security.capability"]
|
105
|
+
except Exception as e:
|
106
|
+
self.target.log.warning("Failed to get attrs for entry %s", entry)
|
107
|
+
self.target.log.debug("", exc_info=e)
|
108
|
+
continue
|
109
|
+
|
110
|
+
for attr in attrs:
|
99
111
|
try:
|
100
|
-
|
101
|
-
except
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
112
|
+
permitted, inheritable, effective, root_id = parse_attr(attr.value)
|
113
|
+
except ValueError as e:
|
114
|
+
self.target.log.warning("Could not parse attributes for entry %s: %s", entry, str(e.value))
|
115
|
+
self.target.log.debug("", exc_info=e)
|
116
|
+
|
117
|
+
yield CapabilityRecord(
|
118
|
+
ts_mtime=entry.lstat().st_mtime,
|
119
|
+
path=self.target.fs.path(entry.path),
|
120
|
+
permitted=permitted,
|
121
|
+
inheritable=inheritable,
|
122
|
+
effective=effective,
|
123
|
+
root_id=root_id,
|
124
|
+
_target=self.target,
|
125
|
+
)
|
126
|
+
|
127
|
+
|
128
|
+
def parse_attr(attr: bytes) -> tuple[list[str], list[str], bool, int]:
|
129
|
+
"""Efficiently parse a Linux xattr capability struct.
|
130
|
+
|
131
|
+
Returns:
|
132
|
+
A tuple of permitted capability names, inheritable capability names, effective flag and ``root_id``.
|
133
|
+
"""
|
134
|
+
buf = BytesIO(attr)
|
135
|
+
|
136
|
+
# The struct is small enough we can just use int.from_bytes
|
137
|
+
magic_etc = int.from_bytes(buf.read(4), "little")
|
138
|
+
effective = magic_etc & VFS_CAP_FLAGS_EFFECTIVE != 0
|
139
|
+
cap_revision = magic_etc & VFS_CAP_REVISION_MASK
|
140
|
+
|
141
|
+
permitted_caps = []
|
142
|
+
inheritable_caps = []
|
143
|
+
root_id = None
|
144
|
+
|
145
|
+
if cap_revision == VFS_CAP_REVISION_1:
|
146
|
+
num_caps = VFS_CAP_U32_1
|
147
|
+
data_len = (1 + 2 * VFS_CAP_U32_1) * 4
|
148
|
+
|
149
|
+
elif cap_revision == VFS_CAP_REVISION_2:
|
150
|
+
num_caps = VFS_CAP_U32_2
|
151
|
+
data_len = (1 + 2 * VFS_CAP_U32_2) * 4
|
152
|
+
|
153
|
+
elif cap_revision == VFS_CAP_REVISION_3:
|
154
|
+
num_caps = VFS_CAP_U32_3
|
155
|
+
data_len = (2 + 2 * VFS_CAP_U32_2) * 4
|
156
|
+
|
157
|
+
else:
|
158
|
+
raise ValueError("Unexpected capability revision '%s'" % cap_revision)
|
159
|
+
|
160
|
+
if data_len != (actual_len := len(attr)):
|
161
|
+
raise ValueError("Unexpected capability length (%s vs %s)", data_len, actual_len)
|
162
|
+
|
163
|
+
for _ in range(num_caps):
|
164
|
+
permitted_caps.append(int.from_bytes(buf.read(4), "little"))
|
165
|
+
inheritable_caps.append(int.from_bytes(buf.read(4), "little"))
|
166
|
+
|
167
|
+
if cap_revision == VFS_CAP_REVISION_3:
|
168
|
+
root_id = int.from_bytes(buf.read(4), "little")
|
169
|
+
|
170
|
+
permitted = []
|
171
|
+
inheritable = []
|
172
|
+
|
173
|
+
for capability in Capabilities:
|
174
|
+
for caps, results in [(permitted_caps, permitted), (inheritable_caps, inheritable)]:
|
175
|
+
# CAP_TO_INDEX
|
176
|
+
cap_index = capability.value >> 5
|
177
|
+
if cap_index >= len(caps):
|
178
|
+
# We loop over all capabilities, but might only have a version 1 caps list
|
179
|
+
continue
|
180
|
+
|
181
|
+
if caps[cap_index] & (1 << (capability.value & 31)) != 0:
|
182
|
+
results.append(capability.name)
|
183
|
+
|
184
|
+
return permitted, inheritable, effective, root_id
|
@@ -1,12 +1,11 @@
|
|
1
|
-
from typing import
|
1
|
+
from typing import Iterator
|
2
2
|
|
3
3
|
from dissect.util.ts import from_unix
|
4
4
|
|
5
5
|
from dissect.target.exceptions import FileNotFoundError, UnsupportedPluginError
|
6
|
-
from dissect.target.filesystem import LayerFilesystemEntry
|
7
|
-
from dissect.target.helpers.fsutil import TargetPath
|
6
|
+
from dissect.target.filesystem import FilesystemEntry, LayerFilesystemEntry
|
8
7
|
from dissect.target.helpers.record import TargetRecordDescriptor
|
9
|
-
from dissect.target.plugin import Plugin, export
|
8
|
+
from dissect.target.plugin import Plugin, arg, export
|
10
9
|
from dissect.target.target import Target
|
11
10
|
|
12
11
|
FilesystemRecord = TargetRecordDescriptor(
|
@@ -30,37 +29,49 @@ FilesystemRecord = TargetRecordDescriptor(
|
|
30
29
|
class WalkFSPlugin(Plugin):
|
31
30
|
def check_compatible(self) -> None:
|
32
31
|
if not len(self.target.filesystems):
|
33
|
-
raise UnsupportedPluginError("No filesystems
|
32
|
+
raise UnsupportedPluginError("No filesystems to walk")
|
34
33
|
|
35
34
|
@export(record=FilesystemRecord)
|
36
|
-
|
35
|
+
@arg("--walkfs-path", default="/", help="path to recursively walk")
|
36
|
+
def walkfs(self, walkfs_path: str = "/") -> Iterator[FilesystemRecord]:
|
37
37
|
"""Walk a target's filesystem and return all filesystem entries."""
|
38
|
-
for
|
39
|
-
|
40
|
-
|
41
|
-
path = self.target.fs.path(entry.path)
|
42
|
-
try:
|
43
|
-
record = generate_record(self.target, path)
|
44
|
-
except FileNotFoundError:
|
45
|
-
continue
|
46
|
-
yield record
|
38
|
+
for entry in self.target.fs.recurse(walkfs_path):
|
39
|
+
try:
|
40
|
+
yield generate_record(self.target, entry)
|
47
41
|
|
42
|
+
except FileNotFoundError as e:
|
43
|
+
self.target.log.warning("File not found: %s", entry)
|
44
|
+
self.target.log.debug("", exc_info=e)
|
45
|
+
except Exception as e:
|
46
|
+
self.target.log.warning("Exception generating record for: %s", entry)
|
47
|
+
self.target.log.debug("", exc_info=e)
|
48
|
+
continue
|
49
|
+
|
50
|
+
|
51
|
+
def generate_record(target: Target, entry: FilesystemEntry) -> FilesystemRecord:
|
52
|
+
"""Generate a :class:`FilesystemRecord` from the given :class:`FilesystemEntry`.
|
53
|
+
|
54
|
+
Args:
|
55
|
+
target: :class:`Target` instance
|
56
|
+
entry: :class:`FilesystemEntry` instance
|
57
|
+
|
58
|
+
Returns:
|
59
|
+
Generated :class:`FilesystemRecord` for the given :class:`FilesystemEntry`.
|
60
|
+
"""
|
61
|
+
stat = entry.lstat()
|
48
62
|
|
49
|
-
def generate_record(target: Target, path: TargetPath) -> FilesystemRecord:
|
50
|
-
stat = path.lstat()
|
51
|
-
btime = from_unix(stat.st_birthtime) if stat.st_birthtime else None
|
52
|
-
entry = path.get()
|
53
63
|
if isinstance(entry, LayerFilesystemEntry):
|
54
64
|
fs_types = [sub_entry.fs.__type__ for sub_entry in entry.entries]
|
55
65
|
else:
|
56
66
|
fs_types = [entry.fs.__type__]
|
67
|
+
|
57
68
|
return FilesystemRecord(
|
58
69
|
atime=from_unix(stat.st_atime),
|
59
70
|
mtime=from_unix(stat.st_mtime),
|
60
71
|
ctime=from_unix(stat.st_ctime),
|
61
|
-
btime=
|
72
|
+
btime=from_unix(stat.st_birthtime) if stat.st_birthtime else None,
|
62
73
|
ino=stat.st_ino,
|
63
|
-
path=path,
|
74
|
+
path=entry.path,
|
64
75
|
size=stat.st_size,
|
65
76
|
mode=stat.st_mode,
|
66
77
|
uid=stat.st_uid,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: dissect.target
|
3
|
-
Version: 3.19.
|
3
|
+
Version: 3.19.dev47
|
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,7 +1,7 @@
|
|
1
1
|
dissect/target/__init__.py,sha256=Oc7ounTgq2hE4nR6YcNabetc7SQA40ldSa35VEdZcQU,63
|
2
2
|
dissect/target/container.py,sha256=0YcwcGmfJjhPXUB6DEcjWEoSuAtTDxMDpoTviMrLsxM,9353
|
3
3
|
dissect/target/exceptions.py,sha256=ULi7NXlqju_d8KENEL3aimmfKTFfbNssfeWhAnOB654,2972
|
4
|
-
dissect/target/filesystem.py,sha256=
|
4
|
+
dissect/target/filesystem.py,sha256=WpcT7UKzJxr85-Y4x8QeQci4UX0z39VlraRcnmkDFkg,60519
|
5
5
|
dissect/target/loader.py,sha256=I8WNzDA0SMy42F7zfyBcSKj_VKNv64213WUvtGZ77qE,7374
|
6
6
|
dissect/target/plugin.py,sha256=k9xWNnIGQG0DQsq6DKYJ6_DAX1aIA0SjzniWmOwX8O4,50317
|
7
7
|
dissect/target/report.py,sha256=06uiP4MbNI8cWMVrC1SasNS-Yg6ptjVjckwj8Yhe0Js,7958
|
@@ -50,7 +50,7 @@ dissect/target/helpers/configutil.py,sha256=AEnkMQ0e6PncvCqGa-ACzBQWQBhMGBCzO5qz
|
|
50
50
|
dissect/target/helpers/cyber.py,sha256=WnJlk-HqAETmDAgLq92JPxyDLxvzSoFV_WrO-odVKBI,16805
|
51
51
|
dissect/target/helpers/descriptor_extensions.py,sha256=uT8GwznfDAiIgMM7JKKOY0PXKMv2c0GCqJTCkWFgops,2605
|
52
52
|
dissect/target/helpers/docs.py,sha256=J5U65Y3yOTqxDEZRCdrEmO63XQCeDzOJea1PwPM6Cyc,5146
|
53
|
-
dissect/target/helpers/fsutil.py,sha256=
|
53
|
+
dissect/target/helpers/fsutil.py,sha256=X1JrgVd9VZh-ttynar3uW9Y9vdqvB5uMvq-4DKFgm9k,20356
|
54
54
|
dissect/target/helpers/hashutil.py,sha256=bYAGEjyYyxuCTziO4kCx6srzY1Cm-PXmayRRcxt5ca4,1061
|
55
55
|
dissect/target/helpers/keychain.py,sha256=wYH0sf7eaxP0bZTo80RF_BQMWulCWmIQ8Tzt9K5TSNQ,3611
|
56
56
|
dissect/target/helpers/lazy.py,sha256=823VtmdWsbJyVZvNWopDhQdqq2i1xtj6b8IKfveboKw,1771
|
@@ -169,7 +169,7 @@ dissect/target/plugins/filesystem/acquire_handles.py,sha256=-pX_akH5GrYe0HofXOa2
|
|
169
169
|
dissect/target/plugins/filesystem/acquire_hash.py,sha256=OVxI19-Bl1tdqCiFMscFMLmyoiBOsuAjL-Q8aQpEwl0,1441
|
170
170
|
dissect/target/plugins/filesystem/icat.py,sha256=bOMi04IlljnKwxTWTZJKtK7RxKnabFu3WcXyUwzkE-4,4090
|
171
171
|
dissect/target/plugins/filesystem/resolver.py,sha256=HfyASUFV4F9uD-yFXilFpPTORAsRDvdmTvuYHgOaOWg,4776
|
172
|
-
dissect/target/plugins/filesystem/walkfs.py,sha256=
|
172
|
+
dissect/target/plugins/filesystem/walkfs.py,sha256=rklbN805roy2fKAQe5L1JhTvI0qNgGS70ZNGFwevLB0,2740
|
173
173
|
dissect/target/plugins/filesystem/yara.py,sha256=zh4hU3L_egddLqDeaHDVuCWYhTlNzPYPVak36Q6IMxI,6621
|
174
174
|
dissect/target/plugins/filesystem/ntfs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
175
175
|
dissect/target/plugins/filesystem/ntfs/mft.py,sha256=WzvKSlH4egvDsuonRQ3AjYS59t9jjFX_-GOsAPLUeSk,12418
|
@@ -177,7 +177,7 @@ dissect/target/plugins/filesystem/ntfs/mft_timeline.py,sha256=vvNFAZbr7s3X2OTYf4
|
|
177
177
|
dissect/target/plugins/filesystem/ntfs/usnjrnl.py,sha256=uiT1ipmcAo__6VIUi8R_vvIu22vdnjMACKwLSAbzYjs,3704
|
178
178
|
dissect/target/plugins/filesystem/ntfs/utils.py,sha256=xG7Lgw9NX4tDDrZVRm0vycFVJTOM7j-HrjqzDh0f4uA,3136
|
179
179
|
dissect/target/plugins/filesystem/unix/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
180
|
-
dissect/target/plugins/filesystem/unix/capability.py,sha256=
|
180
|
+
dissect/target/plugins/filesystem/unix/capability.py,sha256=WScVTW9bZBsH36ZRsAUTZzl9yXG4rglv_MaieWD5H-w,5752
|
181
181
|
dissect/target/plugins/filesystem/unix/suid.py,sha256=Q0Y5CyPm34REruyZYP5siFAka4i7QEOOxZ9K2L-SxPY,1290
|
182
182
|
dissect/target/plugins/general/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
183
183
|
dissect/target/plugins/general/config.py,sha256=Mdy9uhWn4OJ96zfXpLgjVifV5SrViqHnpSnKhC1mjZE,3432
|
@@ -356,10 +356,10 @@ dissect/target/volumes/luks.py,sha256=OmCMsw6rCUXG1_plnLVLTpsvE1n_6WtoRUGQbpmu1z
|
|
356
356
|
dissect/target/volumes/lvm.py,sha256=wwQVR9I3G9YzmY6UxFsH2Y4MXGBcKL9aayWGCDTiWMU,2269
|
357
357
|
dissect/target/volumes/md.py,sha256=7ShPtusuLGaIv27SvEETtgsuoQyAa4iAAeOR1NEaajI,1689
|
358
358
|
dissect/target/volumes/vmfs.py,sha256=-LoUbn9WNwTtLi_4K34uV_-wDw2W5hgaqxZNj4UmqAQ,1730
|
359
|
-
dissect.target-3.19.
|
360
|
-
dissect.target-3.19.
|
361
|
-
dissect.target-3.19.
|
362
|
-
dissect.target-3.19.
|
363
|
-
dissect.target-3.19.
|
364
|
-
dissect.target-3.19.
|
365
|
-
dissect.target-3.19.
|
359
|
+
dissect.target-3.19.dev47.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
|
360
|
+
dissect.target-3.19.dev47.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
|
361
|
+
dissect.target-3.19.dev47.dist-info/METADATA,sha256=NCGFEq1LFs3I0EP59BzAba793TZy6rhKYUi4bT9rBxs,12897
|
362
|
+
dissect.target-3.19.dev47.dist-info/WHEEL,sha256=Mdi9PDNwEZptOjTlUcAth7XJDFtKrHYaQMPulZeBCiQ,91
|
363
|
+
dissect.target-3.19.dev47.dist-info/entry_points.txt,sha256=BWuxAb_6AvUAQpIQOQU0IMTlaF6TDht2AIZK8bHd-zE,492
|
364
|
+
dissect.target-3.19.dev47.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
|
365
|
+
dissect.target-3.19.dev47.dist-info/RECORD,,
|
File without changes
|
File without changes
|
{dissect.target-3.19.dev46.dist-info → dissect.target-3.19.dev47.dist-info}/entry_points.txt
RENAMED
File without changes
|
File without changes
|