From 0452f69f82e116aed6030e2baf4ec67684fd977e Mon Sep 17 00:00:00 2001 From: Matt Tressler Date: Mon, 3 Aug 2020 10:38:19 -0400 Subject: [PATCH] created keyboard_notifiers --- volatility/framework/automagic/linux.py | 1 + .../plugins/linux/keyboard_notifiers.py | 62 +++++++++++++++++++ .../framework/symbols/linux/__init__.py | 8 +++ 3 files changed, 71 insertions(+) create mode 100644 volatility/framework/plugins/linux/keyboard_notifiers.py diff --git a/volatility/framework/automagic/linux.py b/volatility/framework/automagic/linux.py index 266c279da..4fcae4a78 100644 --- a/volatility/framework/automagic/linux.py +++ b/volatility/framework/automagic/linux.py @@ -133,6 +133,7 @@ class LinuxIntelStacker(interfaces.automagic.StackerLayerInterface): @classmethod def virtual_to_physical_address(cls, addr: int) -> int: + """Converts a virtual linux address to a physical one (does not account of ASLR)""" if addr > 0xffffffff80000000: diff --git a/volatility/framework/plugins/linux/keyboard_notifiers.py b/volatility/framework/plugins/linux/keyboard_notifiers.py new file mode 100644 index 000000000..fe3ce4523 --- /dev/null +++ b/volatility/framework/plugins/linux/keyboard_notifiers.py @@ -0,0 +1,62 @@ +# This file is Copyright 2019 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 volatility.framework import interfaces, renderers, constants, contexts, exceptions +from volatility.framework.symbols import linux +from volatility.framework.configuration import requirements +from volatility.framework.renderers import format_hints +from volatility.plugins.linux import lsmod + +vollog = logging.getLogger(__name__) + + +class Keyboard_notifiers(interfaces.plugins.PluginInterface): + """Parses the keyboard notifier call chain""" + + @classmethod + def get_requirements(cls): + return [ + requirements.TranslationLayerRequirement(name='primary', + description='Memory layer for the kernel', + architectures=["Intel32", "Intel64"]), + requirements.SymbolTableRequirement( + name="vmlinux", description="Linux kernel symbols"), + requirements.PluginRequirement( + name='lsmod', plugin=lsmod.Lsmod, version=(1, 0, 0)) + ] + + def _generator(self): + vmlinux = contexts.Module( + self.context, self.config['vmlinux'], self.config['primary'], 0) + + modules = lsmod.Lsmod.list_modules(self.context, self.config['primary'], self.config['vmlinux']) + + handlers = linux.LinuxUtilities.generate_kernel_handler_info(self.context, self.config['primary'], self.config['vmlinux'], modules) + + try: + knl_addr = vmlinux.object_from_symbol("keyboard_notifier_list") + except exceptions.SymbolError: + knl_addr = None + + if not knl_addr: + raise TypeError( + "This plugin requires the keyboard_notifier_list structure. " + "This structure is not present in the supplied symbol table. " + "This means you are either analyzing an unsupported kernel version or that your symbol table is corrupt." + ) + + knl = vmlinux.object(object_type="atomic_notifier_head", offset=knl_addr.vol.offset) + + for call_back in linux.LinuxUtilities.walk_internal_list(vmlinux, "notifier_block", "next", knl.head): + call_addr = call_back.notifier_call + + module_name, symbol_name = linux.LinuxUtilities.lookup_module_address(self.context, handlers, call_addr) + + yield (0, [format_hints.Hex(call_addr), module_name, symbol_name]) + + + def run(self): + return renderers.TreeGrid([("Address", format_hints.Hex), ("Module", str), ("Symbol", str)], self._generator()) diff --git a/volatility/framework/symbols/linux/__init__.py b/volatility/framework/symbols/linux/__init__.py index 81ed116f1..a77b06cce 100644 --- a/volatility/framework/symbols/linux/__init__.py +++ b/volatility/framework/symbols/linux/__init__.py @@ -251,3 +251,11 @@ class LinuxUtilities(object): break return mod_name, symbol_name + + @classmethod + def walk_internal_list(cls, vmlinux, struct_name, list_member, list_start): + while list_start: + list_struct = vmlinux.object( + object_type=struct_name, offset=list_start.vol.offset) + yield list_struct + list_start = getattr(list_struct, list_member)