Loading...
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 135 | 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) |