From 5ca4f8e78839f85dde0b8e5aa2730cbdba46834b Mon Sep 17 00:00:00 2001 From: Mike Auty Date: Mon, 17 Jul 2017 16:38:25 +0100 Subject: [PATCH] Use a central bit of code to do the load and unload of cached linux banners. --- volatility/framework/automagic/linux.py | 14 ++------- .../framework/automagic/linux_symbol_cache.py | 30 +++++++++++++++---- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/volatility/framework/automagic/linux.py b/volatility/framework/automagic/linux.py index 560ea63aa..b5bbea84a 100644 --- a/volatility/framework/automagic/linux.py +++ b/volatility/framework/automagic/linux.py @@ -1,8 +1,7 @@ import logging -import os -import pickle -from volatility.framework import interfaces, constants +from volatility.framework import interfaces +from volatility.framework.automagic import linux_symbol_cache from volatility.framework.layers import intel, scanners vollog = logging.getLogger(__name__) @@ -14,8 +13,7 @@ class LinuxSymbolFinder(interfaces.automagic.AutomagicInterface): def __init__(self, context, config_path): super().__init__(context, config_path) self._requirements = None - self._linux_banners = {} - self._load_linux_banners() + self._linux_banners = linux_symbol_cache.LinuxSymbolCache.load_linux_banners() def __call__(self, context, config_path, requirement, progress_callback = None): """Searches for LinuxSymbolRequirements and attempt to populate them""" @@ -35,12 +33,6 @@ class LinuxSymbolFinder(interfaces.automagic.AutomagicInterface): self._banner_scan(context, path, requirement, context.config[physical_path], progress_callback) - def _load_linux_banners(self): - if os.path.exists(constants.LINUX_BANNERS_PATH): - with open(constants.LINUX_BANNERS_PATH, "rb") as f: - # We use pickle over JSON because we're dealing with bytes objects - self._linux_banners.update(pickle.load(f)) - def _banner_scan(self, context, config_path, requirement, layer_name, progress_callback = None): """Accepts a context, config_path and SymbolRequirement, with a constructed layer_name and scans the layer for linux banners""" diff --git a/volatility/framework/automagic/linux_symbol_cache.py b/volatility/framework/automagic/linux_symbol_cache.py index 3aad6dbe8..b59e92b7d 100644 --- a/volatility/framework/automagic/linux_symbol_cache.py +++ b/volatility/framework/automagic/linux_symbol_cache.py @@ -2,6 +2,7 @@ import logging import os import pathlib import pickle +from urllib import parse from volatility.framework import interfaces, constants from volatility.framework.symbols import intermed @@ -12,16 +13,34 @@ vollog = logging.getLogger(__name__) class LinuxSymbolCache(interfaces.automagic.AutomagicInterface): """Class to run through all Linux symbols tables and cache their banners""" - def __call__(self, context, config_path, configurable, progress_callback = None): - """Runs the automagic over the configurable""" - # We only need to be called once, so no recursion necessary - + @classmethod + def load_linux_banners(cls): linuxbanners = {} if os.path.exists(constants.LINUX_BANNERS_PATH): with open(constants.LINUX_BANNERS_PATH, "rb") as f: # We use pickle over JSON because we're dealing with bytes objects linuxbanners.update(pickle.load(f)) + # Remove possibilities that can't exist locally. + for banner in linuxbanners: + for path in linuxbanners[banner]: + url = parse.urlparse(path) + if url.scheme == 'file' and not os.path.exists(url.path): + vollog.log(constants.LOGLEVEL_V, + "Removing cached path {} for banner {}: files does not exist".format(path, banner)) + linuxbanners[banner].remove(path) + return linuxbanners + + @classmethod + def save_linux_banners(cls, linuxbanners): + with open(constants.LINUX_BANNERS_PATH, "wb") as f: + pickle.dump(linuxbanners, f) + + def __call__(self, context, config_path, configurable, progress_callback = None): + """Runs the automagic over the configurable""" + # We only need to be called once, so no recursion necessary + linuxbanners = self.load_linux_banners() + search_paths = constants.SYMBOL_BASEPATHS cacheables = [] for path in search_paths: @@ -58,5 +77,4 @@ class LinuxSymbolCache(interfaces.automagic.AutomagicInterface): pass # Rewrite the cached linuxbanners each run, since writing is faster than the cache validation portion - with open(constants.LINUX_BANNERS_PATH, "wb") as f: - pickle.dump(linuxbanners, f) + self.save_linux_banners(linuxbanners)