Improve volshell: aliases and mode

This commit is contained in:
Mike Auty
2019-09-23 21:41:35 +01:00
parent 5a0957a301
commit 575463e69e
5 changed files with 60 additions and 69 deletions
+3 -3
View File
@@ -13,7 +13,7 @@ import volatility.plugins
import volatility.symbols
from volatility import cli, framework
from volatility.cli import text_renderer
from volatility.cli.volshell import shellplugin, windows, linux, mac
from volatility.cli.volshell import generic, windows, linux, mac
from volatility.framework import automagic, constants, contexts, exceptions, interfaces, plugins
# Make sure we log everything
@@ -145,7 +145,7 @@ class VolShell(cli.CommandLine):
configurables_list[amagic.__class__.__name__] = amagic
# We don't list plugin arguments, because they can be provided within python
volshell_plugin_list = {'generic': shellplugin.Volshell, 'windows': windows.Volshell}
volshell_plugin_list = {'generic': generic.Volshell, 'windows': windows.Volshell}
for plugin in volshell_plugin_list:
subparser = parser.add_argument_group(title = plugin.capitalize(),
description = "Configuration options based on {} options".format(
@@ -163,7 +163,7 @@ class VolShell(cli.CommandLine):
vollog.log(constants.LOGLEVEL_VVV, "Cache directory used: {}".format(constants.CACHE_PATH))
plugin = shellplugin.Volshell
plugin = generic.Volshell
if args.windows:
plugin = windows.Volshell
if args.linux:
@@ -5,7 +5,7 @@ import binascii
import code
import struct
import sys
from typing import Any, Dict, List, Optional
from typing import Any, Dict, List, Optional, Tuple
from volatility.framework import renderers, interfaces
from volatility.framework.configuration import requirements
@@ -50,15 +50,25 @@ class Volshell(interfaces.plugins.PluginInterface):
pass
else:
import rlcompleter
completer = rlcompleter.Completer(namespace = self.construct_locals())
completer = rlcompleter.Completer(namespace = self._construct_locals_dict())
readline.set_completer(completer.complete)
readline.parse_and_bind("tab: complete")
print("Readline imported successfully")
# TODO: provide help, consider generic functions (pslist?) and/or providing windows/linux functions
mode = self.__module__.split('.')[-1]
mode = mode[0].upper() + mode[1:]
banner = """
Call help() to see available functions
Volshell mode: {}
Current Layer: {}
""".format(mode, self.current_layer)
sys.ps1 = "({}) >>> ".format(self.current_layer)
code.interact(banner = "\nCall help() to see available functions\n", local = self.construct_locals())
code.interact(banner = banner, local = self._construct_locals_dict())
return renderers.TreeGrid([("Terminating", str)], None)
@@ -66,7 +76,8 @@ class Volshell(interfaces.plugins.PluginInterface):
"""Describes the available commands"""
variables = []
print("\nMethods:")
for name, item in self.construct_locals().items():
for aliases, item in self.construct_locals():
name = ", ".join(aliases)
if item.__doc__ and callable(item):
print("* {}".format(name))
print(" {}".format(item.__doc__))
@@ -77,29 +88,23 @@ class Volshell(interfaces.plugins.PluginInterface):
for var in variables:
print(" {}".format(var))
def construct_locals(self) -> Dict[str, Any]:
def construct_locals(self) -> List[Tuple[List[str], Any]]:
"""Returns a dictionary listing the functions to be added to the
environment."""
return {
'dt': self.display_type,
'display_type': self.display_type,
'db': self.display_bytes,
'display_bytes': self.display_bytes,
'dw': self.display_words,
'display_words': self.display_words,
'dd': self.display_doublewords,
'display_doublewords': self.display_doublewords,
'dq': self.display_quadwords,
'display_quadwords': self.display_quadwords,
'dis': self.disassemble,
'disassemble': self.disassemble,
'cl': self.change_layer,
'change_layer': self.change_layer,
'context': self.context,
'self': self,
'hh': self.help,
'help': self.help,
}
return [(['dt', 'display_type'], self.display_type), (['db', 'display_bytes'], self.display_bytes),
(['dw', 'display_words'], self.display_words), (['dd',
'display_doublewords'], self.display_doublewords),
(['dq', 'display_quadwords'], self.display_quadwords), (['dis', 'disassemble'], self.disassemble),
(['cl', 'change_layer'], self.change_layer), (['context'], self.context), (['self'], self),
(['hh', 'help'], self.help)]
def _construct_locals_dict(self) -> Dict[str, Any]:
"""Returns a dictionary of the locals """
result = {}
for aliases, value in self.construct_locals():
for alias in aliases:
result[alias] = value
return result
def _read_data(self, offset, count = 128, layer_name = None):
"""Reads the bytes necessary for the display_* methods"""
+9 -14
View File
@@ -2,14 +2,14 @@
# which is available at https://www.volatilityfoundation.org/license/vsl_v1.0
#
from typing import Dict, Any
from typing import Any, List, Tuple
from volatility.cli.volshell import shellplugin
from volatility.cli.volshell import generic
from volatility.framework.configuration import requirements
from volatility.plugins.linux import pslist
class Volshell(shellplugin.Volshell):
class Volshell(generic.Volshell):
"""Shell environment to directly interact with a linux memory image."""
@classmethod
@@ -38,18 +38,13 @@ class Volshell(shellplugin.Volshell):
# We always use the main kernel memory and associated symbols
return list(pslist.PsList.list_tasks(self.context, self.config['primary'], self.config['vmlinux']))
def construct_locals(self) -> Dict[str, Any]:
def construct_locals(self) -> List[Tuple[List[str], Any]]:
result = super().construct_locals()
result.update({
'ct': self.change_task,
'change_task': self.change_task,
'lt': self.list_tasks,
'list_tasks': self.list_tasks,
'symbols': self.context.symbol_space[self.config['vmlinux']],
# windows/windbg compatibility aliases
'cp': self.change_task,
'ps': self.list_tasks,
})
result += [
(['ct', 'change_task', 'cp'], self.change_task),
(['lt', 'list_tasks', 'ps'], self.list_tasks),
(['symbols'], self.context.symbol_space[self.config['vmlinux']]),
]
if self.config.get('pid', None) is not None:
self.change_task(self.config['pid'])
return result
+9 -14
View File
@@ -2,14 +2,14 @@
# which is available at https://www.volatilityfoundation.org/license/vsl_v1.0
#
from typing import Dict, Any
from typing import Any, List, Tuple
from volatility.cli.volshell import shellplugin
from volatility.cli.volshell import generic
from volatility.framework.configuration import requirements
from volatility.plugins.mac import pslist
class Volshell(shellplugin.Volshell):
class Volshell(generic.Volshell):
"""Shell environment to directly interact with a mac memory image."""
@classmethod
@@ -38,18 +38,13 @@ class Volshell(shellplugin.Volshell):
# We always use the main kernel memory and associated symbols
return list(pslist.PsList.list_tasks(self.context, self.config['primary'], self.config['darwin']))
def construct_locals(self) -> Dict[str, Any]:
def construct_locals(self) -> List[Tuple[List[str], Any]]:
result = super().construct_locals()
result.update({
'ct': self.change_task,
'change_task': self.change_task,
'lt': self.list_tasks,
'list_tasks': self.list_tasks,
'symbols': self.context.symbol_space[self.config['darwin']],
# windows/windbg compatibility aliases
'cp': self.change_task,
'ps': self.list_tasks,
})
result += [
(['ct', 'change_task', 'cp'], self.change_task),
(['lt', 'list_tasks', 'ps'], self.list_tasks),
(['symbols'], self.context.symbol_space[self.config['darwin']]),
]
if self.config.get('pid', None) is not None:
self.change_task(self.config['pid'])
return result
+9 -13
View File
@@ -2,14 +2,14 @@
# which is available at https://www.volatilityfoundation.org/license/vsl_v1.0
#
from typing import Dict, Any
from typing import Dict, Any, List, Tuple
from volatility.cli.volshell import shellplugin
from volatility.cli.volshell import generic
from volatility.framework.configuration import requirements
from volatility.plugins.windows import pslist
class Volshell(shellplugin.Volshell):
class Volshell(generic.Volshell):
"""Shell environment to directly interact with a windows memory image."""
@classmethod
@@ -35,17 +35,13 @@ class Volshell(shellplugin.Volshell):
# We always use the main kernel memory and associated symbols
return list(pslist.PsList.list_processes(self.context, self.config['primary'], self.config['nt_symbols']))
def construct_locals(self) -> Dict[str, Any]:
def construct_locals(self) -> List[Tuple[List[str], Any]]:
result = super().construct_locals()
result.update({
'cp': self.change_process,
'change_process': self.change_process,
'lp': self.list_processes,
'list_processes': self.list_processes,
'symbols': self.context.symbol_space[self.config['nt_symbols']],
# windbg compatibility aliases
'ps': self.list_processes,
})
result += [
(['cp', 'change_process'], self.change_process),
(['lp', 'list_processes', 'ps'], self.list_processes),
(['symbols'], self.context.symbol_space[self.config['nt_symbols']]),
]
if self.config.get('pid', None) is not None:
self.change_process(self.config['pid'])
return result