Source code for volatility3.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 volatility3.framework import exceptions, renderers, interfaces
from volatility3.framework.configuration import requirements
from volatility3.framework.interfaces import plugins
from volatility3.framework.objects import utility
from volatility3.plugins.mac import pslist


[docs]class Psaux(plugins.PluginInterface): """Recovers program command line arguments.""" _required_framework_version = (2, 0, 0)
[docs] @classmethod def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]: return [ requirements.ModuleRequirement( name="kernel", description="Kernel module for the OS", architectures=["Intel32", "Intel64"], ), requirements.PluginRequirement( name="pslist", plugin=pslist.PsList, version=(3, 0, 0) ), requirements.ListRequirement( name="pid", description="Filter on specific process IDs", element_type=int, optional=True, ), ]
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: 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", errors="replace") for s in args]) yield (0, (task.p_pid, task_name, task.p_argc, args_str))
[docs] def run(self) -> renderers.TreeGrid: filter_func = pslist.PsList.create_pid_filter(self.config.get("pid", None)) list_tasks = pslist.PsList.get_list_tasks( self.config.get("pslist_method", pslist.PsList.pslist_methods[0]) ) return renderers.TreeGrid( [("PID", int), ("Process", str), ("Argc", int), ("Arguments", str)], self._generator( list_tasks(self.context, self.config["kernel"], filter_func=filter_func) ), )