FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
voltron/voltron/plugin.py at master · Python-Repository-Hub/voltron · GitHub
Python-Repository-Hub
/
voltron
Public
forked from
snare/voltron
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Pull requests
0
Projects
Security and quality
0
Insights
Additional navigation options
Code
Pull requests
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
voltron
/
voltron
/
plugin.py
Copy path
More file actions
More file actions
Latest commit
History
History
History
363 lines (290 loc) · 11.1 KB
Breadcrumbs
voltron
/
voltron
/
plugin.py
Copy path
File metadata and controls
363 lines (290 loc) · 11.1 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
import
logging
import
inspect
import
os
from
collections
import
defaultdict
from
scruffy
.
plugin
import
Plugin
import
voltron
log
=
logging
.
getLogger
(
'plugin'
)
class
PluginManager
(
object
):
"""
Collects and validates API, debugger and view plugins. Provides methods to
access and search the plugin collection.
Plugin loading itself is handled by scruffy, which is configured in the
environment specification in `env.py`.
"""
def
__init__
(
self
):
"""
Initialise a new PluginManager.
"""
self
.
_api_plugins
=
defaultdict
(
lambda
:
None
)
self
.
_debugger_plugins
=
defaultdict
(
lambda
:
None
)
self
.
_view_plugins
=
defaultdict
(
lambda
:
None
)
self
.
_web_plugins
=
defaultdict
(
lambda
:
None
)
self
.
_command_plugins
=
defaultdict
(
lambda
:
None
)
def
register_plugins
(
self
):
for
p
in
voltron
.
env
.
plugins
:
self
.
register_plugin
(
p
)
def
register_command_plugins
(
self
):
for
p
in
voltron
.
env
.
plugins
:
if
issubclass
(
p
,
CommandPlugin
):
self
.
register_plugin
(
p
)
@
property
def
api_plugins
(
self
):
return
self
.
_api_plugins
@
property
def
debugger_plugins
(
self
):
return
self
.
_debugger_plugins
@
property
def
view_plugins
(
self
):
return
self
.
_view_plugins
@
property
def
web_plugins
(
self
):
return
self
.
_web_plugins
@
property
def
command_plugins
(
self
):
return
self
.
_command_plugins
def
register_plugin
(
self
,
plugin
):
"""
Register a new plugin with the PluginManager.
`plugin` is a subclass of scruffy's Plugin class.
This is called by __init__(), but may also be called by the debugger
host to load a specific plugin at runtime.
"""
if
hasattr
(
plugin
,
'initialise'
):
plugin
.
initialise
()
if
self
.
valid_api_plugin
(
plugin
):
log
.
debug
(
"Registering API plugin: {}"
.
format
(
plugin
))
self
.
_api_plugins
[
plugin
.
request
]
=
plugin
()
elif
self
.
valid_debugger_plugin
(
plugin
):
log
.
debug
(
"Registering debugger plugin: {}"
.
format
(
plugin
))
self
.
_debugger_plugins
[
plugin
.
host
]
=
plugin
()
elif
self
.
valid_view_plugin
(
plugin
):
log
.
debug
(
"Registering view plugin: {}"
.
format
(
plugin
))
self
.
_view_plugins
[
plugin
.
name
]
=
plugin
()
elif
self
.
valid_web_plugin
(
plugin
):
log
.
debug
(
"Registering web plugin: {}"
.
format
(
plugin
))
self
.
_web_plugins
[
plugin
.
name
]
=
plugin
()
elif
self
.
valid_command_plugin
(
plugin
):
log
.
debug
(
"Registering command plugin: {}"
.
format
(
plugin
))
self
.
_command_plugins
[
plugin
.
name
]
=
plugin
()
if
voltron
.
debugger
:
voltron
.
debugger
.
register_command_plugin
(
plugin
.
name
,
plugin
.
command_class
)
else
:
log
.
debug
(
"Ignoring invalid plugin: {}"
.
format
(
plugin
))
def
valid_api_plugin
(
self
,
plugin
):
"""
Validate an API plugin, ensuring it is an API plugin and has the
necessary fields present.
`plugin` is a subclass of scruffy's Plugin class.
"""
if
(
issubclass
(
plugin
,
APIPlugin
)
and
hasattr
(
plugin
,
'plugin_type'
)
and
plugin
.
plugin_type
==
'api'
and
hasattr
(
plugin
,
'request'
)
and
plugin
.
request
!=
None
and
hasattr
(
plugin
,
'request_class'
)
and
plugin
.
request_class
!=
None
and
hasattr
(
plugin
,
'response_class'
)
and
plugin
.
response_class
!=
None
):
return
True
return
False
def
valid_debugger_plugin
(
self
,
plugin
):
"""
Validate a debugger plugin, ensuring it is a debugger plugin and has
the necessary fields present.
`plugin` is a subclass of scruffy's Plugin class.
"""
if
(
issubclass
(
plugin
,
DebuggerAdaptorPlugin
)
and
hasattr
(
plugin
,
'plugin_type'
)
and
plugin
.
plugin_type
==
'debugger'
and
hasattr
(
plugin
,
'host'
)
and
plugin
.
host
!=
None
):
return
True
return
False
def
valid_view_plugin
(
self
,
plugin
):
"""
Validate a view plugin, ensuring it is a view plugin and has the
necessary fields present.
`plugin` is a subclass of scruffy's Plugin class.
"""
if
(
issubclass
(
plugin
,
ViewPlugin
)
and
hasattr
(
plugin
,
'plugin_type'
)
and
plugin
.
plugin_type
==
'view'
and
hasattr
(
plugin
,
'name'
)
and
plugin
.
name
!=
None
and
hasattr
(
plugin
,
'view_class'
)
and
plugin
.
view_class
!=
None
):
return
True
return
False
def
valid_web_plugin
(
self
,
plugin
):
"""
Validate a web plugin, ensuring it is a web plugin and has the
necessary fields present.
`plugin` is a subclass of scruffy's Plugin class.
"""
if
(
issubclass
(
plugin
,
WebPlugin
)
and
hasattr
(
plugin
,
'plugin_type'
)
and
plugin
.
plugin_type
==
'web'
and
hasattr
(
plugin
,
'name'
)
and
plugin
.
name
!=
None
):
return
True
return
False
def
valid_command_plugin
(
self
,
plugin
):
"""
Validate a command plugin, ensuring it is a command plugin and has the
necessary fields present.
`plugin` is a subclass of scruffy's Plugin class.
"""
if
(
issubclass
(
plugin
,
CommandPlugin
)
and
hasattr
(
plugin
,
'plugin_type'
)
and
plugin
.
plugin_type
==
'command'
and
hasattr
(
plugin
,
'name'
)
and
plugin
.
name
!=
None
):
return
True
return
False
def
api_plugin_for_request
(
self
,
request
=
None
):
"""
Find an API plugin that supports the given request type.
"""
return
self
.
api_plugins
[
request
]
def
debugger_plugin_for_host
(
self
,
host
=
None
):
"""
Find a debugger plugin that supports the debugger host.
"""
return
self
.
debugger_plugins
[
host
]
def
view_plugin_with_name
(
self
,
name
=
None
):
"""
Find a view plugin that for the given view name.
"""
return
self
.
view_plugins
[
name
]
def
web_plugin_with_name
(
self
,
name
=
None
):
"""
Find a web plugin that for the given view name.
"""
return
self
.
web_plugins
[
name
]
def
command_plugin_with_name
(
self
,
name
=
None
):
"""
Find a command plugin that for the given view name.
"""
return
self
.
command_plugins
[
name
]
class
VoltronPlugin
(
Plugin
):
@
classmethod
def
initialise
(
cls
):
pass
class
APIPlugin
(
VoltronPlugin
):
"""
Abstract API plugin class. API plugins subclass this.
`plugin_type` is 'api'
`request` is the request type (e.g. 'version')
`request_class` is the APIRequest subclass (e.g. APIVersionRequest)
`response_class` is the APIResponse subclass (e.g. APIVersionResponse)
`supported_hosts` is an array of debugger adaptor plugins that this plugin
supports (e.g. 'lldb', 'gdb'). There is also a special host type called
'core' If the plugin requires only the 'core' debugger host, it can be used
with any debugger adaptor plugin that implements the full interface (ie.
the included 'lldb' and 'gdb' plugins). If it requires a specifically named
debugger host plugin, then it will only work with those plugins specified.
This allows developers to add custom API plugins that communicate directly
with their chosen debugger host API, to do things that the standard
debugger adaptor plugins don't support.
See the core API plugins in voltron/plugins/api/ for examples.
"""
plugin_type
=
'api'
request
=
None
request_class
=
None
response_class
=
None
supported_hosts
=
[
'core'
]
@
classmethod
def
initialise
(
cls
):
if
cls
.
request_class
:
cls
.
request_class
.
_plugin
=
cls
cls
.
request_class
.
request
=
cls
.
request
class
DebuggerAdaptorPlugin
(
VoltronPlugin
):
"""
Debugger adaptor plugin parent class.
`plugin_type` is 'debugger'
`host` is the name of the debugger host (e.g. 'lldb' or 'gdb')
`adaptor_class` is the debugger adaptor class that can be queried
See the core debugger plugins in voltron/plugins/debugger/ for examples.
"""
plugin_type
=
'debugger'
host
=
None
adaptor_class
=
None
supported_hosts
=
[
'core'
]
@
classmethod
def
initialise
(
cls
):
if
cls
.
adaptor_class
:
cls
.
adaptor_class
.
_plugin
=
cls
class
ViewPlugin
(
VoltronPlugin
):
"""
View plugin parent class.
`plugin_type` is 'view'
`name` is the name of the view (e.g. 'register' or 'disassembly')
`view_class` is the main view class
See the core view plugins in voltron/plugins/view/ for examples.
"""
plugin_type
=
'view'
name
=
None
view_class
=
None
@
classmethod
def
initialise
(
cls
):
if
cls
.
view_class
:
cls
.
view_class
.
_plugin
=
cls
cls
.
view_class
.
view_type
=
cls
.
name
class
WebPlugin
(
VoltronPlugin
):
"""
Web plugin parent class.
`plugin_type` is 'web'
`name` is the name of the web plugin (e.g. 'webview')
`app` is a Flask app (or whatever, optional)
"""
_dir
=
None
plugin_type
=
'web'
name
=
None
app
=
None
def
__init__
(
self
):
self
.
_dir
=
os
.
path
.
dirname
(
inspect
.
getfile
(
self
.
__class__
))
class
CommandPlugin
(
VoltronPlugin
):
"""
Command plugin parent class.
`plugin_type` is 'command'
`name` is the name of the command plugin
"""
plugin_type
=
'command'
name
=
None
class
VoltronCommand
(
object
):
pass
#
# Shared plugin manager and convenience methods
#
pm
=
PluginManager
()
def
api_request
(
request
,
*
args
,
**
kwargs
):
"""
Create an API request.
`request_type` is the request type (string). This is used to look up a
plugin, whose request class is instantiated and passed the remaining
arguments passed to this function.
"""
plugin
=
pm
.
api_plugin_for_request
(
request
)
if
plugin
and
plugin
.
request_class
:
req
=
plugin
.
request_class
(
*
args
,
**
kwargs
)
else
:
raise
Exception
(
"Invalid request type"
)
return
req
def
api_response
(
request
,
*
args
,
**
kwargs
):
plugin
=
pm
.
api_plugin_for_request
(
request
)
if
plugin
and
plugin
.
response_class
:
req
=
plugin
.
response_class
(
*
args
,
**
kwargs
)
else
:
raise
Exception
(
"Invalid request type"
)
return
req
def
debugger_adaptor
(
host
,
*
args
,
**
kwargs
):
plugin
=
pm
.
debugger_plugin_for_host
(
host
)
if
plugin
and
plugin
.
adaptor_class
:
adaptor
=
plugin
.
adaptor_class
(
*
args
,
**
kwargs
)
else
:
raise
Exception
(
"Invalid debugger host"
)
return
adaptor
def
view
(
name
,
*
args
,
**
kwargs
):
plugin
=
pm
.
view_plugin_with_name
(
name
)
if
plugin
and
plugin
.
view_class
:
view
=
plugin
.
view_class
(
*
args
,
**
kwargs
)
else
:
raise
Exception
(
"Invalid view name"
)
return
view
def
command
(
name
,
*
args
,
**
kwargs
):
plugin
=
pm
.
command_plugin_with_name
(
name
)
if
plugin
and
plugin
.
command_class
:
command
=
plugin
.
command_class
(
*
args
,
**
kwargs
)
else
:
raise
Exception
(
"Invalid command name"
)
return
command
def
web_plugins
():
return
pm
.
web_plugins
Back
|
FazBrowse Home
|
New Git URL