diff --git a/volatility/framework/layers/__init__.py b/volatility/framework/layers/__init__.py index 048a6c4f0..3aa482d69 100644 --- a/volatility/framework/layers/__init__.py +++ b/volatility/framework/layers/__init__.py @@ -33,6 +33,8 @@ class ResourceAccessor(object): def open(self, url, mode = "rb"): """Returns a file-like object for a particular URL opened in mode""" + urllib.request.install_opener(urllib.request.build_opener(JarHandler)) + with contextlib.closing(urllib.request.urlopen(url, context = self._context)) as fp: # Cache the file locally url_type, path = urllib.parse.splittype(url) @@ -86,3 +88,24 @@ class ResourceAccessor(object): if curfile is None: raise ValueError("URL does not reference an openable file") return curfile + + +class JarHandler(request.BaseHandler): + """Handles the jar scheme for URIs""" + + def default_open(self, req): + """Handles the request if it's the jar scheme""" + if req.type == 'jar': + subscheme, remainder = req.full_url.split(":")[1], ":".join(req.full_url.split(":")[2:]) + if subscheme != 'file': + vollog.log(constants.LOGLEVEL_VVV, "Unsupported jar subscheme {}".format(subscheme)) + return None + + zipsplit = remainder.split("!") + if len(zipsplit) != 2: + vollog.log(constants.LOGLEVEL_VVV, + "Path did not contain exactly one fragment indicator: {}".format(remainder)) + return None + + zippath, filepath = zipsplit + return zipfile.ZipFile(zippath).open(filepath) diff --git a/volatility/framework/symbols/intermed.py b/volatility/framework/symbols/intermed.py index 2541283ec..c4672be62 100644 --- a/volatility/framework/symbols/intermed.py +++ b/volatility/framework/symbols/intermed.py @@ -4,6 +4,7 @@ import json import logging import os import pathlib +import zipfile from volatility import schemas from volatility.framework import class_subclasses, constants, exceptions, interfaces, objects, layers @@ -135,8 +136,16 @@ class IntermediateSymbolTable(interfaces.symbols.SymbolTableInterface): except FileNotFoundError: # If there's no linux symbols, don't cry about it pass - # Finally try looking in zip files - pass + # Finally try looking in zip files + zip_path = os.path.join(path, sub_path + ".zip") + if os.path.exists(zip_path): + # We have a zipfile, so run through it and look for sub files that match the filename + with zipfile.ZipFile(zip_path) as zfile: + for name in zfile.namelist(): + for extension in extensions: + # By ending with an extension (and therefore, not /), we should not return any directories + if name.endswith(filename + extension) or (filename == "*" and name.endswith(extension)): + yield "jar:file:" + str(pathlib.Path(zip_path)) + "!" + name class ISFormatTable(interfaces.symbols.SymbolTableInterface):