From 67533b034a6c31368c1bfc176497368255a6ccfb Mon Sep 17 00:00:00 2001 From: Dave Lassalle Date: Wed, 26 Mar 2025 08:21:28 -0500 Subject: [PATCH] #1471 - deprecation class for moving --- volatility3/framework/deprecation.py | 47 +++++++++++++++++++ .../framework/plugins/windows/amcache.py | 16 +++---- 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/volatility3/framework/deprecation.py b/volatility3/framework/deprecation.py index e2e91a0eb..5d8087503 100644 --- a/volatility3/framework/deprecation.py +++ b/volatility3/framework/deprecation.py @@ -88,3 +88,50 @@ def deprecated_method( return wrapper return decorator + +def renamed_class(deprecated_class_name: str, message: str, removal_date: str): + """A decorator for marking classes as being renamed and removed in the future. + Callers to this function should explicitly update to use the other plugins instead. + + Args: + deprecated_class_name: The name of the class being deprecated + message: A message added to the standard deprecation warning. Should include the replacement API paths + removal_date: A YYYY-MM-DD formatted date of when the function will be removed from the framework + """ + + def decorator(replacement_func): + @functools.wraps(replacement_func) + def wrapper(*args, **kwargs): + warnings.warn( + f"This plugin ({deprecated_class_name}) has been renamed and will be removed in the first release after {removal_date}. {message}", + FutureWarning, + ) + return replacement_func(*args, **kwargs) + + return wrapper + + return decorator + + +class PluginRenameClass: + """Class to move all classmethod invocations (for when a plugin has been moved)""" + + def __init_subclass__(cls, replacement_class, removal_date, **kwargs): + deprecated_class_name = f"{cls.__module__}.{cls.__qualname__}" + super().__init_subclass__(**kwargs) + for attr, value in replacement_class.__dict__.items(): + if isinstance(value, classmethod): + setattr( + cls, + attr, + classmethod( + renamed_class( + deprecated_class_name=deprecated_class_name, + removal_date=removal_date, + message=f"Please ensure all method calls to this plugin are replaced with calls to {replacement_class.__module__}.{replacement_class.__qualname__}", + )(value.__func__) + ), + ) + else: + setattr(cls, attr, value) + return super(replacement_class).__init_subclass__(**kwargs) \ No newline at end of file diff --git a/volatility3/framework/plugins/windows/amcache.py b/volatility3/framework/plugins/windows/amcache.py index 6e45d5b36..bf0f8f8ad 100644 --- a/volatility3/framework/plugins/windows/amcache.py +++ b/volatility3/framework/plugins/windows/amcache.py @@ -3,22 +3,18 @@ # import logging import warnings +from volatility3.framework import interfaces, deprecation from volatility3.plugins.windows.registry import amcache vollog = logging.getLogger(__name__) -class Amcache(amcache.Amcache): +class Amcache( + interfaces.plugins.PluginInterface, + deprecation.PluginRenameClass, + replacement_class=amcache.Amcache, + removal_date="2025-09-25"): """Extract information on executed applications from the AmCache (deprecated).""" _required_framework_version = (2, 0, 0) _version = (2, 0, 0) - - def __getattribute__(self, *args, **kwargs): - warnings.warn( - FutureWarning( - "The windows.amcache.Amcache plugin is deprecated and will be removed on " - "2025-09-25. Use windows.registry.amcache.Amcache instead." - ) - ) - return super().__getattribute__(*args, **kwargs)