33#
44
55import logging
6- from typing import List
6+ from typing import List , Iterator
77
8- from volatility3 .framework import renderers , interfaces , constants , objects
9- from volatility3 .framework .constants .linux import PT_FLAGS
8+ from volatility3 .framework import renderers , interfaces
109from volatility3 .framework .constants .architectures import LINUX_ARCHS
1110from volatility3 .framework .objects import utility
1211from volatility3 .framework .configuration import requirements
1716
1817
1918class Ptrace (plugins .PluginInterface ):
20- """Enumerates tracer and tracee tasks"""
19+ """Enumerates ptrace's tracer and tracee tasks"""
2120
2221 _required_framework_version = (2 , 10 , 0 )
2322 _version = (1 , 0 , 0 )
@@ -36,85 +35,63 @@ def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]
3635 ]
3736
3837 @classmethod
39- def enumerate_ptraced_tasks (
38+ def enumerate_ptrace_tasks (
4039 cls ,
4140 context : interfaces .context .ContextInterface ,
42- symbol_table : str ,
43- ):
44- vmlinux = context . modules [ symbol_table ]
41+ vmlinux_module_name : str ,
42+ ) -> Iterator [ interfaces . objects . ObjectInterface ] :
43+ """Enumerates ptrace's tracer and tracee tasks
4544
46- tsk_struct_symname = vmlinux .symbol_table_name + constants .BANG + "task_struct"
45+ Args:
46+ context: The context to retrieve required elements (layers, symbol tables) from
47+ vmlinux_module_name: The name of the kernel module on which to operate
48+
49+ Yields:
50+ A task_struct object
51+ """
4752
4853 tasks = pslist .PsList .list_tasks (
4954 context ,
50- symbol_table ,
55+ vmlinux_module_name ,
5156 filter_func = pslist .PsList .create_pid_filter (),
5257 include_threads = True ,
5358 )
5459
5560 for task in tasks :
56- tracing_tid_list = [
57- int (task_being_traced .pid )
58- for task_being_traced in task .ptraced .to_list (
59- tsk_struct_symname , "ptrace_entry"
60- )
61+ if task .is_being_ptraced or task .is_ptracing :
62+ yield task
63+
64+ def _generator (self , vmlinux_module_name ):
65+ for task in self .enumerate_ptrace_tasks (self .context , vmlinux_module_name ):
66+ task_comm = utility .array_to_string (task .comm )
67+ user_pid = task .tgid
68+ user_tid = task .pid
69+ tracer_tid = task .get_ptrace_tracer_tid () or renderers .NotAvailableValue ()
70+ tracee_tids = task .get_ptrace_tracee_tids () or [
71+ renderers .NotAvailableValue ()
6172 ]
62-
63- if task .ptrace == 0 and not tracing_tid_list :
64- continue
65-
66- flags = (
67- PT_FLAGS (task .ptrace ).flags
68- if task .ptrace != 0
69- else renderers .NotAvailableValue ()
70- )
71-
72- traced_by_tid = (
73- task .parent .pid
74- if task .real_parent != task .parent
75- else renderers .NotAvailableValue ()
76- )
77-
78- tracing_tids = "," .join (map (str , tracing_tid_list ))
79-
80- yield task .comm , task .tgid , task .pid , traced_by_tid , tracing_tids , flags
81-
82- def _generator (self , symbol_table ):
83- for fields in self .enumerate_ptraced_tasks (self .context , symbol_table ):
84- yield (0 , fields )
85-
86- @staticmethod
87- def format_fields_with_headers (headers , generator ):
88- """Uses the headers type to cast the fields obtained from the generator"""
89- for level , fields in generator :
90- formatted_fields = []
91- for header , field in zip (headers , fields ):
92- header_type = header [1 ]
93-
94- if isinstance (
95- field , (header_type , interfaces .renderers .BaseAbsentValue )
96- ):
97- formatted_field = field
98- elif isinstance (field , objects .Array ) and header_type is str :
99- formatted_field = utility .array_to_string (field )
100- else :
101- formatted_field = header_type (field )
102-
103- formatted_fields .append (formatted_field )
104- yield level , formatted_fields
73+ flags = task .get_ptrace_tracee_flags () or renderers .NotAvailableValue ()
74+
75+ for tree , tracing_tid in enumerate (tracee_tids ):
76+ fields = [
77+ task_comm ,
78+ user_pid ,
79+ user_tid ,
80+ tracer_tid ,
81+ tracing_tid ,
82+ flags ,
83+ ]
84+ yield (tree , fields )
10585
10686 def run (self ):
107- symbol_table = self .config ["kernel" ]
87+ vmlinux_module_name = self .config ["kernel" ]
10888
10989 headers = [
11090 ("Process" , str ),
11191 ("PID" , int ),
11292 ("TID" , int ),
11393 ("Traced by TID" , int ),
114- ("Tracing TIDs " , str ),
94+ ("Tracing TID " , int ),
11595 ("Flags" , str ),
11696 ]
117- return renderers .TreeGrid (
118- headers ,
119- self .format_fields_with_headers (headers , self ._generator (symbol_table )),
120- )
97+ return renderers .TreeGrid (headers , self ._generator (vmlinux_module_name ))
0 commit comments