From 832c997e20b7685f772e518d091fdca534a2e2d8 Mon Sep 17 00:00:00 2001 From: SolitudePy <47316655+SolitudePy@users.noreply.github.com> Date: Sat, 7 Jun 2025 19:29:55 +0300 Subject: [PATCH 1/2] Plugins: categorize linux.check_modules as a malware plugin --- .../framework/plugins/linux/check_modules.py | 68 +++--------------- .../plugins/linux/malware/check_modules.py | 70 +++++++++++++++++++ 2 files changed, 79 insertions(+), 59 deletions(-) create mode 100644 volatility3/framework/plugins/linux/malware/check_modules.py diff --git a/volatility3/framework/plugins/linux/check_modules.py b/volatility3/framework/plugins/linux/check_modules.py index 7805bbd8a..d8b3ddcf1 100644 --- a/volatility3/framework/plugins/linux/check_modules.py +++ b/volatility3/framework/plugins/linux/check_modules.py @@ -1,70 +1,20 @@ -# This file is Copyright 2020 Volatility Foundation and licensed under the Volatility Software License 1.0 +# This file is Copyright 2025 Volatility Foundation and licensed under the Volatility Software License 1.0 # which is available at https://www.volatilityfoundation.org/license/vsl-v1.0 # - import logging -from typing import List, Dict, Generator - -import volatility3.framework.symbols.linux.utilities.modules as linux_utilities_modules from volatility3.framework import interfaces, deprecation -from volatility3.framework.configuration import requirements -from volatility3.framework.objects import utility -from volatility3.framework.symbols.linux import extensions -from volatility3.framework.interfaces import plugins +from volatility3.plugins.linux.malware import check_modules vollog = logging.getLogger(__name__) -class Check_modules(plugins.PluginInterface): - """Compares module list to sysfs info, if available""" +class Check_modules( + interfaces.plugins.PluginInterface, + deprecation.PluginRenameClass, + replacement_class=check_modules.Check_modules, + removal_date="2026-06-07", +): + """Compares module list to sysfs info, if available (deprecated).""" _version = (3, 0, 1) _required_framework_version = (2, 0, 0) - - @classmethod - def compare_kset_and_lsmod( - cls, context: str, vmlinux_name: str - ) -> Generator[extensions.module, None, None]: - kset_modules = linux_utilities_modules.Modules.get_kset_modules( - context=context, vmlinux_name=vmlinux_name - ) - - lsmod_modules = set( - str(utility.array_to_string(modules.name)) - for modules in linux_utilities_modules.Modules.list_modules( - context=context, vmlinux_module_name=vmlinux_name - ) - ) - - for mod_name in set(kset_modules.keys()).difference(lsmod_modules): - yield kset_modules[mod_name] - - run = linux_utilities_modules.ModuleDisplayPlugin.run - _generator = linux_utilities_modules.ModuleDisplayPlugin.generator - implementation = compare_kset_and_lsmod - - @classmethod - def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]: - return [ - requirements.VersionRequirement( - name="modules", - component=linux_utilities_modules.Modules, - version=(3, 0, 1), - ), - requirements.VersionRequirement( - name="linux_utilities_modules_module_display_plugin", - component=linux_utilities_modules.ModuleDisplayPlugin, - version=(1, 0, 0), - ), - ] + linux_utilities_modules.ModuleDisplayPlugin.get_requirements() - - @classmethod - @deprecation.deprecated_method( - replacement=linux_utilities_modules.Modules.get_kset_modules, - removal_date="2025-09-25", - replacement_version=(3, 0, 0), - ) - def get_kset_modules( - cls, context: interfaces.context.ContextInterface, vmlinux_name: str - ) -> Dict[str, extensions.module]: - return linux_utilities_modules.Modules.get_kset_modules(context, vmlinux_name) diff --git a/volatility3/framework/plugins/linux/malware/check_modules.py b/volatility3/framework/plugins/linux/malware/check_modules.py new file mode 100644 index 000000000..7805bbd8a --- /dev/null +++ b/volatility3/framework/plugins/linux/malware/check_modules.py @@ -0,0 +1,70 @@ +# This file is Copyright 2020 Volatility Foundation and licensed under the Volatility Software License 1.0 +# which is available at https://www.volatilityfoundation.org/license/vsl-v1.0 +# + +import logging +from typing import List, Dict, Generator + +import volatility3.framework.symbols.linux.utilities.modules as linux_utilities_modules +from volatility3.framework import interfaces, deprecation +from volatility3.framework.configuration import requirements +from volatility3.framework.objects import utility +from volatility3.framework.symbols.linux import extensions +from volatility3.framework.interfaces import plugins + +vollog = logging.getLogger(__name__) + + +class Check_modules(plugins.PluginInterface): + """Compares module list to sysfs info, if available""" + + _version = (3, 0, 1) + _required_framework_version = (2, 0, 0) + + @classmethod + def compare_kset_and_lsmod( + cls, context: str, vmlinux_name: str + ) -> Generator[extensions.module, None, None]: + kset_modules = linux_utilities_modules.Modules.get_kset_modules( + context=context, vmlinux_name=vmlinux_name + ) + + lsmod_modules = set( + str(utility.array_to_string(modules.name)) + for modules in linux_utilities_modules.Modules.list_modules( + context=context, vmlinux_module_name=vmlinux_name + ) + ) + + for mod_name in set(kset_modules.keys()).difference(lsmod_modules): + yield kset_modules[mod_name] + + run = linux_utilities_modules.ModuleDisplayPlugin.run + _generator = linux_utilities_modules.ModuleDisplayPlugin.generator + implementation = compare_kset_and_lsmod + + @classmethod + def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]: + return [ + requirements.VersionRequirement( + name="modules", + component=linux_utilities_modules.Modules, + version=(3, 0, 1), + ), + requirements.VersionRequirement( + name="linux_utilities_modules_module_display_plugin", + component=linux_utilities_modules.ModuleDisplayPlugin, + version=(1, 0, 0), + ), + ] + linux_utilities_modules.ModuleDisplayPlugin.get_requirements() + + @classmethod + @deprecation.deprecated_method( + replacement=linux_utilities_modules.Modules.get_kset_modules, + removal_date="2025-09-25", + replacement_version=(3, 0, 0), + ) + def get_kset_modules( + cls, context: interfaces.context.ContextInterface, vmlinux_name: str + ) -> Dict[str, extensions.module]: + return linux_utilities_modules.Modules.get_kset_modules(context, vmlinux_name) From 4b279f96339f7d5b00af2abf2c8d7d6041777d75 Mon Sep 17 00:00:00 2001 From: SolitudePy <47316655+SolitudePy@users.noreply.github.com> Date: Sat, 7 Jun 2025 19:30:04 +0300 Subject: [PATCH 2/2] linux.malware.check_modules - fix test --- test/plugins/linux/linux.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/plugins/linux/linux.py b/test/plugins/linux/linux.py index e39c1d15d..12309cc59 100644 --- a/test/plugins/linux/linux.py +++ b/test/plugins/linux/linux.py @@ -438,7 +438,7 @@ class TestLinuxCheckAfinfo: class TestLinuxCheckModules: def test_linux_generic_check_modules(self, image, volatility, python): rc, out, _err = test_volatility.runvol_plugin( - "linux.check_modules.Check_modules", image, volatility, python + "linux.malware.check_modules.Check_modules", image, volatility, python ) # linux-sample-1.bin has no suspicious results.