forked from apple/darwin-xnu
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ipcimportancedetail.py
135 lines (111 loc) · 5.33 KB
/
ipcimportancedetail.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
from xnu import *
"""
Recursive ipc importance chain viewing macro. This file incorporates complex python datastructures
interspersed with cvalue based objects from lldb interface.
"""
class TaskNode(object):
def __init__(self, task_kobj):
self.task = task_kobj
self.importance_refs = []
@staticmethod
def GetHeaderString():
return GetTaskSummary.header + " " + GetProcSummary.header + " {: <18s}".format("task_imp_base")
def __str__(self):
out_arr = []
if unsigned(self.task) != 0:
out_arr.append(GetTaskSummary(self.task) + " " + GetProcSummary(Cast(self.task.bsd_info, 'proc *')) + " {: <#018x}".format(self.task.task_imp_base) )
else:
out_arr.append("Unknown task.")
#out_arr.append("TASK: {: <#018x} {: <s}".format(self.task, GetProcNameForTask(self.task))
for i in self.importance_refs:
out_arr.append("\t" + i.GetBackRefChain())
return "\n".join(out_arr)
def AddImportanceNode(self, iinode):
self.importance_refs.append(iinode)
class IIINode(object):
"""docstring for IIINode"""
def __init__(self, elem, parentNode):
super(IIINode, self).__init__()
self.elem = elem
self.children = []
self.parent = parentNode
def addChildNode(self, elemNode):
self.children.append(elemNode)
def __str__(self):
if unsigned(self.elem.iii_elem.iie_bits) & 0x80000000:
return GetIPCImportanceInheritSummary(self.elem)
else:
return GetIPCImportantTaskSummary(self.elem)
def GetShortSummary(self):
to_task = self.GetToTask()
if unsigned(self.elem.iii_elem.iie_bits) & 0x80000000:
return "{: <#018x} INH ({:d}){: <s}".format(self.elem, GetProcPIDForTask(to_task), GetProcNameForTask(to_task))
else:
return "{: <#018x} IIT ({:d}){: <s}".format(self.elem, GetProcPIDForTask(to_task), GetProcNameForTask(to_task))
def GetChildSummaries(self, prefix="\t"):
retval = []
for i in self.children:
retval.append(prefix + str(i))
retval.append(i.GetChildSummaries(prefix+"\t"))
return "\n".join(retval)
def GetToTask(self):
if unsigned(self.elem.iii_elem.iie_bits) & 0x80000000:
return self.elem.iii_to_task.iit_task
else:
return self.elem.iit_task
def GetParentNode(self):
return self.parent
def GetBackRefChain(self):
out_str = ""
cur_elem = self.elem
out_str += self.GetShortSummary()
from_elem = Cast(cur_elem.iii_from_elem, 'ipc_importance_inherit *')
# NOTE: We are exploiting the layout of iit and iii to have iie at the begining.
# so casting one to another is fine as long as we tread carefully.
while unsigned(from_elem.iii_elem.iie_bits) & 0x80000000:
out_str += " <- {: <#018x} INH ({:d}){: <s}".format(from_elem, GetProcPIDForTask(from_elem.iii_to_task.iit_task), GetProcNameForTask(from_elem.iii_to_task.iit_task))
from_elem = Cast(from_elem.iii_from_elem, 'ipc_importance_inherit *')
if unsigned(from_elem.iii_elem.iie_bits) & 0x80000000 == 0:
iit_elem = Cast(from_elem, 'ipc_importance_task *')
out_str += " <- {: <#018x} IIT ({:d}){: <s}".format(iit_elem, GetProcPIDForTask(iit_elem.iit_task), GetProcNameForTask(iit_elem.iit_task))
return out_str
#unused
cur_elem = self
while cur_elem.parent:
out_str += "<-" + cur_elem.GetShortSummary()
cur_elem = cur_elem.GetParentNode()
return out_str
def GetIIIListFromIIE(iie, rootnode):
""" walk the iii queue and find each III element in a list format
"""
for i in IterateQueue(iie.iie_inherits, 'struct ipc_importance_inherit *', 'iii_inheritance'):
iieNode = IIINode(i, rootnode)
if unsigned(i.iii_elem.iie_bits) & 0x80000000:
rootnode.addChildNode(iieNode)
GetIIIListFromIIE(i.iii_elem, iieNode)
GetTaskNodeByKernelTaskObj(iieNode.GetToTask()).AddImportanceNode(iieNode)
return
AllTasksCollection = {}
def GetTaskNodeByKernelTaskObj(task_kobj):
global AllTasksCollection
key = hex(unsigned(task_kobj))
if key not in AllTasksCollection:
AllTasksCollection[key] = TaskNode(task_kobj)
return AllTasksCollection[key]
@lldb_command('showallipcimportance')
def ShowInheritanceChains(cmd_args=[], cmd_options={}):
""" show boost inheritance chains.
Usage: (lldb) showboostinheritancechains <task_t>
"""
print ' ' + GetIPCImportantTaskSummary.header + ' ' + GetIPCImportanceElemSummary.header
for task in kern.tasks:
if unsigned(task.task_imp_base):
print " " + GetIPCImportantTaskSummary(task.task_imp_base) + ' ' + GetIPCImportanceElemSummary(addressof(task.task_imp_base.iit_elem))
base_node = IIINode(Cast(task.task_imp_base, 'ipc_importance_inherit *'), None)
GetIIIListFromIIE(task.task_imp_base.iit_elem, base_node)
print base_node.GetChildSummaries(prefix="\t\t")
print "\n\n ======================== TASK REVERSE CHAIN OF IMPORTANCES ========================="
print TaskNode.GetHeaderString()
for k in AllTasksCollection.keys():
t = AllTasksCollection[k]
print "\n" + str(t)