Merge pull request #938 from volatilityfoundation/issues/issue937

Improve handling of swap files
This commit is contained in:
ikelos
2023-05-03 00:45:50 +01:00
committed by GitHub
3 changed files with 47 additions and 15 deletions
+7 -14
View File
@@ -353,7 +353,9 @@ class CommandLine:
###
if args.file:
try:
single_location = self.location_from_file(args.file)
single_location = requirements.URLRequirement.location_from_file(
args.file
)
ctx.config["automagic.LayerStacker.single_location"] = single_location
except ValueError as excp:
parser.error(str(excp))
@@ -456,19 +458,10 @@ class CommandLine:
Returns:
The URL for the location of the file
"""
# We want to work in URLs, but we need to accept absolute and relative files (including on windows)
single_location = parse.urlparse(filename, "")
if single_location.scheme == "" or len(single_location.scheme) == 1:
single_location = parse.urlparse(
parse.urljoin("file:", request.pathname2url(os.path.abspath(filename)))
)
if single_location.scheme == "file":
if not os.path.exists(request.url2pathname(single_location.path)):
filename = request.url2pathname(single_location.path)
if not filename:
raise ValueError("File URL looks incorrect (potentially missing /)")
raise ValueError(f"File does not exist: {filename}")
return parse.urlunparse(single_location)
vollog.debug(
f"{__name__}.location_from_file has been deprecated and moved to requirements.URIRequirement.location_from_file"
)
return requirements.URIRequirement.location_from_file(filename)
def process_exceptions(self, excp):
"""Provide useful feedback if an exception occurs during a run of a plugin."""
+14 -1
View File
@@ -367,6 +367,7 @@ class WinSwapLayers(interfaces.automagic.AutomagicInterface):
progress_callback: constants.ProgressCallback = None,
) -> None:
"""Finds translation layers that can have swap layers added."""
path_join = interfaces.configuration.path_join
self._translation_requirement = self.find_requirements(
context,
@@ -382,11 +383,13 @@ class WinSwapLayers(interfaces.automagic.AutomagicInterface):
swap_sub_config, swap_req = self.find_swap_requirement(
trans_sub_config, trans_req
)
counter = 0
swap_config = interfaces.configuration.parent_path(swap_sub_config)
if swap_req and swap_req.unsatisfied(context, swap_config):
# See if any of them need constructing
for swap_location in self.config.get("single_swap_locations", []):
# Setup config locations/paths
current_layer_name = swap_req.name + str(counter)
@@ -398,7 +401,17 @@ class WinSwapLayers(interfaces.automagic.AutomagicInterface):
# Fill in the config
if swap_location:
context.config[current_layer_path] = current_layer_name
context.config[layer_loc_path] = swap_location
try:
context.config[
layer_loc_path
] = requirements.URIRequirement.location_from_file(
swap_location
)
except ValueError:
vollog.warning(
f"Volatility swap_location {swap_location} could not be validated - swap layer disabled"
)
continue
context.config[
layer_class_path
] = "volatility3.framework.layers.physical.FileLayer"
@@ -10,7 +10,9 @@ expect to be in the context (such as particular layers or symboltables).
"""
import abc
import logging
import os
from typing import Any, ClassVar, Dict, List, Optional, Tuple, Type
from urllib import parse, request
from volatility3.framework import constants, interfaces
@@ -55,6 +57,30 @@ class URIRequirement(StringRequirement):
# TODO: Maybe a a check that to unsatisfied that the path really is a URL?
@classmethod
def location_from_file(cls, filename: str) -> str:
"""Returns the URL location from a file parameter (which may be a URL)
Args:
filename: The path to the file (either an absolute, relative, or URL path)
Returns:
The URL for the location of the file
"""
# We want to work in URLs, but we need to accept absolute and relative files (including on windows)
single_location = parse.urlparse(filename, "")
if single_location.scheme == "" or len(single_location.scheme) == 1:
single_location = parse.urlparse(
parse.urljoin("file:", request.pathname2url(os.path.abspath(filename)))
)
if single_location.scheme == "file":
if not os.path.exists(request.url2pathname(single_location.path)):
filename = request.url2pathname(single_location.path)
if not filename:
raise ValueError("File URL looks incorrect (potentially missing /)")
raise ValueError(f"File does not exist: {filename}")
return parse.urlunparse(single_location)
class BytesRequirement(interfaces.configuration.SimpleTypeRequirement):
"""A requirement type that contains a byte string."""