def render_text(self, outfd, data): common.set_plugin_members(self) self.table_header(outfd, [ ("PID", "8"), ("Name", "16"), ("Start Time", "32"), ("Priority", "6"), ("Start Function", "[addrpad]"), ("Function Map", ""), ]) kaddr_info = common.get_handler_name_addrs(self) for proc in data: for th in proc.threads(): func_addr = th.continuation (module, handler_sym) = common.get_handler_name(kaddr_info, func_addr) if handler_sym: handler = handler_sym elif module: handler = module else: handler = proc.find_map_path(func_addr) self.table_row(outfd, proc.p_pid, proc.p_comm, th.start_time(), th.priority, func_addr, handler)
def render_text(self, outfd, data): common.set_plugin_members(self) self.table_header(outfd, [("PID","8"), ("Name", "16"), ("Start Time", "32"), ("Priority", "6"), ("Start Function", "[addrpad]"), ("Function Map", ""), ]) kaddr_info = common.get_handler_name_addrs(self) for proc in data: for th in proc.threads(): func_addr = th.continuation (module, handler_sym) = common.get_handler_name(kaddr_info, func_addr) if handler_sym: handler = handler_sym elif module: handler = module else: handler = proc.find_map_path(func_addr) self.table_row(outfd, proc.p_pid, proc.p_comm, th.start_time(), th.sched_pri, func_addr, handler)
def render_text(self, outfd, data): common.set_plugin_members(self) self.table_header( outfd, [ ("Offset", "[addrpad]"), ("Scope", "24"), ("IData", "[addrpad]"), ("Callback Addr", "[addrpad]"), ("Callback Mod", "24"), ("Callback Sym", ""), ], ) kaddr_info = common.get_handler_name_addrs(self) for scope in data: scope_name = scope.ks_identifier for ls in scope.listeners(): cb = ls.kll_callback.v() (module, handler_sym) = common.get_handler_name(kaddr_info, cb) self.table_row( outfd, ls.v(), scope_name, ls.kll_idata, cb, module, handler_sym, )
def generator(self, data): kaddr_info = common.get_handler_name_addrs(self) for proc in data: for th in proc.threads(): func_addr = th.continuation (module, handler_sym) = common.get_handler_name(kaddr_info, func_addr) if handler_sym: handler = handler_sym elif module: handler = module else: handler = proc.find_map_path(func_addr) yield ( 0, [ int(proc.p_pid), str(proc.p_comm), str(th.start_time()), int(th.sched_pri), Address(func_addr), str(handler), ], )
def _walk_opv_desc(self, kaddr_info): table_addr = self.addr_space.profile.get_symbol("_vfs_opv_descs") table = obj.Object(targetType = "unsigned long", theType = "Array", count = 32, vm = self.addr_space, offset = table_addr) for desc in table: if desc.v() == 0: break table_name = self.addr_space.profile.get_symbol_by_address("kernel", desc.v()) if not table_name: table_name = "<unknown table>" vnodeopv_desc = obj.Object("vnodeopv_desc", offset = desc.v(), vm = self.addr_space) vdesc_arr = obj.Object(theType = "Array", targetType = "vnodeopv_entry_desc", offset = vnodeopv_desc.opv_desc_ops, count = 64, vm = self.addr_space) for vdesc in vdesc_arr: ptr = vdesc.opve_impl.v() if ptr == 0: break name = self.addr_space.read(vdesc.opve_op.vdesc_name.v(), 64) if name: idx = name.find("\x00") if idx != -1: name = name[:idx] else: name = "<INVALID NAME>" name = table_name + "/" + name (module, handler_sym) = common.get_handler_name(kaddr_info, ptr) yield (vdesc.v(), name, ptr, module, handler_sym)
def calculate(self): common.set_plugin_members(self) kaddr_info = common.get_handler_name_addrs(self) dict_ptr_addr = common.get_cpp_sym("sAllClassesDict", self.addr_space.profile) dict_addr = obj.Object("unsigned long", offset=dict_ptr_addr, vm=self.addr_space) fdict = obj.Object(self._struct_or_class("OSDictionary"), offset=dict_addr.v(), vm=self.addr_space) ents = obj.Object('Array', offset=fdict.dictionary, vm=self.addr_space, targetType=self._struct_or_class("dictEntry"), count=fdict.count) for ent in ents: if ent == None or not ent.is_valid(): continue class_name = str( ent.key.dereference_as(self._struct_or_class("OSString"))) osmeta = obj.Object(self._struct_or_class("OSMetaClass"), offset=ent.value.v(), vm=self.addr_space) cname = str( osmeta.className.dereference_as( self._struct_or_class("OSString"))) offset = 0 if hasattr(osmeta, "metaClass"): arr_start = osmeta.metaClass.v() else: arr_start = obj.Object("Pointer", offset=osmeta.obj_offset, vm=self.addr_space) vptr = obj.Object("unsigned long", offset=arr_start, vm=self.addr_space) while vptr != 0: (module, handler_sym) = common.get_handler_name(kaddr_info, vptr) yield (cname, vptr, module, handler_sym) offset = offset + vptr.size() vptr = obj.Object("unsigned long", offset=arr_start + offset, vm=self.addr_space)
def _walk_opv_desc(self, kaddr_info): table_addr = self.addr_space.profile.get_symbol("_vfs_opv_descs") table = obj.Object( targetType="unsigned long", theType="Array", count=32, vm=self.addr_space, offset=table_addr, ) for desc in table: if desc.v() == 0: break table_name = self.addr_space.profile.get_symbol_by_address( "kernel", desc.v()) if not table_name: table_name = "<unknown table>" vnodeopv_desc = obj.Object("vnodeopv_desc", offset=desc.v(), vm=self.addr_space) vdesc_arr = obj.Object( theType="Array", targetType="vnodeopv_entry_desc", offset=vnodeopv_desc.opv_desc_ops, count=64, vm=self.addr_space, ) for vdesc in vdesc_arr: ptr = vdesc.opve_impl.v() if ptr == 0: break name = self.addr_space.read(vdesc.opve_op.vdesc_name.v(), 64) if name: idx = name.find(b"\x00") if idx != -1: name = name[:idx] else: name = b"<INVALID NAME>" name = table_name + "/" + name.decode('ascii') (module, handler_sym) = common.get_handler_name(kaddr_info, ptr) yield (vdesc.v(), name, ptr, module, handler_sym)
def calculate(self): common.set_plugin_members(self) nchrdev_addr = self.addr_space.profile.get_symbol("_nchrdev") nchrdev = obj.Object("unsigned int", offset=nchrdev_addr, vm=self.addr_space) cdevsw_addr = self.addr_space.profile.get_symbol("_cdevsw") cdevsw = obj.Object( theType="Array", targetType="cdevsw", offset=cdevsw_addr, vm=self.addr_space, count=nchrdev, ) kaddr_info = common.get_handler_name_addrs(self) op_members = list( self.profile.types['cdevsw'].keywords["members"].keys()) op_members.remove('d_ttys') op_members.remove('d_type') files = mac_list_files.mac_list_files(self._config).calculate() for vnode, path in files: if vnode.v_type.v() not in [3, 4]: continue if path.startswith("/Macintosh HD"): path = path[13:] dn = vnode.v_data.dereference_as("devnode") dev = dn.dn_typeinfo.dev major = (dev >> 24) & 0xFF if not (0 <= major <= nchrdev): continue cdev = cdevsw[major] for member in op_members: ptr = cdev.__getattr__(member).v() if ptr != 0: (module, handler_sym) = common.get_handler_name(kaddr_info, ptr) yield (cdev.v(), path, member, ptr, module, handler_sym)
def _walk_vfstbllist(self, kaddr_info): table_size_ptr = self.addr_space.profile.get_symbol("_maxvfsconf") if table_size_ptr == None: table_size_ptr = self.addr_space.profile.get_symbol("_maxvfsslots") table_size = obj.Object("unsigned int", offset=table_size_ptr, vm=self.addr_space) table_ptr = self.addr_space.profile.get_symbol("_vfstbllist") table = obj.Object( theType="Array", targetType="vfstable", offset=table_ptr, count=table_size, vm=self.addr_space, ) vfs_op_members = list( self.profile.types['vfsops'].keywords["members"].keys()) if "vfs_reserved" in vfs_op_members: vfs_op_members.remove("vfs_reserved") for vfs in table: if not vfs.is_valid(): continue name = self.addr_space.read(vfs.vfc_name.obj_offset, 16) if name: idx = name.find(b"\x00") if idx != -1: name = name[:idx] else: name = b"<INVALID NAME>" if name == b"<unassigned>": break ops = vfs.vfc_vfsops for member in vfs_op_members: ptr = ops.__getattr__(member).v() if ptr == 0: continue (module, handler_sym) = common.get_handler_name(kaddr_info, ptr) yield (vfs.v(), name, ptr, module, handler_sym)
def generator(self, data): kaddr_info = common.get_handler_name_addrs(self) for scope in data: cb = scope.ks_callback.v() (module, handler_sym) = common.get_handler_name(kaddr_info, cb) yield (0, [ Address(scope.v()), str(scope.ks_identifier), Address(scope.ks_idata), str(len([l for l in scope.listeners()])), Address(cb), str(module), str(handler_sym), ])
def generator(self, data): kaddr_info = common.get_handler_name_addrs(self) for scope in data: cb = scope.ks_callback.v() (module, handler_sym) = common.get_handler_name(kaddr_info, cb) yield(0, [ Address(scope.v()), str(scope.ks_identifier), Address(scope.ks_idata), int(len([l for l in scope.listeners()])), Address(cb), str(module), str(handler_sym), ])
def generator(self, data): kaddr_info = common.get_handler_name_addrs(self) for scope in data: scope_name = scope.ks_identifier for ls in scope.listeners(): cb = ls.kll_callback.v() (module, handler_sym) = common.get_handler_name(kaddr_info, cb) yield(0, [ Address(ls.v()), str(scope_name), Address(ls.kll_idata), Address(cb), str(module), str(handler_sym), ])
def generator(self, data): kaddr_info = common.get_handler_name_addrs(self) for scope in data: scope_name = scope.ks_identifier for ls in scope.listeners(): cb = ls.kll_callback.v() (module, handler_sym) = common.get_handler_name(kaddr_info, cb) yield (0, [ Address(ls.v()), str(scope_name), Address(ls.kll_idata), Address(cb), str(module), str(handler_sym), ])
def render_text(self, outfd, data): common.set_plugin_members(self) self.table_header(outfd, [("Offset", "[addrpad]"), ("Scope", "24"), ("IData", "[addrpad]"), ("Callback Addr", "[addrpad]"), ("Callback Mod", "24"), ("Callback Sym", ""),]) kaddr_info = common.get_handler_name_addrs(self) for scope in data: scope_name = scope.ks_identifier for ls in scope.listeners(): cb = ls.kll_callback.v() (module, handler_sym) = common.get_handler_name(kaddr_info, cb) self.table_row(outfd, ls.v(), scope_name, ls.kll_idata, cb, module, handler_sym)
def calculate(self): common.set_plugin_members(self) kaddr_info = common.get_handler_name_addrs(self) real_ncpus = obj.Object("int", offset = self.addr_space.profile.get_symbol("_real_ncpus"), vm = self.addr_space) ptr = self.addr_space.profile.get_symbol("_cpu_data_ptr") cpu_data_ptrs = obj.Object(theType = 'Array', offset = ptr, vm = self.addr_space, targetType = "unsigned long long", count = real_ncpus) for i in range(real_ncpus): cpu_data = obj.Object('cpu_data', offset = cpu_data_ptrs[i], vm = self.addr_space) c = cpu_data.rtclock_timer q = c.queue ent = q.head.next first = ent seen = {} while ent.is_valid(): seen[ent.v()] = 1 timer = obj.Object("call_entry", offset = ent.v(), vm = self.addr_space) func = timer.func.v() if func < 0x1000 or func == 0xffffffff00000000: break (module, handler_sym) = common.get_handler_name(kaddr_info, func) if hasattr(timer, "entry_time"): entry_time = timer.entry_time.v() else: entry_time = -1 yield func, timer.param0, timer.param1, timer.deadline, entry_time, module, handler_sym ent = timer.q_link.next if ent == first or ent.v() in seen: break
def _walk_vfstbllist(self, kaddr_info): table_size_ptr = self.addr_space.profile.get_symbol("_maxvfsconf") if table_size_ptr == None: table_size_ptr = self.addr_space.profile.get_symbol("_maxvfsslots") table_size = obj.Object("unsigned int", offset = table_size_ptr, vm = self.addr_space) table_ptr = self.addr_space.profile.get_symbol("_vfstbllist") table = obj.Object(theType = "Array", targetType = "vfstable", offset = table_ptr, count = table_size, vm = self.addr_space) vfs_op_members = self.profile.types['vfsops'].keywords["members"].keys() if "vfs_reserved" in vfs_op_members: vfs_op_members.remove("vfs_reserved") for vfs in table: if not vfs.is_valid(): continue name = self.addr_space.read(vfs.vfc_name.obj_offset, 16) if name: idx = name.find("\x00") if idx != -1: name = name[:idx] else: name = "<INVALID NAME>" if name == "<unassigned>": break ops = vfs.vfc_vfsops for member in vfs_op_members: ptr = ops.__getattr__(member).v() if ptr == 0: continue (module, handler_sym) = common.get_handler_name(kaddr_info, ptr) yield (vfs.v(), name, ptr, module, handler_sym)
def calculate(self): common.set_plugin_members(self) kaddr_info = common.get_handler_name_addrs(self) dict_ptr_addr = common.get_cpp_sym("sAllClassesDict", self.addr_space.profile) dict_addr = obj.Object("unsigned long", offset = dict_ptr_addr, vm = self.addr_space) fdict = obj.Object(self._struct_or_class("OSDictionary"), offset = dict_addr.v(), vm = self.addr_space) ents = obj.Object('Array', offset = fdict.dictionary, vm = self.addr_space, targetType = self._struct_or_class("dictEntry"), count = fdict.count) for ent in ents: if ent == None or not ent.is_valid(): continue class_name = str(ent.key.dereference_as(self._struct_or_class("OSString"))) osmeta = obj.Object(self._struct_or_class("OSMetaClass"), offset = ent.value.v(), vm = self.addr_space) cname = str(osmeta.className.dereference_as(self._struct_or_class("OSString"))) offset = 0 if hasattr(osmeta, "metaClass"): arr_start = osmeta.metaClass.v() else: arr_start = obj.Object("Pointer", offset = osmeta.obj_offset, vm = self.addr_space) vptr = obj.Object("unsigned long", offset = arr_start, vm = self.addr_space) while vptr != 0: (module, handler_sym) = common.get_handler_name(kaddr_info, vptr) yield (cname, vptr, module, handler_sym) offset = offset + vptr.size() vptr = obj.Object("unsigned long", offset = arr_start + offset, vm = self.addr_space)
def calculate(self): common.set_plugin_members(self) nchrdev_addr = self.addr_space.profile.get_symbol("_nchrdev") nchrdev = obj.Object("unsigned int", offset = nchrdev_addr, vm = self.addr_space) cdevsw_addr = self.addr_space.profile.get_symbol("_cdevsw") cdevsw = obj.Object(theType = "Array", targetType = "cdevsw", offset = cdevsw_addr, vm = self.addr_space, count = nchrdev) kaddr_info = common.get_handler_name_addrs(self) op_members = self.profile.types['cdevsw'].keywords["members"].keys() op_members.remove('d_ttys') op_members.remove('d_type') files = mac_list_files.mac_list_files(self._config).calculate() for vnode, path in files: if vnode.v_type.v() not in [3, 4]: continue if path.startswith("/Macintosh HD"): path = path[13:] dn = vnode.v_data.dereference_as("devnode") dev = dn.dn_typeinfo.dev major = (dev >> 24) & 0xff if not (0 <= major <= nchrdev): continue cdev = cdevsw[major] for member in op_members: ptr = cdev.__getattr__(member).v() if ptr != 0: (module, handler_sym) = common.get_handler_name(kaddr_info, ptr) yield (cdev.v(), path, member, ptr, module, handler_sym)
def render_text(self, outfd, data): common.set_plugin_members(self) self.table_header(outfd, [("Offset", "[addrpad]"), ("Name", "24"), ("IData", "[addrpad]"), ("Listeners", "5"), ("Callback Addr", "[addrpad]"), ("Callback Mod", "24"), ("Callback Sym", ""),]) kaddr_info = common.get_handler_name_addrs(self) for scope in data: cb = scope.ks_callback.v() (module, handler_sym) = common.get_handler_name(kaddr_info, cb) self.table_row(outfd, scope.v(), scope.ks_identifier, scope.ks_idata, len([l for l in scope.listeners()]), cb, module, handler_sym)
def generator(self, data): kaddr_info = common.get_handler_name_addrs(self) for proc in data: for th in proc.threads(): func_addr = th.continuation (module, handler_sym) = common.get_handler_name(kaddr_info, func_addr) if handler_sym: handler = handler_sym elif module: handler = module else: handler = proc.find_map_path(func_addr) yield(0, [ int(proc.p_pid), str(proc.p_comm), str(th.start_time()), str(th.priority), Address(func_addr), str(handler), ])
def walk_reg_entry(self, reg_addr): regroot = obj.Object(self._struct_or_class("IORegistryEntry"), offset = reg_addr, vm = self.addr_space) fdict = regroot.fRegistryTable props = self.parse_properties(regroot.fPropertyTable) ents = obj.Object('Array', offset = fdict.dictionary, vm = self.addr_space, targetType = self._struct_or_class("dictEntry"), count = fdict.count) keys = [] children = [] current_name = "" device_mem = False for ent in ents: if ent == None or not ent.is_valid(): continue key = str(ent.key.dereference_as(self._struct_or_class("OSString"))) keys.append(key) if key == "IODeviceMemory": current_name = str(ent.value.dereference_as(self._struct_or_class("OSString"))) device_mem = True if key == "IOName" and device_mem == False: current_name = str(ent.value.dereference_as(self._struct_or_class("OSString"))) if key == "IOServiceChildLinks": children.append(ent.value) if current_name == "": if "IOClass" in props: addr = props["IOClass"] s = obj.Object(self._struct_or_class("OSString"), offset = addr, vm = self.addr_space) current_name = "IOCLass: %s" % str(s) if current_name == "": serv = obj.Object(self._struct_or_class("IOService"), offset = reg_addr, vm = self.addr_space) buf = self.addr_space.read(serv.pwrMgt.Name, 128) if buf: idx = buf.find("\x00") if idx != -1: buf = buf[:idx] current_name = buf prop_string = "".join(["%s=%x, " % (k,v) for (k,v) in props.items()]) #print "%-20s | %s | %s" % (current_name, keys, prop_string) offset = self.addr_space.profile.get_obj_offset(self._struct_or_class("_IOServiceInterestNotifier"), "chain") for (k, v) in props.items(): if k.find("nterest") != -1: cmd = obj.Object(self._struct_or_class("IOCommand"), offset = v, vm = self.addr_space) notifier_ptr = cmd.fCommandChain.next first_ptr = notifier_ptr last = 0 while notifier_ptr.is_valid() and notifier_ptr != last: notifier = obj.Object(self._struct_or_class("_IOServiceInterestNotifier"), offset = notifier_ptr - offset, vm = self.addr_space) if not notifier.handler.is_valid(): break last = notifier_ptr notifier_ptr = notifier.chain.next if notifier_ptr == first_ptr: break handler = notifier.handler.v() (module, handler_sym) = common.get_handler_name(kaddr_info, handler) yield k, handler, module, handler_sym for child in children: for k, handler, module, handler_sym in self.walk_child_links(child): yield k, handler, module, handler_sym
def walk_reg_entry(self, reg_addr): regroot = obj.Object( self._struct_or_class("IORegistryEntry"), offset=reg_addr, vm=self.addr_space, ) fdict = regroot.fRegistryTable props = self.parse_properties(regroot.fPropertyTable) ents = obj.Object( 'Array', offset=fdict.dictionary, vm=self.addr_space, targetType=self._struct_or_class("dictEntry"), count=fdict.count, ) keys = [] children = [] current_name = "" device_mem = False for ent in ents: if ent == None or not ent.is_valid(): continue key = str(ent.key.dereference_as( self._struct_or_class("OSString"))) keys.append(key) if key == "IODeviceMemory": current_name = str( ent.value.dereference_as( self._struct_or_class("OSString"))) device_mem = True if key == "IOName" and device_mem == False: current_name = str( ent.value.dereference_as( self._struct_or_class("OSString"))) if key == "IOServiceChildLinks": children.append(ent.value) if current_name == "": if "IOClass" in props: addr = props["IOClass"] s = obj.Object( self._struct_or_class("OSString"), offset=addr, vm=self.addr_space, ) current_name = "IOCLass: %s" % str(s) if current_name == "": serv = obj.Object( self._struct_or_class("IOService"), offset=reg_addr, vm=self.addr_space, ) buf = self.addr_space.read(serv.pwrMgt.Name, 128) if buf: idx = buf.find(b"\x00") if idx != -1: buf = buf[:idx] current_name = buf prop_string = "".join( ["%s=%x, " % (k, v) for (k, v) in list(props.items())]) # print "%-20s | %s | %s" % (current_name, keys, prop_string) offset = self.addr_space.profile.get_obj_offset( self._struct_or_class("_IOServiceInterestNotifier"), "chain") for (k, v) in list(props.items()): if k.find("nterest") != -1: cmd = obj.Object( self._struct_or_class("IOCommand"), offset=v, vm=self.addr_space, ) notifier_ptr = cmd.fCommandChain.next first_ptr = notifier_ptr last = 0 while notifier_ptr.is_valid() and notifier_ptr != last: notifier = obj.Object( self._struct_or_class("_IOServiceInterestNotifier"), offset=notifier_ptr - offset, vm=self.addr_space, ) if not notifier.handler.is_valid(): break last = notifier_ptr notifier_ptr = notifier.chain.next if notifier_ptr == first_ptr: break handler = notifier.handler.v() (module, handler_sym) = common.get_handler_name( kaddr_info, handler) yield k, handler, module, handler_sym for child in children: for k, handler, module, handler_sym in self.walk_child_links( child): yield k, handler, module, handler_sym