From d7619d6170ea6484bfc39944c4224aa20f5d4ba4 Mon Sep 17 00:00:00 2001 From: Matt Tressler Date: Mon, 3 Aug 2020 11:59:35 -0400 Subject: [PATCH] created linux_check_idt; plugin currently is not finding the module names for each entry in idt table --- .../framework/plugins/linux/check_idt.py | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 volatility/framework/plugins/linux/check_idt.py diff --git a/volatility/framework/plugins/linux/check_idt.py b/volatility/framework/plugins/linux/check_idt.py new file mode 100644 index 000000000..bc327bdab --- /dev/null +++ b/volatility/framework/plugins/linux/check_idt.py @@ -0,0 +1,94 @@ +# 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 typing import List + +from volatility.framework import interfaces, renderers, constants, contexts, exceptions, symbols +from volatility.framework.configuration import requirements +from volatility.framework.renderers import format_hints +from volatility.framework.symbols import linux +from volatility.plugins.linux import lsmod + +vollog = logging.getLogger(__name__) + + +class Check_idt(interfaces.plugins.PluginInterface): + """ Checks if the IDT has been altered """ + + @classmethod + def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]: + 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) + + + is_32bit = not symbols.symbol_table_is_64bit(self.context, self.config["vmlinux"]) + + tblsz = 256 + + # hw handlers + system call + check_idxs = list(range(0, 20)) + [128] + + if is_32bit: + if vmlinux.has_type("gate_struct"): + idt_type = "gate_struct" + else: + idt_type = "desc_struct" + else: + if vmlinux.has_type("gate_struct64"): + idt_type = "gate_struct64" + elif vmlinux.has_type("gate_struct"): + idt_type = "gate_struct" + else: + idt_type = "idt_desc" + + # this is written as a list b/c there are supposdly kernels with per-CPU IDTs + # but I haven't found one yet... + # ^ This is from vol2. Not sure if this should stay a list or if object_from_symbol + # would even give u a multi-element list + addrs = [vmlinux.object_from_symbol("idt_table")] + + for tableaddr in addrs: + table = vmlinux.object(object_type='array', offset=tableaddr.vol.offset, subtype=vmlinux.get_type(idt_type), count=tblsz) + + for i in check_idxs: + ent = table[i] + + if not ent: + continue + + if hasattr(ent, "Address"): + idt_addr = ent.Address + else: + low = ent.offset_low + middle = ent.offset_middle + + if hasattr(ent, "offset_high"): + high = ent.offset_high + else: + high = 0 + + idt_addr = (high << 32) | (middle << 16) | low + + module_name, symbol_name = linux.LinuxUtilities.lookup_module_address(self.context, handlers, idt_addr) + + yield(0, [format_hints.Hex(i), format_hints.Hex(idt_addr), module_name, symbol_name]) + + + def run(self): + return renderers.TreeGrid([("Index", format_hints.Hex), ("Address", format_hints.Hex), ("Module", str), ("Symbol", str)], self._generator())