dissect.target 3.20.dev41__py3-none-any.whl → 3.20.dev43__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/general/loaders.py +18 -5
- dissect/target/plugins/general/plugins.py +50 -11
- dissect/target/tools/query.py +15 -6
- {dissect.target-3.20.dev41.dist-info → dissect.target-3.20.dev43.dist-info}/METADATA +1 -1
- {dissect.target-3.20.dev41.dist-info → dissect.target-3.20.dev43.dist-info}/RECORD +10 -10
- {dissect.target-3.20.dev41.dist-info → dissect.target-3.20.dev43.dist-info}/COPYRIGHT +0 -0
- {dissect.target-3.20.dev41.dist-info → dissect.target-3.20.dev43.dist-info}/LICENSE +0 -0
- {dissect.target-3.20.dev41.dist-info → dissect.target-3.20.dev43.dist-info}/WHEEL +0 -0
- {dissect.target-3.20.dev41.dist-info → dissect.target-3.20.dev43.dist-info}/entry_points.txt +0 -0
- {dissect.target-3.20.dev41.dist-info → dissect.target-3.20.dev43.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,8 @@
|
|
1
|
+
import json
|
2
|
+
|
1
3
|
from dissect.target.helpers.docs import INDENT_STEP, get_docstring
|
2
4
|
from dissect.target.loader import LOADERS_BY_SCHEME
|
3
|
-
from dissect.target.plugin import Plugin, export
|
5
|
+
from dissect.target.plugin import Plugin, arg, export
|
4
6
|
|
5
7
|
|
6
8
|
class LoaderListPlugin(Plugin):
|
@@ -10,7 +12,12 @@ class LoaderListPlugin(Plugin):
|
|
10
12
|
pass
|
11
13
|
|
12
14
|
@export(output="none")
|
13
|
-
|
15
|
+
# NOTE: We would prefer to re-use arguments across plugins from argparse in query.py, but that is not possible yet.
|
16
|
+
# For now we use --as-json, but in the future this should be changed to inherit --json from target-query.
|
17
|
+
# https://github.com/fox-it/dissect.target/pull/841
|
18
|
+
# https://github.com/fox-it/dissect.target/issues/889
|
19
|
+
@arg("--as-json", dest="as_json", action="store_true")
|
20
|
+
def loaders(self, as_json: bool = False) -> None:
|
14
21
|
"""List the available loaders."""
|
15
22
|
|
16
23
|
loaders_info = {}
|
@@ -21,6 +28,12 @@ class LoaderListPlugin(Plugin):
|
|
21
28
|
except ImportError:
|
22
29
|
continue
|
23
30
|
|
24
|
-
|
25
|
-
|
26
|
-
|
31
|
+
loaders = sorted(loaders_info.items())
|
32
|
+
|
33
|
+
if as_json:
|
34
|
+
print(json.dumps([{"name": name, "description": desc} for name, desc in loaders]), end="")
|
35
|
+
|
36
|
+
else:
|
37
|
+
print("Available loaders:")
|
38
|
+
for loader_name, loader_description in loaders:
|
39
|
+
print(f"{INDENT_STEP}{loader_name} - {loader_description}")
|
@@ -1,5 +1,8 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import json
|
1
4
|
import textwrap
|
2
|
-
from typing import
|
5
|
+
from typing import Iterator, Type
|
3
6
|
|
4
7
|
from dissect.target import plugin
|
5
8
|
from dissect.target.helpers.docs import INDENT_STEP, get_plugin_overview
|
@@ -23,7 +26,8 @@ def categorize_plugins(plugins_selection: list[dict] = None) -> dict:
|
|
23
26
|
return output_dict
|
24
27
|
|
25
28
|
|
26
|
-
def get_exported_plugins():
|
29
|
+
def get_exported_plugins() -> list:
|
30
|
+
"""Returns list of exported plugins."""
|
27
31
|
return [p for p in plugin.plugins() if len(p["exports"])]
|
28
32
|
|
29
33
|
|
@@ -50,10 +54,10 @@ def update_dict_recursive(source_dict: dict, updated_dict: dict) -> dict:
|
|
50
54
|
|
51
55
|
|
52
56
|
def output_plugin_description_recursive(
|
53
|
-
structure_dict:
|
57
|
+
structure_dict: dict | Plugin,
|
54
58
|
print_docs: bool,
|
55
|
-
indentation_step=0,
|
56
|
-
) ->
|
59
|
+
indentation_step: int = 0,
|
60
|
+
) -> list[str]:
|
57
61
|
"""Create plugin overview with identations."""
|
58
62
|
|
59
63
|
if isinstance(structure_dict, type) and issubclass(structure_dict, Plugin):
|
@@ -78,10 +82,10 @@ def get_plugin_description(
|
|
78
82
|
|
79
83
|
|
80
84
|
def get_description_dict(
|
81
|
-
structure_dict:
|
85
|
+
structure_dict: dict,
|
82
86
|
print_docs: bool,
|
83
87
|
indentation_step: int,
|
84
|
-
) ->
|
88
|
+
) -> list[str]:
|
85
89
|
"""Returns a list of indented descriptions."""
|
86
90
|
|
87
91
|
output_descriptions = []
|
@@ -105,10 +109,17 @@ class PluginListPlugin(Plugin):
|
|
105
109
|
|
106
110
|
@export(output="none", cache=False)
|
107
111
|
@arg("--docs", dest="print_docs", action="store_true")
|
108
|
-
|
109
|
-
|
112
|
+
# NOTE: We would prefer to re-use arguments across plugins from argparse in query.py, but that is not possible yet.
|
113
|
+
# For now we use --as-json, but in the future this should be changed to inherit --json from target-query.
|
114
|
+
# https://github.com/fox-it/dissect.target/pull/841
|
115
|
+
# https://github.com/fox-it/dissect.target/issues/889
|
116
|
+
@arg("--as-json", dest="as_json", action="store_true")
|
117
|
+
def plugins(self, plugins: list[Plugin] = None, print_docs: bool = False, as_json: bool = False) -> None:
|
118
|
+
"""Print all available plugins."""
|
119
|
+
|
120
|
+
dict_plugins = list({p.path: p.plugin_desc for p in plugins}.values())
|
121
|
+
categorized_plugins = dict(sorted(categorize_plugins(dict_plugins).items()))
|
110
122
|
|
111
|
-
categorized_plugins = dict(sorted(categorize_plugins(plugins).items()))
|
112
123
|
plugin_descriptions = output_plugin_description_recursive(categorized_plugins, print_docs)
|
113
124
|
|
114
125
|
plugins_list = textwrap.indent(
|
@@ -142,4 +153,32 @@ class PluginListPlugin(Plugin):
|
|
142
153
|
"Failed to load:",
|
143
154
|
failed_list,
|
144
155
|
]
|
145
|
-
|
156
|
+
|
157
|
+
if as_json:
|
158
|
+
out = {"loaded": list(generate_plugins_json(plugins))}
|
159
|
+
|
160
|
+
if failed_plugins := plugin.failed():
|
161
|
+
out["failed"] = [
|
162
|
+
{"module": p["module"], "stacktrace": "".join(p["stacktrace"])} for p in failed_plugins
|
163
|
+
]
|
164
|
+
|
165
|
+
print(json.dumps(out), end="")
|
166
|
+
|
167
|
+
else:
|
168
|
+
print("\n".join(output_lines))
|
169
|
+
|
170
|
+
|
171
|
+
def generate_plugins_json(plugins: list[Plugin]) -> Iterator[dict]:
|
172
|
+
"""Generates JSON output of a list of :class:`Plugin`s."""
|
173
|
+
|
174
|
+
for p in plugins:
|
175
|
+
func = getattr(p.class_object, p.method_name)
|
176
|
+
description = getattr(func, "__doc__", None)
|
177
|
+
summary = description.split("\n\n", 1)[0].strip() if description else None
|
178
|
+
|
179
|
+
yield {
|
180
|
+
"name": p.name,
|
181
|
+
"output": p.output_type,
|
182
|
+
"description": summary,
|
183
|
+
"path": p.path,
|
184
|
+
}
|
dissect/target/tools/query.py
CHANGED
@@ -169,31 +169,40 @@ def main():
|
|
169
169
|
# Show the list of available plugins for the given optional target and optional
|
170
170
|
# search pattern, only display plugins that can be applied to ANY targets
|
171
171
|
if args.list:
|
172
|
-
collected_plugins =
|
172
|
+
collected_plugins = []
|
173
173
|
|
174
174
|
if targets:
|
175
175
|
for plugin_target in Target.open_all(targets, args.children):
|
176
176
|
funcs, _ = find_plugin_functions(plugin_target, args.list, compatibility=True, show_hidden=True)
|
177
177
|
for func in funcs:
|
178
|
-
collected_plugins
|
178
|
+
collected_plugins.append(func)
|
179
179
|
else:
|
180
180
|
funcs, _ = find_plugin_functions(Target(), args.list, compatibility=False, show_hidden=True)
|
181
181
|
for func in funcs:
|
182
|
-
collected_plugins
|
182
|
+
collected_plugins.append(func)
|
183
183
|
|
184
|
-
# Display in a user friendly manner
|
185
184
|
target = Target()
|
186
185
|
fparser = generate_argparse_for_bound_method(target.plugins, usage_tmpl=USAGE_FORMAT_TMPL)
|
187
186
|
fargs, rest = fparser.parse_known_args(rest)
|
188
187
|
|
188
|
+
# Display in a user friendly manner
|
189
189
|
if collected_plugins:
|
190
|
-
|
190
|
+
if args.json:
|
191
|
+
print('{"plugins": ', end="")
|
192
|
+
target.plugins(collected_plugins, as_json=args.json)
|
191
193
|
|
192
194
|
# No real targets specified, show the available loaders
|
193
195
|
if not targets:
|
194
196
|
fparser = generate_argparse_for_bound_method(target.loaders, usage_tmpl=USAGE_FORMAT_TMPL)
|
195
197
|
fargs, rest = fparser.parse_known_args(rest)
|
196
|
-
|
198
|
+
del fargs.as_json
|
199
|
+
if args.json:
|
200
|
+
print(', "loaders": ', end="")
|
201
|
+
target.loaders(**vars(fargs), as_json=args.json)
|
202
|
+
|
203
|
+
if args.json:
|
204
|
+
print("}")
|
205
|
+
|
197
206
|
parser.exit()
|
198
207
|
|
199
208
|
if not targets:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: dissect.target
|
3
|
-
Version: 3.20.
|
3
|
+
Version: 3.20.dev43
|
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
|
@@ -186,10 +186,10 @@ dissect/target/plugins/general/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5
|
|
186
186
|
dissect/target/plugins/general/config.py,sha256=Mdy9uhWn4OJ96zfXpLgjVifV5SrViqHnpSnKhC1mjZE,3432
|
187
187
|
dissect/target/plugins/general/default.py,sha256=8W_9JV3jKEeETlyTrB25sACoIIFmmO8wlVU5Zoi51W0,1425
|
188
188
|
dissect/target/plugins/general/example.py,sha256=mYAbhtfQmUBj2L2C1DFt9bWpI7rQLJwCIYUsNLcA_pc,6053
|
189
|
-
dissect/target/plugins/general/loaders.py,sha256=
|
189
|
+
dissect/target/plugins/general/loaders.py,sha256=z_t55Q1XNjmTOxq0E4tCwpZ-utFyxiLKyAJIFgJMlJs,1508
|
190
190
|
dissect/target/plugins/general/network.py,sha256=J8aMfUJ7dgwqpaXzZpHHyOUYg-cPef2Qaa3krUj-A-Q,3225
|
191
191
|
dissect/target/plugins/general/osinfo.py,sha256=oU-vmMiA-oaSEQWTSyn6-yQiH2sLQT6aTQHRd0677wo,1415
|
192
|
-
dissect/target/plugins/general/plugins.py,sha256=
|
192
|
+
dissect/target/plugins/general/plugins.py,sha256=9KJ70YvYwBfxt19C9yISv8YE4mOdHNvP16fTCTHC68U,6033
|
193
193
|
dissect/target/plugins/general/scrape.py,sha256=Fz7BNXflvuxlnVulyyDhLpyU8D_hJdH6vWVtER9vjTg,6651
|
194
194
|
dissect/target/plugins/general/users.py,sha256=yy9gvRXfN9BT71v4Xqo5hpwfgN9he9Otu8TBPZ_Tegs,3009
|
195
195
|
dissect/target/plugins/os/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -356,7 +356,7 @@ dissect/target/tools/fsutils.py,sha256=q0t9gFwKHaPr2Ya-MN2o4LsYledde7kp2DZZTd8ro
|
|
356
356
|
dissect/target/tools/info.py,sha256=8nnbqFUYeo4NLPE7ORcTBcDL-TioGB2Nqc1TKcu5qdY,5715
|
357
357
|
dissect/target/tools/logging.py,sha256=5ZnumtMWLyslxfrUGZ4ntRyf3obOOhmn8SBjKfdLcEg,4174
|
358
358
|
dissect/target/tools/mount.py,sha256=8GRYnu4xEmFBHxuIZAYhOMyyTGX8fat1Ou07DNiUnW4,3945
|
359
|
-
dissect/target/tools/query.py,sha256=
|
359
|
+
dissect/target/tools/query.py,sha256=OYWVmCx2nFx85x1r8Y6D17UdUIi8PJm304xBfT-H8vs,15605
|
360
360
|
dissect/target/tools/reg.py,sha256=FDsiBBDxjWVUBTRj8xn82vZe-J_d9piM-TKS3PHZCcM,3193
|
361
361
|
dissect/target/tools/shell.py,sha256=qY-JIwFQKBHTbqOiFxeO9OYeOlesQlx0r8PHghSAV8I,54207
|
362
362
|
dissect/target/tools/utils.py,sha256=JJZDSso1CEK2sv4Z3HJNgqxH6G9S5lbmV-C3h-XmcMo,12035
|
@@ -373,10 +373,10 @@ dissect/target/volumes/luks.py,sha256=OmCMsw6rCUXG1_plnLVLTpsvE1n_6WtoRUGQbpmu1z
|
|
373
373
|
dissect/target/volumes/lvm.py,sha256=wwQVR9I3G9YzmY6UxFsH2Y4MXGBcKL9aayWGCDTiWMU,2269
|
374
374
|
dissect/target/volumes/md.py,sha256=7ShPtusuLGaIv27SvEETtgsuoQyAa4iAAeOR1NEaajI,1689
|
375
375
|
dissect/target/volumes/vmfs.py,sha256=-LoUbn9WNwTtLi_4K34uV_-wDw2W5hgaqxZNj4UmqAQ,1730
|
376
|
-
dissect.target-3.20.
|
377
|
-
dissect.target-3.20.
|
378
|
-
dissect.target-3.20.
|
379
|
-
dissect.target-3.20.
|
380
|
-
dissect.target-3.20.
|
381
|
-
dissect.target-3.20.
|
382
|
-
dissect.target-3.20.
|
376
|
+
dissect.target-3.20.dev43.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
|
377
|
+
dissect.target-3.20.dev43.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
|
378
|
+
dissect.target-3.20.dev43.dist-info/METADATA,sha256=FO2hxtOkklCzr7ZrCmD1SeMtL5Dqy8jufOSQFRUQVRY,12897
|
379
|
+
dissect.target-3.20.dev43.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
380
|
+
dissect.target-3.20.dev43.dist-info/entry_points.txt,sha256=BWuxAb_6AvUAQpIQOQU0IMTlaF6TDht2AIZK8bHd-zE,492
|
381
|
+
dissect.target-3.20.dev43.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
|
382
|
+
dissect.target-3.20.dev43.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
{dissect.target-3.20.dev41.dist-info → dissect.target-3.20.dev43.dist-info}/entry_points.txt
RENAMED
File without changes
|
File without changes
|