def _generator(self): vmlinux = contexts.Module(self.context, self.config['vmlinux'], self.config['primary'], 0) op_members = vmlinux.get_type('file_operations').members seq_members = vmlinux.get_type('seq_operations').members tcp = ("tcp_seq_afinfo", ["tcp6_seq_afinfo", "tcp4_seq_afinfo"]) udp = ("udp_seq_afinfo", [ "udplite6_seq_afinfo", "udp6_seq_afinfo", "udplite4_seq_afinfo", "udp4_seq_afinfo" ]) protocols = [tcp, udp] for (struct_type, global_vars) in protocols: for global_var_name in global_vars: # this will lookup fail for the IPv6 protocols on kernels without IPv6 support try: global_var = vmlinux.get_symbol(global_var_name) except exceptions.SymbolError: continue global_var = vmlinux.object(object_type=struct_type, offset=global_var.address) for name, member, address in self._check_afinfo( global_var_name, global_var, op_members, seq_members): yield 0, (name, member, format_hints.Hex(address))
def list_kernel_events(cls, context: interfaces.context.ContextInterface, layer_name: str, darwin_symbols: str, filter_func: Callable[[int], bool] = lambda _: False) -> \ Iterable[Tuple[interfaces.objects.ObjectInterface, interfaces.objects.ObjectInterface, interfaces.objects.ObjectInterface]]: """ Returns the kernel event filters registered Return values: A tuple of 3 elements: 1) The name of the process that registered the filter 2) The process ID of the process that registered the filter 3) The object of the associated kernel event filter """ kernel = contexts.Module(context, darwin_symbols, layer_name, 0) list_tasks = pslist.PsList.get_list_tasks( pslist.PsList.pslist_methods[0]) for task in list_tasks(context, layer_name, darwin_symbols, filter_func): task_name = utility.array_to_string(task.p_comm) pid = task.p_pid for kn in cls._get_task_kevents(kernel, task): yield task_name, pid, kn
def _generator(self): kernel = contexts.Module(self.context, self.config['darwin'], self.config['primary'], 0) mods = lsmod.Lsmod.list_modules(self.context, self.config['primary'], self.config['darwin']) handlers = mac.MacUtilities.generate_kernel_handler_info( self.context, self.config['primary'], kernel, mods) for scope in self.list_kauth_scopes(self.context, self.config['primary'], self.config['darwin']): callback = scope.ks_callback if callback == 0: continue module_name, symbol_name = mac.MacUtilities.lookup_module_address( self.context, handlers, callback) identifier = utility.pointer_to_string(scope.ks_identifier, 128) yield (0, (identifier, format_hints.Hex(scope.ks_idata), len([l for l in scope.get_listeners()]), format_hints.Hex(callback), module_name, symbol_name))
def _generator(self): kernel = contexts.Module(self._context, self.config['darwin'], self.config['primary'], 0) mods = lsmod.Lsmod.list_modules(self.context, self.config['primary'], self.config['darwin']) handlers = mac.MacUtilities.generate_kernel_handler_info( self.context, self.config['primary'], kernel, mods) table = kernel.object_from_symbol(symbol_name="mach_trap_table") for i, ent in enumerate(table): try: call_addr = ent.mach_trap_function.dereference().vol.offset except exceptions.InvalidAddressException: continue if not call_addr or call_addr == 0: continue module_name, symbol_name = mac.MacUtilities.lookup_module_address( self.context, handlers, call_addr) yield (0, (format_hints.Hex(table.vol.offset), "TrapTable", i, format_hints.Hex(call_addr), module_name, symbol_name))
def _generator(self): kernel = contexts.Module(self._context, self.config['darwin'], self.config['primary'], 0) mods = lsmod.Lsmod.list_modules(self.context, self.config['primary'], self.config['darwin']) handlers = mac.MacUtilities.generate_kernel_handler_info( self.context, self.config['primary'], kernel, mods) sysctl_list = kernel.object_from_symbol(symbol_name="sysctl__children") for sysctl, name, val in self._process_sysctl_list( kernel, sysctl_list): try: check_addr = sysctl.oid_handler except exceptions.InvalidAddressException: continue module_name, symbol_name = mac.MacUtilities.lookup_module_address( self.context, handlers, check_addr) yield (0, (name, sysctl.oid_number, sysctl.get_perms(), format_hints.Hex(check_addr), val, module_name, symbol_name))
def list_tasks_pid_hash_table(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 using the pid hash table Args: context: The context to retrieve required elements (layers, symbol tables) from layer_name: The name of the layer on which to operate darwin_symbols: The name of the table containing the kernel symbols filter_func: A function which takes a task object and returns True if the task should be ignored/filtered Returns: The list of task objects from the `layer_name` layer's `tasks` list after filtering """ kernel = contexts.Module(context, darwin_symbols, layer_name, 0) table_size = kernel.object_from_symbol(symbol_name="pidhash") pidhashtbl = kernel.object_from_symbol(symbol_name="pidhashtbl") proc_array = kernel.object(object_type="array", offset=pidhashtbl, count=table_size + 1, subtype=kernel.get_type("pidhashhead")) for proc_list in proc_array: for proc in mac.MacUtilities.walk_list_head(proc_list, "p_hash"): if not filter_func(proc): yield proc
def _generator(self): vmlinux = contexts.Module(self.context, self.config['vmlinux'], self.config['primary'], 0) modules = lsmod.Lsmod.list_modules(self.context, self.config['primary'], self.config['vmlinux']) handlers = linux.LinuxUtilities.generate_kernel_handler_info( self.context, self.config['primary'], self.config['vmlinux'], modules) try: knl_addr = vmlinux.object_from_symbol("keyboard_notifier_list") except exceptions.SymbolError: knl_addr = None if not knl_addr: raise TypeError( "This plugin requires the keyboard_notifier_list structure. " "This structure is not present in the supplied symbol table. " "This means you are either analyzing an unsupported kernel version or that your symbol table is corrupt." ) knl = vmlinux.object(object_type="atomic_notifier_head", offset=knl_addr.vol.offset) for call_back in linux.LinuxUtilities.walk_internal_list( vmlinux, "notifier_block", "next", knl.head): call_addr = call_back.notifier_call module_name, symbol_name = linux.LinuxUtilities.lookup_module_address( self.context, handlers, call_addr) yield (0, [format_hints.Hex(call_addr), module_name, symbol_name])
def _generator(self): """ Lists the registered VFS event watching processes Also lists which event(s) a process is registered for """ kernel = contexts.Module(self.context, self.config['darwin'], self.config['primary'], 0) watcher_table = kernel.object_from_symbol("watcher_table") for watcher in watcher_table: if watcher == 0: continue task_name = utility.array_to_string(watcher.proc_name) task_pid = watcher.pid events = [] try: event_array = kernel.object(object_type = "array", offset = watcher.event_list, count = 13, subtype = kernel.get_type("unsigned char")) except exceptions.InvalidAddressException: continue for i, event in enumerate(event_array): if event == 1: events.append(self.event_types[i]) if events != []: yield (0, (task_name, task_pid, ",".join(events)))
def _generator(self): """ Enumerates the listeners for each kauth scope """ kernel = contexts.Module(self.context, self.config['darwin'], self.config['primary'], 0) mods = lsmod.Lsmod.list_modules(self.context, self.config['primary'], self.config['darwin']) handlers = mac.MacUtilities.generate_kernel_handler_info( self.context, self.config['primary'], kernel, mods) for scope in kauth_scopes.Kauth_scopes.list_kauth_scopes( self.context, self.config['primary'], self.config['darwin']): scope_name = utility.pointer_to_string(scope.ks_identifier, 128) for listener in scope.get_listeners(): callback = listener.kll_callback if callback == 0: continue module_name, symbol_name = mac.MacUtilities.lookup_module_address( self.context, handlers, callback) yield (0, (scope_name, format_hints.Hex(listener.kll_idata), format_hints.Hex(callback), module_name, symbol_name))
def _generator(self, mods: Iterator[Any]): kernel = contexts.Module(self._context, self.config['darwin'], self.config['primary'], 0) handlers = mac.MacUtilities.generate_kernel_handler_info(self.context, self.config['primary'], kernel, mods) policy_list = kernel.object_from_symbol(symbol_name = "mac_policy_list").cast("mac_policy_list") entries = kernel.object(object_type = "array", offset = policy_list.entries.dereference().vol.offset, subtype = kernel.get_type('mac_policy_list_element'), count = policy_list.staticmax + 1) for i, ent in enumerate(entries): # I don't know how this can happen, but the kernel makes this check all over the place # the policy isn't useful without any ops so a rootkit can't abuse this try: mpc = ent.mpc.dereference() ops = mpc.mpc_ops.dereference() except exceptions.InvalidAddressException: continue try: ent_name = utility.pointer_to_string(mpc.mpc_name, 255) except exceptions.InvalidAddressException: ent_name = "N/A" for check in ops.vol.members: call_addr = getattr(ops, check) if call_addr is None or call_addr == 0: continue module_name, symbol_name = mac.MacUtilities.lookup_module_address(self.context, handlers, call_addr) yield (0, (check, ent_name, format_hints.Hex(call_addr), module_name, symbol_name))
def _generator(self): kernel = contexts.Module(self._context, self.config['darwin'], self.config['primary'], 0) try: list_head = kernel.object_from_symbol(symbol_name="ifnet_head") except exceptions.SymbolError: list_head = kernel.object_from_symbol( symbol_name="dlil_ifnet_head") for ifnet in mac.MacUtilities.walk_tailq(list_head, "if_link"): name = utility.pointer_to_string(ifnet.if_name, 32) unit = ifnet.if_unit prom = ifnet.if_flags & 0x100 == 0x100 # IFF_PROMISC sock_addr_dl = ifnet.sockaddr_dl() if sock_addr_dl is None: mac_addr = renderers.UnreadableValue() else: mac_addr = str(sock_addr_dl) for ifaddr in mac.MacUtilities.walk_tailq(ifnet.if_addrhead, "ifa_link"): ip = ifaddr.ifa_addr.get_address() yield (0, ("{0}{1}".format(name, unit), ip, mac_addr, prom))
def list_modules( cls, context: interfaces.context.ContextInterface, layer_name: str, vmlinux_symbols: str ) -> Iterable[interfaces.objects.ObjectInterface]: """Lists all the modules in the primary layer. Args: context: The context to retrieve required elements (layers, symbol tables) from layer_name: The name of the layer on which to operate vmlinux_symbols: The name of the table containing the kernel symbols Yields: The modules present in the `layer_name` layer's modules list This function will throw a SymbolError exception if kernel module support is not enabled. """ vmlinux = contexts.Module(context, vmlinux_symbols, layer_name, 0) modules = vmlinux.object_from_symbol( symbol_name="modules").cast("list_head") table_name = modules.vol.type_name.split(constants.BANG)[0] for module in modules.to_list(table_name + constants.BANG + "module", "list"): yield module
def _generator(self): vmlinux = contexts.Module(self.context, self.config['vmlinux'], self.config['primary'], 0) ptr_sz = vmlinux.get_type("pointer").size if ptr_sz == 4: table_name = "32bit" else: table_name = "64bit" try: table_info = self._get_table_info(vmlinux, "sys_call_table", ptr_sz) except exceptions.SymbolError: vollog.error("Unable to find the system call table. Exiting.") return tables = [(table_name, table_info)] # this table is only present on 64 bit systems with 32 bit emulation # enabled in order to support 32 bit programs and libraries # if the symbol isn't there then the support isn't in the kernel and so we skip it try: ia32_symbol = self.context.symbol_space.get_symbol( vmlinux.name + constants.BANG + "ia32_sys_call_table") except exceptions.SymbolError: ia32_symbol = None if ia32_symbol != None: ia32_info = self._get_table_info(vmlinux, "ia32_sys_call_table", ptr_sz) tables.append(("32bit", ia32_info)) for (table_name, (tableaddr, tblsz)) in tables: table = vmlinux.object(object_type="array", subtype=vmlinux.get_type("pointer"), offset=tableaddr, count=tblsz) for (i, call_addr) in enumerate(table): if not call_addr: continue symbols = list( self.context.symbol_space.get_symbols_by_location( call_addr)) if len(symbols) > 0: sym_name = str(symbols[0].split(constants.BANG)[1]) if constants.BANG in symbols[0] else \ str(symbols[0]) else: sym_name = "UNKNOWN" yield (0, (format_hints.Hex(tableaddr), table_name, i, format_hints.Hex(call_addr), sym_name))
def __init__(self, context: interfaces.context.ContextInterface, config: interfaces.configuration.HierarchicalDict): self._context = context self._config = config vmlinux = context.modules[self._config['kernel']] self.layer_name = kernel.layer_name # type: ignore symbol_table_name = vmlinux.symbol_table_name # type: ignore self.vmlinux = contexts.Module(context, symbol_table_name, self.layer_name, 0) # type: ignore self.long_unsigned_int_size = self.vmlinux.get_type( 'long unsigned int').size
def _generator(self): vmlinux = contexts.Module(self.context, self.config['vmlinux'], self.config['primary'], 0) modules = lsmod.Lsmod.list_modules(self.context, self.config['primary'], self.config['vmlinux']) handlers = linux.LinuxUtilities.generate_kernel_handler_info( self.context, self.config['primary'], self.config['vmlinux'], modules) try: tty_drivers = vmlinux.object_from_symbol("tty_drivers").cast( "list_head") except exceptions.SymbolError: tty_drivers = None if not tty_drivers: raise TypeError( "This plugin requires the tty_drivers structure." "This structure is not present in the supplied symbol table." "This means you are either analyzing an unsupported kernel version or that your symbol table is corrupt." ) for tty in tty_drivers.to_list( vmlinux.name + constants.BANG + "tty_driver", "tty_drivers"): try: ttys = utility.array_of_pointers(tty.ttys.dereference(), count=tty.num, subtype=vmlinux.name + constants.BANG + "tty_struct", context=self.context) except exceptions.PagedInvalidAddressException: continue for tty_dev in ttys: if tty_dev == 0: continue name = utility.array_to_string(tty_dev.name) recv_buf = tty_dev.ldisc.ops.receive_buf module_name, symbol_name = linux.LinuxUtilities.lookup_module_address( self.context, handlers, recv_buf) yield (0, (name, format_hints.Hex(recv_buf), module_name, symbol_name))
def _generator(self): vmlinux = contexts.Module(self.context, self.config['vmlinux'], self.config['primary'], 0) kset_modules = self.get_kset_modules(vmlinux) lsmod_modules = set( str(utility.array_to_string(modules.name)) for modules in lsmod.Lsmod.list_modules( self.context, self.config['primary'], self.config['vmlinux'])) for mod_name in set(kset_modules.keys()).difference(lsmod_modules): yield (0, (format_hints.Hex(kset_modules[mod_name]), str(mod_name)))
def list_modules(cls, context: interfaces.context.ContextInterface, layer_name: str, darwin_symbols: str): """Lists all the modules in the primary layer. Args: context: The context to retrieve required elements (layers, symbol tables) from layer_name: The name of the layer on which to operate darwin_symbols: The name of the table containing the kernel symbols Returns: A list of modules from the `layer_name` layer """ kernel = contexts.Module(context, darwin_symbols, layer_name, 0) kernel_layer = context.layers[layer_name] kmod_ptr = kernel.object_from_symbol(symbol_name = "kmod") try: kmod = kmod_ptr.dereference().cast("kmod_info") except exceptions.InvalidAddressException: return [] yield kmod try: kmod = kmod.next except exceptions.InvalidAddressException: return [] seen = set() while kmod != 0 and \ kmod not in seen and \ len(seen) < 1024: kmod_obj = kmod.dereference() if not kernel_layer.is_valid(kmod_obj.vol.offset, kmod_obj.vol.size): break seen.add(kmod) yield kmod try: kmod = kmod.next except exceptions.InvalidAddressException: return
def list_mounts(cls, context: interfaces.context.ContextInterface, layer_name: str, darwin_symbols: str): """Lists all the mount structures in the primary layer. Args: context: The context to retrieve required elements (layers, symbol tables) from layer_name: The name of the layer on which to operate darwin_symbols: The name of the table containing the kernel symbols Returns: A list of mount structures from the `layer_name` layer """ kernel = contexts.Module(context, darwin_symbols, layer_name, 0) list_head = kernel.object_from_symbol(symbol_name="mountlist") for mount in mac.MacUtilities.walk_tailq(list_head, "mnt_list"): yield mount
def list_tasks_allproc(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 processes in the primary layer based on the allproc method Args: context: The context to retrieve required elements (layers, symbol tables) from layer_name: The name of the layer on which to operate darwin_symbols: The name of the table containing the kernel symbols filter_func: A function which takes a process object and returns True if the process should be ignored/filtered Returns: The list of process objects from the processes linked list after filtering """ kernel = contexts.Module(context, darwin_symbols, layer_name, 0) kernel_layer = context.layers[layer_name] proc = kernel.object_from_symbol(symbol_name="allproc").lh_first seen = {} # type: Dict[int, int] while proc is not None and proc.vol.offset != 0: if proc.vol.offset in seen: vollog.log( logging.INFO, "Recursive process list detected (a result of non-atomic acquisition)." ) break else: seen[proc.vol.offset] = 1 if kernel_layer.is_valid(proc.vol.offset, proc.vol.size) and not filter_func(proc): yield proc try: proc = proc.p_list.le_next.dereference() except exceptions.InvalidAddressException: break
def list_tasks_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 based on the tasks queue Args: context: The context to retrieve required elements (layers, symbol tables) from layer_name: The name of the layer on which to operate darwin_symbols: The name of the table containing the kernel symbols filter_func: A function which takes a task object and returns True if the task should be ignored/filtered Returns: The list of task objects from the `layer_name` layer's `tasks` list after filtering """ kernel = contexts.Module(context, darwin_symbols, layer_name, 0) kernel_layer = context.layers[layer_name] queue_entry = kernel.object_from_symbol(symbol_name="tasks") seen = {} # type: Dict[int, int] 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 try: proc = task.bsd_info.dereference().cast("proc") except exceptions.InvalidAddressException: continue if kernel_layer.is_valid(proc.vol.offset, proc.vol.size) and not filter_func(proc): yield proc
def list_kauth_scopes(cls, context: interfaces.context.ContextInterface, layer_name: str, darwin_symbols: str, filter_func: Callable[[int], bool] = lambda _: False) -> \ Iterable[Tuple[interfaces.objects.ObjectInterface, interfaces.objects.ObjectInterface, interfaces.objects.ObjectInterface]]: """ Enumerates the registered kauth scopes and yields each object Uses smear-safe enumeration API """ kernel = contexts.Module(context, darwin_symbols, layer_name, 0) scopes = kernel.object_from_symbol("kauth_scopes") for scope in mac.MacUtilities.walk_tailq(scopes, "ks_link"): yield scope
def _generator(self): kernel = contexts.Module(self.context, self.config['darwin'], self.config['primary'], 0) mods = lsmod.Lsmod.list_modules(self.context, self.config['primary'], self.config['darwin']) handlers = mac.MacUtilities.generate_kernel_handler_info(self.context, self.config['primary'], kernel, mods) real_ncpus = kernel.object_from_symbol(symbol_name = "real_ncpus") cpu_data_ptrs_ptr = kernel.get_symbol("cpu_data_ptr").address cpu_data_ptrs_addr = kernel.object(object_type = "pointer", offset = cpu_data_ptrs_ptr, subtype = kernel.get_type('long unsigned int')) cpu_data_ptrs = kernel.object(object_type = "array", offset = cpu_data_ptrs_addr, subtype = kernel.get_type('cpu_data'), count = real_ncpus) for cpu_data_ptr in cpu_data_ptrs: try: queue = cpu_data_ptr.rtclock_timer.queue.head except exceptions.InvalidAddressException: break for timer in queue.walk_list(queue, "q_link", "call_entry"): try: handler = timer.func.dereference().vol.offset except exceptions.InvalidAddressException: continue if timer.has_member("entry_time"): entry_time = timer.entry_time else: entry_time = -1 module_name, symbol_name = mac.MacUtilities.lookup_module_address(self.context, handlers, handler) yield (0, (format_hints.Hex(handler), format_hints.Hex(timer.param0), format_hints.Hex(timer.param1), \ timer.deadline, entry_time, module_name, symbol_name))
def _generator(self): kernel = contexts.Module(self._context, self.config['darwin'], self.config['primary'], 0) mods = lsmod.Lsmod.list_modules(self.context, self.config['primary'], self.config['darwin']) handlers = mac.MacUtilities.generate_kernel_handler_info( self.context, self.config['primary'], kernel, mods) members_to_check = [ "sf_unregistered", "sf_attach", "sf_detach", "sf_notify", "sf_getpeername", "sf_getsockname", "sf_data_in", "sf_data_out", "sf_connect_in", "sf_connect_out", "sf_bind", "sf_setoption", "sf_getoption", "sf_listen", "sf_ioctl" ] filter_list = kernel.object_from_symbol(symbol_name="sock_filter_head") for filter_container in mac.MacUtilities.walk_tailq( filter_list, "sf_global_next"): current_filter = filter_container.sf_filter filter_name = utility.pointer_to_string(current_filter.sf_name, count=128) try: filter_socket = filter_container.sf_entry_head.sfe_socket.vol.offset except exceptions.InvalidAddressException: filter_socket = 0 for member in members_to_check: check_addr = current_filter.member(attr=member) if check_addr == 0: continue module_name, symbol_name = mac.MacUtilities.lookup_module_address( self.context, handlers, check_addr) yield (0, (format_hints.Hex(current_filter.vol.offset), filter_name, member, \ format_hints.Hex(filter_socket), format_hints.Hex(check_addr), module_name, symbol_name))
def generate_kernel_handler_info( cls, context: interfaces.context.ContextInterface, layer_name: str, kernel_name: str, mods_list: Iterator[interfaces.objects.ObjectInterface] ) -> List[Tuple[str, int, int]]: """ A helper function that gets the beginning and end address of the kernel module """ kernel = contexts.Module(context, kernel_name, layer_name, 0) mask = context.layers[layer_name].address_mask start_addr = kernel.object_from_symbol("_text") start_addr = start_addr.vol.offset & mask end_addr = kernel.object_from_symbol("_etext") end_addr = end_addr.vol.offset & mask return [(constants.linux.KERNEL_NAME, start_addr, end_addr)] + \ LinuxUtilities.mask_mods_list(context, layer_name, mods_list)
def list_tasks( cls, context: interfaces.context.ContextInterface, layer_name: str, vmlinux_symbols: str, filter_func: Callable[[int], bool] = lambda _: False ) -> Iterable[interfaces.objects.ObjectInterface]: """Lists all the tasks in the primary layer. Args: context: The context to retrieve required elements (layers, symbol tables) from layer_name: The name of the layer on which to operate vmlinux_symbols: The name of the table containing the kernel symbols Yields: Process objects """ vmlinux = contexts.Module(context, vmlinux_symbols, layer_name, 0) init_task = vmlinux.object_from_symbol(symbol_name="init_task") for task in init_task.tasks: if not filter_func(task): yield task
def _generator(self): vmlinux = contexts.Module(self.context, self.config['vmlinux'], self.config['primary'], 0) modules = lsmod.Lsmod.list_modules(self.context, self.config['primary'], self.config['vmlinux']) handlers = linux.LinuxUtilities.generate_kernel_handler_info(self.context, self.config['primary'], self.config['vmlinux'], modules) is_32bit = not symbols.symbol_table_is_64bit(self.context, self.config["vmlinux"]) idt_table_size = 256 address_mask = self.context.layers[self.config['primary']].address_mask # hw handlers + system call check_idxs = list(range(0, 20)) + [128] if is_32bit: if vmlinux.has_type("gate_struct"): idt_type = "gate_struct" else: idt_type = "desc_struct" else: if vmlinux.has_type("gate_struct64"): idt_type = "gate_struct64" elif vmlinux.has_type("gate_struct"): idt_type = "gate_struct" else: idt_type = "idt_desc" addrs = vmlinux.object_from_symbol("idt_table") table = vmlinux.object(object_type = 'array', offset = addrs.vol.offset, subtype = vmlinux.get_type(idt_type), count = idt_table_size) for i in check_idxs: ent = table[i] if not ent: continue if hasattr(ent, "Address"): idt_addr = ent.Address else: low = ent.offset_low middle = ent.offset_middle if hasattr(ent, "offset_high"): high = ent.offset_high else: high = 0 idt_addr = (high << 32) | (middle << 16) | low idt_addr = idt_addr & address_mask module_name, symbol_name = linux.LinuxUtilities.lookup_module_address(self.context, handlers, idt_addr) yield (0, [format_hints.Hex(i), format_hints.Hex(idt_addr), module_name, symbol_name])