diff --git a/volatility/plugins/mac/lsmod.py b/volatility/plugins/mac/lsmod.py new file mode 100644 index 000000000..df16d4409 --- /dev/null +++ b/volatility/plugins/mac/lsmod.py @@ -0,0 +1,57 @@ +"""A module containing a collection of plugins that produce data +typically found in Mac's lsmod command. +""" + +from volatility.framework import renderers, constants, interfaces +from volatility.framework.automagic import mac +from volatility.framework.configuration import requirements +from volatility.framework.interfaces import plugins +from volatility.framework.objects import utility +from volatility.framework.renderers import format_hints + +class Lsmod(plugins.PluginInterface): + """Lists loaded kernel modules""" + + @classmethod + def get_requirements(cls): + return [requirements.TranslationLayerRequirement(name = 'primary', + description = 'Kernel Address Space', + architectures = ["Intel32", "Intel64"]), + requirements.SymbolRequirement(name = "darwin", + description = "Linux Kernel")] + + @classmethod + def list_modules(cls, + context: interfaces.context.ContextInterface, + layer_name: str, + darwin_symbols: str): + """Lists all the modules in the primary layer""" + + aslr_shift = mac.MacUtilities.find_aslr(context, darwin_symbols, layer_name) + + darwin = context.module(darwin_symbols, layer_name, aslr_shift) + + kmod_ptr = darwin.object(symbol_name = "kmod") + + # TODO - use smear-proof list walking API after dev release + kmod = kmod_ptr.dereference().cast("kmod_info") + while kmod != 0: + yield kmod + kmod = kmod.next + + def _generator(self): + for module in self.list_modules(self.context, + self.config['primary'], + self.config['darwin']): + + mod_name = utility.array_to_string(module.name) + mod_size = module.size + + yield 0, (format_hints.Hex(module.vol.offset), mod_name, mod_size) + + def run(self): + return renderers.TreeGrid( + [("Offset", format_hints.Hex), + ("Name", str), + ("Size", int)], + self._generator()) diff --git a/volatility/plugins/mac/pstree.py b/volatility/plugins/mac/pstree.py new file mode 100644 index 000000000..beb075a86 --- /dev/null +++ b/volatility/plugins/mac/pstree.py @@ -0,0 +1,71 @@ +from volatility.framework import renderers +from volatility.framework.interfaces import plugins +from volatility.framework.objects import utility +from volatility.plugins.mac import pslist +from volatility.framework.configuration import requirements + +class PsTree(plugins.PluginInterface): + """Plugin for listing processes in a tree based on their parent process ID """ + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._processes = {} + self._levels = {} + self._children = {} + + @classmethod + def get_requirements(cls): + return [requirements.TranslationLayerRequirement(name = 'primary', + description = 'Kernel Address Space', + architectures = ["Intel32", "Intel64"]), + requirements.SymbolRequirement(name = "darwin", + description = "Mac Kernel")] + + def find_level(self, pid): + """Finds how deep the pid is in the processes list""" + seen = set([]) + seen.add(pid) + level = 0 + proc = self._processes.get(pid, None) + while proc is not None and proc.vol.offset != 0 and proc.p_ppid != 0 and proc.p_ppid not in seen: + ppid = int(proc.p_ppid) + child_list = self._children.get(ppid, set([])) + child_list.add(proc.p_pid) + self._children[ppid] = child_list + proc = self._processes.get(ppid, None) + level += 1 + self._levels[pid] = level + + def _generator(self): + """Generates the """ + for proc in pslist.PsList.list_tasks(self.context, self.config['primary'], self.config['darwin']): + self._processes[proc.p_pid] = proc + + # Build the child/level maps + for pid in self._processes: + self.find_level(pid) + + def yield_processes(pid): + proc = self._processes[pid] + row = (proc.p_pid, + proc.p_ppid, + utility.array_to_string(proc.p_comm)) + + yield (self._levels[pid] - 1, row) + for child_pid in self._children.get(pid, []): + yield from yield_processes(child_pid) + + for pid in self._levels: + if self._levels[pid] == 1: + yield from yield_processes(pid) + + + def run(self): + return renderers.TreeGrid([("PID", int), + ("PPID", int), + ("COMM", str)], + self._generator()) + + + +