From 07ece011a31ebb4d4213e8d92b9899248bd14e8f Mon Sep 17 00:00:00 2001 From: Andrew Case Date: Tue, 27 Aug 2019 13:12:20 -0500 Subject: [PATCH] Add mac_tasks --- volatility/framework/plugins/mac/tasks.py | 68 +++++++++++++++++++ volatility/framework/symbols/mac/__init__.py | 2 + .../symbols/mac/extensions/__init__.py | 13 +++- 3 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 volatility/framework/plugins/mac/tasks.py diff --git a/volatility/framework/plugins/mac/tasks.py b/volatility/framework/plugins/mac/tasks.py new file mode 100644 index 000000000..cf5c3aeb3 --- /dev/null +++ b/volatility/framework/plugins/mac/tasks.py @@ -0,0 +1,68 @@ +# This file was contributed to the Volatility Framework Version 3. +# Copyright (C) 2018 Volatility Foundation. +# +# THE LICENSED WORK IS PROVIDED UNDER THE TERMS OF THE Volatility Contributors +# Public License V1.0("LICENSE") AS FIRST COMPLETED BY: Volatility Foundation, +# Inc. ANY USE, PUBLIC DISPLAY, PUBLIC PERFORMANCE, REPRODUCTION OR DISTRIBUTION +# OF, OR PREPARATION OF SUBSEQUENT WORKS, DERIVATIVE WORKS OR DERIVED WORKS BASED +# ON, THE LICENSED WORK CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS LICENSE AND ITS +# TERMS, WHETHER OR NOT SUCH RECIPIENT READS THE TERMS OF THE LICENSE. "LICENSED +# WORK,” “RECIPIENT" AND “DISTRIBUTOR" ARE DEFINED IN THE LICENSE. A COPY OF THE +# LICENSE IS LOCATED IN THE TEXT FILE ENTITLED "LICENSE.txt" ACCOMPANYING THE +# CONTENTS OF THIS FILE. IF A COPY OF THE LICENSE DOES NOT ACCOMPANY THIS FILE, A +# COPY OF THE LICENSE MAY ALSO BE OBTAINED AT THE FOLLOWING WEB SITE: +# https://www.volatilityfoundation.org/license/vcpl_v1.0 +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the +# specific language governing rights and limitations under the License. +# + +import logging +from typing import Callable, Iterable, List + +import volatility.framework.interfaces.plugins as interfaces_plugins +from volatility.framework import renderers, interfaces, contexts, constants +from volatility.framework.automagic import mac +from volatility.framework.configuration import requirements +from volatility.framework.objects import utility + +from volatility.plugins.mac import pslist + +vollog = logging.getLogger(__name__) + +class Tasks(pslist.PsList): + """Lists the processes present in a particular mac memory image""" + + @classmethod + def list_tasks(cls, + context: interfaces.context.ContextInterface, + layer_name: str, + darwin_symbols: str, + filter_func: Callable[[int], bool] = lambda _: False) -> \ + Iterable[interfaces.objects.ObjectInterface]: + """Lists all the tasks in the primary layer""" + + mac.MacUtilities.aslr_mask_symbol_table(context, darwin_symbols, layer_name) + + kernel = contexts.Module(context, darwin_symbols, layer_name, 0) + + queue_entry = kernel.object_from_symbol(symbol_name = "tasks") + + seen = {} + for task in queue_entry.walk_list(queue_entry, "tasks", "task"): + if task.vol.offset in seen: + vollog.log(logging.INFO, "Recursive process list detected (a result of non-atomic acquisition).") + break + else: + seen[task.vol.offset] = 1 + + proc = task.bsd_info.dereference().cast("proc") + + if not context.layers[layer_name].is_valid(proc.vol.offset): + break + + if not filter_func(proc): + yield proc + + diff --git a/volatility/framework/symbols/mac/__init__.py b/volatility/framework/symbols/mac/__init__.py index 11b25fdfb..7747ac163 100644 --- a/volatility/framework/symbols/mac/__init__.py +++ b/volatility/framework/symbols/mac/__init__.py @@ -20,3 +20,5 @@ class MacKernelIntermedSymbols(intermed.IntermediateSymbolTable): self.set_type_class('vm_map_object', extensions.vm_map_object) self.set_type_class('socket', extensions.socket) self.set_type_class('inpcb', extensions.inpcb) + self.set_type_class('queue_entry', extensions.queue_entry) + diff --git a/volatility/framework/symbols/mac/extensions/__init__.py b/volatility/framework/symbols/mac/extensions/__init__.py index ebe0049e1..72a8ced14 100644 --- a/volatility/framework/symbols/mac/extensions/__init__.py +++ b/volatility/framework/symbols/mac/extensions/__init__.py @@ -77,7 +77,6 @@ class proc(generic.GenericIntelProcess): yield (start, end - start) - class fileglob(objects.Struct): def get_fg_type(self): @@ -321,7 +320,6 @@ class socket(objects.Struct): return ret - class inpcb(objects.Struct): def get_tcp_state(self): @@ -358,3 +356,14 @@ class inpcb(objects.Struct): rport = self.inp_fport return [lip, lport, rip, rport] + +class queue_entry(objects.Struct): + def walk_list(self, list_head, member_name, type_name): + n = self.next.dereference().cast(type_name) + while n is not None and n.vol.offset != list_head: + yield n + n = n.member(attr = member_name).next.dereference().cast(type_name) + p = self.prev.dereference().cast(type_name) + while p is not None and p.vol.offset != list_head: + yield p + p = p.member(attr = member_name).prev.dereference().cast(type_name)