Source code for volatility.plugins.mac.psaux

# 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
#
"""In-memory artifacts from OSX systems."""
from typing import Iterator, Tuple, Any, Generator, List

from volatility.framework import exceptions, renderers, interfaces
from volatility.framework.configuration import requirements
from volatility.framework.interfaces import plugins
from volatility.framework.objects import utility
from volatility.plugins.mac import tasks


[docs]class Psaux(plugins.PluginInterface): """Recovers program command line arguments."""
[docs] @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 = "darwin", description = "Mac kernel symbols"), requirements.PluginRequirement(name = 'tasks', plugin = tasks.Tasks, version = (1, 0, 0)) ]
def _generator(self, tasks: Iterator[Any]) -> Generator[Tuple[int, Tuple[int, str, int, str]], None, None]: for task in tasks: proc_layer_name = task.add_process_layer() if proc_layer_name is None: continue proc_layer = self.context.layers[proc_layer_name] argsstart = task.user_stack - task.p_argslen if not proc_layer.is_valid(argsstart) or task.p_argslen == 0 or task.p_argc == 0: continue # Add one because the first two are usually duplicates argc = task.p_argc + 1 # smear protection if argc > 1024: continue task_name = utility.array_to_string(task.p_comm) args = [] # type: List[bytes] while argc > 0: try: arg = proc_layer.read(argsstart, 256) except exceptions.InvalidAddressException: break idx = arg.find(b'\x00') if idx != -1: arg = arg[:idx] argsstart += len(str(arg)) + 1 # deal with the stupid alignment (leading nulls) and arg duplication if len(args) == 0: while argsstart < task.user_stack: try: check = proc_layer.read(argsstart, 1) except exceptions.InvalidAddressException: break if check != b"\x00": break argsstart = argsstart + 1 args.append(arg) # also check for initial duplicates since OS X is painful elif arg != args[0]: args.append(arg) argc = argc - 1 args_str = " ".join([s.decode("utf-8") for s in args]) yield (0, (task.p_pid, task_name, task.p_argc, args_str))
[docs] def run(self) -> renderers.TreeGrid: filter_func = tasks.Tasks.create_pid_filter([self.config.get('pid', None)]) return renderers.TreeGrid([("PID", int), ("Process", str), ("Argc", int), ("Arguments", str)], self._generator( tasks.Tasks.list_tasks(self.context, self.config['primary'], self.config['darwin'], filter_func = filter_func)))