From 7aed488721153c7e786de7775a83f1056f3d8d16 Mon Sep 17 00:00:00 2001 From: Mike Auty Date: Sat, 1 Jan 2022 01:21:37 +0000 Subject: [PATCH] Automagic: Allow automagic to exclude unsupported OSes --- doc/source/using-as-a-library.rst | 3 ++- doc/source/vol2to3.rst | 4 ++++ volatility3/framework/automagic/__init__.py | 21 ++++++------------- volatility3/framework/automagic/linux.py | 2 ++ volatility3/framework/automagic/mac.py | 2 ++ volatility3/framework/constants/__init__.py | 1 + volatility3/framework/interfaces/automagic.py | 3 +++ 7 files changed, 20 insertions(+), 16 deletions(-) diff --git a/doc/source/using-as-a-library.rst b/doc/source/using-as-a-library.rst index 95d2b1080..c63adcfc3 100644 --- a/doc/source/using-as-a-library.rst +++ b/doc/source/using-as-a-library.rst @@ -131,7 +131,8 @@ A suitable list of automagics for a particular plugin (based on operating system automagics = automagic.choose_automagic(available_automagics, plugin) This will take the plugin module, extract the operating system (first level of the hierarchy) and then return just -the automagics which apply to the operating system. +the automagics which apply to the operating system. Each automagic can exclude itself from being used for specific +operating systems, so that an automagic designed for linux is not used for windows or mac plugins. These automagics can then be run by providing the list, the context, the plugin to be run, the hierarchy name that the plugin will be constructed on ('plugins' by default) and a progress_callback. This is a callable which takes diff --git a/doc/source/vol2to3.rst b/doc/source/vol2to3.rst index eb33b6618..e768df0c2 100644 --- a/doc/source/vol2to3.rst +++ b/doc/source/vol2to3.rst @@ -62,6 +62,10 @@ automagic processes are clearly defined and can be enabled or disabled as necess included a stacker automagic to emulate the most common feature of Volatility 2, automatically stacking address spaces (now translation layers) on top of each other. +By default the automagic chosen to be run are determined based on the plugin requested, so that linux plugins get linux +specific automagic and windows plugins get windows specific automagic. This should reduce unnecessarily searching for +linux kernels in a windows image, for example. At the moment this is not user configurableS. + Searching and Scanning ---------------------- Scanning is very similar to scanning in Volatility 2, a scanner object (such as a diff --git a/volatility3/framework/automagic/__init__.py b/volatility3/framework/automagic/__init__.py index e4d422c99..7567f206d 100644 --- a/volatility3/framework/automagic/__init__.py +++ b/volatility3/framework/automagic/__init__.py @@ -21,14 +21,6 @@ from volatility3.framework.configuration import requirements vollog = logging.getLogger(__name__) -windows_automagic = [ - 'ConstructionMagic', 'LayerStacker', 'KernelPDBScanner', 'WinSwapLayers', 'KernelModule' -] - -linux_automagic = ['ConstructionMagic', 'LayerStacker', 'LinuxBannerCache', 'LinuxSymbolFinder', 'KernelModule'] - -mac_automagic = ['ConstructionMagic', 'LayerStacker', 'MacBannerCache', 'MacSymbolFinder', 'KernelModule'] - def available(context: interfaces.context.ContextInterface) -> List[interfaces.automagic.AutomagicInterface]: """Returns an ordered list of all subclasses of @@ -58,10 +50,7 @@ def choose_automagic( plugin_category = "None" plugin_categories = plugin.__module__.split('.') lowest_index = len(plugin_categories) - - automagic_categories = {'windows': windows_automagic, 'linux': linux_automagic, 'mac': mac_automagic} - - for os in automagic_categories: + for os in constants.OS_CATEGORIES: try: if plugin_categories.index(os) < lowest_index: lowest_index = plugin_categories.index(os) @@ -70,14 +59,16 @@ def choose_automagic( # The value wasn't found, try the next one pass - if plugin_category not in automagic_categories: + if plugin_category not in constants.OS_CATEGORIES: vollog.info("No plugin category detected") return automagics - vollog.info(f"Detected a {plugin_category} category plugin") + output = [] for amagic in automagics: - if amagic.__class__.__name__ in automagic_categories[plugin_category]: + if plugin_category not in amagic.exclusion_list: + # Only include uncategorized automagic, or platform specific automagic + # (This allows user defined/uncategorized automagic to be included) output += [amagic] return output diff --git a/volatility3/framework/automagic/linux.py b/volatility3/framework/automagic/linux.py index f9fa22c07..a6577e322 100644 --- a/volatility3/framework/automagic/linux.py +++ b/volatility3/framework/automagic/linux.py @@ -147,6 +147,7 @@ class LinuxBannerCache(symbol_cache.SymbolBannerCache): os = "linux" symbol_name = "linux_banner" banner_path = constants.LINUX_BANNERS_PATH + exclusion_list = ['mac', 'windows'] class LinuxSymbolFinder(symbol_finder.SymbolFinder): @@ -156,3 +157,4 @@ class LinuxSymbolFinder(symbol_finder.SymbolFinder): banner_cache = LinuxBannerCache symbol_class = "volatility3.framework.symbols.linux.LinuxKernelIntermedSymbols" find_aslr = lambda cls, *args: LinuxIntelStacker.find_aslr(*args)[1] + exclusion_list = ['mac', 'windows'] diff --git a/volatility3/framework/automagic/mac.py b/volatility3/framework/automagic/mac.py index fb725a234..c37aef463 100644 --- a/volatility3/framework/automagic/mac.py +++ b/volatility3/framework/automagic/mac.py @@ -202,6 +202,7 @@ class MacBannerCache(symbol_cache.SymbolBannerCache): os = "mac" symbol_name = "version" banner_path = constants.MAC_BANNERS_PATH + exclusion_list = ['windows', 'linux'] class MacSymbolFinder(symbol_finder.SymbolFinder): @@ -211,3 +212,4 @@ class MacSymbolFinder(symbol_finder.SymbolFinder): banner_cache = MacBannerCache find_aslr = MacIntelStacker.find_aslr symbol_class = "volatility3.framework.symbols.mac.MacKernelIntermedSymbols" + exclusion_list = ['windows', 'linux'] diff --git a/volatility3/framework/constants/__init__.py b/volatility3/framework/constants/__init__.py index 23598837b..82ebd4936 100644 --- a/volatility3/framework/constants/__init__.py +++ b/volatility3/framework/constants/__init__.py @@ -78,6 +78,7 @@ BUG_URL = "https://github.com/volatilityfoundation/volatility3/issues" ProgressCallback = Optional[Callable[[float, str], None]] """Type information for ProgressCallback objects""" +OS_CATEGORIES = ['windows', 'mac', 'linux'] class Parallelism(enum.IntEnum): """An enumeration listing the different types of parallelism applied to diff --git a/volatility3/framework/interfaces/automagic.py b/volatility3/framework/interfaces/automagic.py index c310f5b4a..c96c9bdbe 100644 --- a/volatility3/framework/interfaces/automagic.py +++ b/volatility3/framework/interfaces/automagic.py @@ -40,6 +40,9 @@ class AutomagicInterface(interfaces.configuration.ConfigurableInterface, metacla priority = 10 """An ordering to indicate how soon this automagic should be run""" + exclusion_list = [] + """A list of plugin categories (typically operating systems) which the plugin will not operate on""" + def __init__(self, context: interfaces.context.ContextInterface, config_path: str, *args, **kwargs) -> None: super().__init__(context, config_path) for requirement in self.get_requirements():