11
11
from functools import wraps
12
12
from typing import Any , Callable , Dict , List , Tuple
13
13
14
- from volatility3 .framework import interfaces , renderers
14
+ from volatility3 .framework import exceptions , interfaces , renderers
15
15
from volatility3 .framework .renderers import format_hints
16
16
17
17
vollog = logging .getLogger (__name__ )
@@ -135,6 +135,22 @@ class CLIRenderer(interfaces.renderers.Renderer):
135
135
name = "unnamed"
136
136
structured_output = False
137
137
138
+ column_output_list : list = None
139
+
140
+ def ignore_columns (
141
+ self ,
142
+ column : interfaces .renderers .Column ,
143
+ ignored_columns : List [interfaces .renderers .Column ],
144
+ ) -> Tuple [List [interfaces .renderers .Column ], Any ]:
145
+ if self .column_output_list :
146
+ accept = False
147
+ for column_prefix in self .column_output_list :
148
+ if column .name .lower ().startswith (column_prefix .lower ()):
149
+ accept = True
150
+ if not accept :
151
+ ignored_columns .append (column )
152
+ return ignored_columns
153
+
138
154
139
155
class QuickTextRenderer (CLIRenderer ):
140
156
_type_renderers = {
@@ -166,9 +182,15 @@ def render(self, grid: interfaces.renderers.TreeGrid) -> None:
166
182
outfd = sys .stdout
167
183
168
184
line = []
185
+ ignored_columns = []
169
186
for column in grid .columns :
170
187
# Ignore the type because namedtuples don't realize they have accessible attributes
171
- line .append (f"{ column .name } " )
188
+ ignored_columns = self .ignore_columns (column , ignored_columns )
189
+ if column not in ignored_columns :
190
+ line .append (f"column.name" )
191
+
192
+ if not line :
193
+ raise exceptions .RenderException ("No visible columns" )
172
194
outfd .write ("\n {}\n " .format ("\t " .join (line )))
173
195
174
196
def visitor (node : interfaces .renderers .TreeNode , accumulator ):
@@ -184,7 +206,8 @@ def visitor(node: interfaces.renderers.TreeNode, accumulator):
184
206
renderer = self ._type_renderers .get (
185
207
column .type , self ._type_renderers ["default" ]
186
208
)
187
- line .append (renderer (node .values [column_index ]))
209
+ if column not in ignored_columns :
210
+ line .append (renderer (node .values [column_index ]))
188
211
accumulator .write ("{}" .format ("\t " .join (line )))
189
212
accumulator .flush ()
190
213
return accumulator
@@ -237,9 +260,12 @@ def render(self, grid: interfaces.renderers.TreeGrid) -> None:
237
260
outfd = sys .stdout
238
261
239
262
header_list = ["TreeDepth" ]
263
+ ignored_columns = []
240
264
for column in grid .columns :
241
265
# Ignore the type because namedtuples don't realize they have accessible attributes
242
- header_list .append (f"{ column .name } " )
266
+ ignored_columns = self .ignore_columns (column , ignored_columns )
267
+ if column not in ignored_columns :
268
+ header_list .append (f"{ column .name } " )
243
269
244
270
writer = csv .DictWriter (
245
271
outfd , header_list , lineterminator = "\n " , escapechar = "\\ "
@@ -254,7 +280,8 @@ def visitor(node: interfaces.renderers.TreeNode, accumulator):
254
280
renderer = self ._type_renderers .get (
255
281
column .type , self ._type_renderers ["default" ]
256
282
)
257
- row [f"{ column .name } " ] = renderer (node .values [column_index ])
283
+ if column not in ignored_columns :
284
+ row [f"{ column .name } " ] = renderer (node .values [column_index ])
258
285
accumulator .writerow (row )
259
286
return accumulator
260
287
@@ -298,6 +325,10 @@ def render(self, grid: interfaces.renderers.TreeGrid) -> None:
298
325
[(column .name , len (column .name )) for column in grid .columns ]
299
326
)
300
327
328
+ ignored_columns = []
329
+ for column in grid .columns :
330
+ ignored_columns = self .ignore_columns (column , ignored_columns )
331
+
301
332
def visitor (
302
333
node : interfaces .renderers .TreeNode ,
303
334
accumulator : List [Tuple [int , Dict [interfaces .renderers .Column , bytes ]]],
@@ -306,6 +337,7 @@ def visitor(
306
337
max_column_widths [tree_indent_column ] = max (
307
338
max_column_widths .get (tree_indent_column , 0 ), node .path_depth
308
339
)
340
+
309
341
line = {}
310
342
for column_index in range (len (grid .columns )):
311
343
column = grid .columns [column_index ]
@@ -319,7 +351,8 @@ def visitor(
319
351
max_column_widths [column .name ] = max (
320
352
max_column_widths .get (column .name , len (column .name )), field_width
321
353
)
322
- line [column ] = data .split ("\n " )
354
+ if column not in ignored_columns :
355
+ line [column ] = data .split ("\n " )
323
356
accumulator .append ((node .path_depth , line ))
324
357
return accumulator
325
358
@@ -335,18 +368,21 @@ def visitor(
335
368
]
336
369
for column_index in range (len (grid .columns )):
337
370
column = grid .columns [column_index ]
338
- format_string_list .append (
339
- "{"
340
- + str (column_index + 1 )
341
- + ":"
342
- + display_alignment
343
- + str (max_column_widths [column .name ])
344
- + "s}"
345
- )
371
+ if column not in ignored_columns :
372
+ format_string_list .append (
373
+ "{"
374
+ + str (column_index + 1 )
375
+ + ":"
376
+ + display_alignment
377
+ + str (max_column_widths [column .name ])
378
+ + "s}"
379
+ )
346
380
347
381
format_string = column_separator .join (format_string_list ) + "\n "
348
382
349
- column_titles = ["" ] + [column .name for column in grid .columns ]
383
+ column_titles = ["" ] + [
384
+ column .name for column in grid .columns if column not in ignored_columns
385
+ ]
350
386
outfd .write (format_string .format (* column_titles ))
351
387
for depth , line in final_output :
352
388
nums_line = max ([len (line [column ]) for column in line ])
@@ -357,20 +393,14 @@ def visitor(
357
393
outfd .write (
358
394
format_string .format (
359
395
"*" * depth ,
360
- * [
361
- self .tab_stop (line [column ][index ])
362
- for column in grid .columns
363
- ],
396
+ * [self .tab_stop (line [column ][index ]) for column in line ],
364
397
)
365
398
)
366
399
else :
367
400
outfd .write (
368
401
format_string .format (
369
402
" " * depth ,
370
- * [
371
- self .tab_stop (line [column ][index ])
372
- for column in grid .columns
373
- ],
403
+ * [self .tab_stop (line [column ][index ]) for column in line ],
374
404
)
375
405
)
376
406
@@ -416,6 +446,10 @@ def render(self, grid: interfaces.renderers.TreeGrid):
416
446
List [interfaces .renderers .TreeNode ],
417
447
] = ({}, [])
418
448
449
+ ignored_columns = []
450
+ for column in grid .columns :
451
+ ignored_columns = self .ignore_columns (column , ignored_columns )
452
+
419
453
def visitor (
420
454
node : interfaces .renderers .TreeNode ,
421
455
accumulator : Tuple [Dict [str , Dict [str , Any ]], List [Dict [str , Any ]]],
@@ -425,6 +459,8 @@ def visitor(
425
459
node_dict : Dict [str , Any ] = {"__children" : []}
426
460
for column_index in range (len (grid .columns )):
427
461
column = grid .columns [column_index ]
462
+ if column in ignored_columns :
463
+ continue
428
464
renderer = self ._type_renderers .get (
429
465
column .type , self ._type_renderers ["default" ]
430
466
)
0 commit comments