dissect.target 3.18.dev2__py3-none-any.whl → 3.18.dev4__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/plugins/os/unix/locate/plocate.py +33 -23
- dissect/target/tools/shell.py +30 -19
- {dissect.target-3.18.dev2.dist-info → dissect.target-3.18.dev4.dist-info}/METADATA +1 -1
- {dissect.target-3.18.dev2.dist-info → dissect.target-3.18.dev4.dist-info}/RECORD +9 -9
- {dissect.target-3.18.dev2.dist-info → dissect.target-3.18.dev4.dist-info}/COPYRIGHT +0 -0
- {dissect.target-3.18.dev2.dist-info → dissect.target-3.18.dev4.dist-info}/LICENSE +0 -0
- {dissect.target-3.18.dev2.dist-info → dissect.target-3.18.dev4.dist-info}/WHEEL +0 -0
- {dissect.target-3.18.dev2.dist-info → dissect.target-3.18.dev4.dist-info}/entry_points.txt +0 -0
- {dissect.target-3.18.dev2.dist-info → dissect.target-3.18.dev4.dist-info}/top_level.txt +0 -0
@@ -1,8 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import platform
|
4
|
-
from
|
5
|
-
from typing import BinaryIO, Iterable
|
4
|
+
from typing import BinaryIO, Iterator
|
6
5
|
|
7
6
|
from dissect.cstruct import cstruct
|
8
7
|
from dissect.util.stream import RangeStream
|
@@ -13,7 +12,11 @@ from dissect.target.plugin import export
|
|
13
12
|
from dissect.target.plugins.os.unix.locate.locate import BaseLocatePlugin
|
14
13
|
|
15
14
|
try:
|
16
|
-
|
15
|
+
from zstandard import (
|
16
|
+
DECOMPRESSION_RECOMMENDED_OUTPUT_SIZE,
|
17
|
+
ZstdCompressionDict,
|
18
|
+
ZstdDecompressor,
|
19
|
+
)
|
17
20
|
|
18
21
|
HAS_ZSTD = True
|
19
22
|
except ImportError:
|
@@ -32,7 +35,7 @@ struct header {
|
|
32
35
|
uint64_t filename_index_offset_bytes;
|
33
36
|
|
34
37
|
/* Version 1 and up only. */
|
35
|
-
uint32_t max_version;
|
38
|
+
uint32_t max_version; // Nominally 1 or 2, but can be increased if more features are added in a backward-compatible way.
|
36
39
|
uint32_t zstd_dictionary_length_bytes;
|
37
40
|
uint64_t zstd_dictionary_offset_bytes;
|
38
41
|
|
@@ -44,6 +47,7 @@ struct header {
|
|
44
47
|
uint64_t conf_block_length_bytes;
|
45
48
|
uint64_t conf_block_offset_bytes;
|
46
49
|
|
50
|
+
// Only if max_version >= 2.
|
47
51
|
uint8_t check_visibility;
|
48
52
|
char padding[7]; /* padding for alignment */
|
49
53
|
};
|
@@ -51,7 +55,7 @@ struct header {
|
|
51
55
|
struct file {
|
52
56
|
char path[];
|
53
57
|
};
|
54
|
-
"""
|
58
|
+
""" # noqa : E501
|
55
59
|
|
56
60
|
PLocateRecord = TargetRecordDescriptor(
|
57
61
|
"linux/locate/plocate",
|
@@ -104,40 +108,46 @@ class PLocateFile:
|
|
104
108
|
self.dict_data = None
|
105
109
|
|
106
110
|
if self.header.zstd_dictionary_offset_bytes:
|
107
|
-
self.dict_data =
|
111
|
+
self.dict_data = ZstdCompressionDict(self.fh.read(self.header.zstd_dictionary_length_bytes))
|
108
112
|
|
109
113
|
self.compressed_length_bytes = (
|
110
114
|
self.header.filename_index_offset_bytes - self.HEADER_SIZE - self.header.zstd_dictionary_length_bytes
|
111
115
|
)
|
112
|
-
self.ctx =
|
116
|
+
self.ctx = ZstdDecompressor(dict_data=self.dict_data)
|
113
117
|
self.buf = RangeStream(self.fh, self.fh.tell(), self.compressed_length_bytes)
|
114
118
|
|
115
|
-
def __iter__(self) ->
|
119
|
+
def __iter__(self) -> Iterator[PLocateFile]:
|
116
120
|
# NOTE: This is a workaround for a PyPy bug
|
117
121
|
# We don't know what breaks, but PyPy + zstandard = unhappy times
|
118
122
|
# You just get random garbage data back instead of the decompressed data
|
119
123
|
# This weird dance of using a decompressobj and unused data is the only way that seems to work
|
120
124
|
# It's more expensive on memory, but at least it doesn't break
|
121
125
|
if platform.python_implementation() == "PyPy":
|
122
|
-
obj = self.ctx.decompressobj()
|
123
126
|
buf = self.buf.read()
|
124
127
|
|
125
|
-
|
126
|
-
|
127
|
-
obj = self.ctx.decompressobj()
|
128
|
-
tmp += obj.decompress(unused_data)
|
128
|
+
def reader(ctx: ZstdDecompressor) -> Iterator[bytes]:
|
129
|
+
obj = ctx.decompressobj()
|
129
130
|
|
130
|
-
|
131
|
+
yield obj.decompress(buf)
|
132
|
+
while unused_data := obj.unused_data:
|
133
|
+
obj = self.ctx.decompressobj()
|
134
|
+
yield obj.decompress(unused_data)
|
135
|
+
|
136
|
+
it = reader(self.ctx)
|
131
137
|
else:
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
138
|
+
# NOTE: The end of a zstandard frame does not include a final `0x00`.
|
139
|
+
# This causes the c_plocate `file` struct to parse the last path and the first path on the next frame as one
|
140
|
+
# since cstruct will read it across frame boundaries waiting for a `0x00`.
|
141
|
+
def reader() -> Iterator[bytes]:
|
142
|
+
with self.ctx.stream_reader(self.buf) as reader:
|
143
|
+
while chunk := reader.read(DECOMPRESSION_RECOMMENDED_OUTPUT_SIZE):
|
144
|
+
yield chunk
|
145
|
+
|
146
|
+
it = reader()
|
147
|
+
|
148
|
+
for chunk in it:
|
149
|
+
for path in chunk.split(b"\x00"):
|
150
|
+
yield path.decode(errors="surrogateescape")
|
141
151
|
|
142
152
|
def filename_index(self) -> bytes:
|
143
153
|
"""Return the filename index of the plocate.db file."""
|
dissect/target/tools/shell.py
CHANGED
@@ -113,6 +113,7 @@ class TargetCmd(cmd.Cmd):
|
|
113
113
|
def __init__(self, target: Target):
|
114
114
|
cmd.Cmd.__init__(self)
|
115
115
|
self.target = target
|
116
|
+
self.debug = False
|
116
117
|
|
117
118
|
def __getattr__(self, attr: str) -> Any:
|
118
119
|
if attr.startswith("help_"):
|
@@ -179,25 +180,22 @@ class TargetCmd(cmd.Cmd):
|
|
179
180
|
lexer.whitespace_split = True
|
180
181
|
argparts = list(lexer)
|
181
182
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
ctx = cyber.cyber(color=None, run_at_end=True)
|
183
|
+
if "|" in argparts:
|
184
|
+
pipeidx = argparts.index("|")
|
185
|
+
argparts, pipeparts = argparts[:pipeidx], argparts[pipeidx + 1 :]
|
186
|
+
try:
|
187
|
+
with build_pipe_stdout(pipeparts) as pipe_stdin:
|
188
|
+
return func(argparts, pipe_stdin)
|
189
|
+
except OSError as e:
|
190
|
+
# in case of a failure in a subprocess
|
191
|
+
print(e)
|
192
|
+
else:
|
193
|
+
ctx = contextlib.nullcontext()
|
194
|
+
if self.target.props.get("cyber") and not no_cyber:
|
195
|
+
ctx = cyber.cyber(color=None, run_at_end=True)
|
196
196
|
|
197
|
-
|
198
|
-
|
199
|
-
except IOError:
|
200
|
-
pass
|
197
|
+
with ctx:
|
198
|
+
return func(argparts, sys.stdout)
|
201
199
|
|
202
200
|
def _exec_command(self, command: str, command_args_str: str) -> Optional[bool]:
|
203
201
|
"""Command execution helper for ``cmd_`` commands."""
|
@@ -279,6 +277,14 @@ class TargetCmd(cmd.Cmd):
|
|
279
277
|
"""exit shell"""
|
280
278
|
return True
|
281
279
|
|
280
|
+
def do_debug(self, line: str) -> Optional[bool]:
|
281
|
+
"""toggle debug mode"""
|
282
|
+
self.debug = not self.debug
|
283
|
+
if self.debug:
|
284
|
+
print("Debug mode on")
|
285
|
+
else:
|
286
|
+
print("Debug mode off")
|
287
|
+
|
282
288
|
|
283
289
|
class TargetHubCli(cmd.Cmd):
|
284
290
|
"""Hub Cli for interacting with multiple targets."""
|
@@ -1241,7 +1247,12 @@ def run_cli(cli: cmd.Cmd) -> None:
|
|
1241
1247
|
print()
|
1242
1248
|
pass
|
1243
1249
|
except Exception as e:
|
1244
|
-
|
1250
|
+
if cli.debug:
|
1251
|
+
log.exception(e)
|
1252
|
+
else:
|
1253
|
+
log.info(e)
|
1254
|
+
print(f"*** Unhandled error: {e}")
|
1255
|
+
print("If you wish to see the full debug trace, enable debug mode.")
|
1245
1256
|
pass
|
1246
1257
|
|
1247
1258
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: dissect.target
|
3
|
-
Version: 3.18.
|
3
|
+
Version: 3.18.dev4
|
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
|
@@ -243,7 +243,7 @@ dissect/target/plugins/os/unix/locate/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCe
|
|
243
243
|
dissect/target/plugins/os/unix/locate/gnulocate.py,sha256=P-YbMFw901p2EBgTaZH6axShfIRRDrCx3APBy6Ii3lE,2934
|
244
244
|
dissect/target/plugins/os/unix/locate/locate.py,sha256=uXFcWAqoz_3eNWHhsGoEtkkhmT5J3F1GYvr4uQxi308,122
|
245
245
|
dissect/target/plugins/os/unix/locate/mlocate.py,sha256=DhrFgxDQF-fMZaA0WK8Z-5o9i9iDsuTHW7MHJtWwz6o,4485
|
246
|
-
dissect/target/plugins/os/unix/locate/plocate.py,sha256=
|
246
|
+
dissect/target/plugins/os/unix/locate/plocate.py,sha256=ShU-F9_31rGfMYXqaR_KrHXVxgDDRZMJ_zEMuekw57w,7229
|
247
247
|
dissect/target/plugins/os/unix/log/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
248
248
|
dissect/target/plugins/os/unix/log/atop.py,sha256=DdiTf-gVJJvvPbR36khU4388lxQzABaWI-95jLCGgSw,16345
|
249
249
|
dissect/target/plugins/os/unix/log/audit.py,sha256=OjorWTmCFvCI5RJq6m6WNW0Lhb-poB2VAggKOGZUHK4,3722
|
@@ -326,7 +326,7 @@ dissect/target/tools/logging.py,sha256=5ZnumtMWLyslxfrUGZ4ntRyf3obOOhmn8SBjKfdLc
|
|
326
326
|
dissect/target/tools/mount.py,sha256=L_0tSmiBdW4aSaF0vXjB0bAkTC0kmT2N1hrbW6s5Jow,3254
|
327
327
|
dissect/target/tools/query.py,sha256=ONHu2FVomLccikb84qBrlhNmEfRoHYFQMcahk_y2c9A,15580
|
328
328
|
dissect/target/tools/reg.py,sha256=FDsiBBDxjWVUBTRj8xn82vZe-J_d9piM-TKS3PHZCcM,3193
|
329
|
-
dissect/target/tools/shell.py,sha256=
|
329
|
+
dissect/target/tools/shell.py,sha256=1Z-gYRlJu0rmFI20taatlofrvp52ac_arXG8AMhwj0w,45182
|
330
330
|
dissect/target/tools/utils.py,sha256=sQizexY3ui5vmWw4KOBLg5ecK3TPFjD-uxDqRn56ZTY,11304
|
331
331
|
dissect/target/tools/dump/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
332
332
|
dissect/target/tools/dump/run.py,sha256=aD84peRS4zHqC78fH7Vd4ni3m1ZmVP70LyMwBRvoDGY,9463
|
@@ -340,10 +340,10 @@ dissect/target/volumes/luks.py,sha256=OmCMsw6rCUXG1_plnLVLTpsvE1n_6WtoRUGQbpmu1z
|
|
340
340
|
dissect/target/volumes/lvm.py,sha256=wwQVR9I3G9YzmY6UxFsH2Y4MXGBcKL9aayWGCDTiWMU,2269
|
341
341
|
dissect/target/volumes/md.py,sha256=j1K1iKmspl0C_OJFc7-Q1BMWN2OCC5EVANIgVlJ_fIE,1673
|
342
342
|
dissect/target/volumes/vmfs.py,sha256=-LoUbn9WNwTtLi_4K34uV_-wDw2W5hgaqxZNj4UmqAQ,1730
|
343
|
-
dissect.target-3.18.
|
344
|
-
dissect.target-3.18.
|
345
|
-
dissect.target-3.18.
|
346
|
-
dissect.target-3.18.
|
347
|
-
dissect.target-3.18.
|
348
|
-
dissect.target-3.18.
|
349
|
-
dissect.target-3.18.
|
343
|
+
dissect.target-3.18.dev4.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
|
344
|
+
dissect.target-3.18.dev4.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
|
345
|
+
dissect.target-3.18.dev4.dist-info/METADATA,sha256=gk5V6v0uboLj95v64bfrxLe_sT7-fksU2GJTOvRXBfE,11299
|
346
|
+
dissect.target-3.18.dev4.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
347
|
+
dissect.target-3.18.dev4.dist-info/entry_points.txt,sha256=tvFPa-Ap-gakjaPwRc6Fl6mxHzxEZ_arAVU-IUYeo_s,447
|
348
|
+
dissect.target-3.18.dev4.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
|
349
|
+
dissect.target-3.18.dev4.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|