diff --git a/volatility3/framework/symbols/linux/kallsyms.py b/volatility3/framework/symbols/linux/kallsyms.py index 493a82538..264c13d3e 100644 --- a/volatility3/framework/symbols/linux/kallsyms.py +++ b/volatility3/framework/symbols/linux/kallsyms.py @@ -788,15 +788,27 @@ class Kallsyms(interfaces.configuration.VersionableInterface): if not self._is_module_ksym_address(address): return None - module = module or self.get_module_by_address(address) + module = module or self._get_module_by_address(address) if not module: + # This may occur if the kernel lacks the mod_tree implementation. + for ( + cur_module, + minimum_address, + maximum_address, + ) in self._module_memory_region: + if minimum_address <= address < maximum_address: + module = cur_module + break + + if not module: + # We couldn't find the module return None kassymbol = self._find_address_in_module_symbols(module, address) - if not kassymbol: - return None + if kassymbol: + return kassymbol - return kassymbol + return None def _find_address_in_module_symbols( self, @@ -814,6 +826,15 @@ class Kallsyms(interfaces.configuration.VersionableInterface): Returns: The matching KASSymbol if found; otherwise, returns None """ + # Before walking all the symbols, ensure the address belongs to this module + module_boundaries = module.get_module_address_boundaries() + if not module_boundaries: + return None + + minimum_address, maximum_address = module_boundaries + if not (minimum_address <= address < maximum_address): + return None + layer = self._context.layers[self._layer_name] for elf_sym_idx, elf_sym in enumerate(module.get_symbols()): if not elf_sym.get_name(): @@ -829,6 +850,18 @@ class Kallsyms(interfaces.configuration.VersionableInterface): return None + @functools.cached_property + def _module_memory_region( + self, + ) -> List[Tuple[interfaces.objects.ObjectInterface, int, int]]: + modules_region = [] + for module in lsmod.Lsmod.list_modules(self._context, self._module_name): + minimum_address, maximum_address = module.get_module_address_boundaries() + module_region = module, minimum_address, maximum_address + modules_region.append(module_region) + + return modules_region + @functools.lru_cache def _get_modules_memory_boundaries(self) -> Tuple[int, int]: """Determine the boundaries of the module allocation area @@ -870,7 +903,7 @@ class Kallsyms(interfaces.configuration.VersionableInterface): _address_min, address_max = self._get_modules_memory_boundaries() return address_max - def get_module_by_address( + def _get_module_by_address( self, address: int ) -> Optional[interfaces.objects.ObjectInterface]: """Searches for the module that contains the given memory address within its range. @@ -957,12 +990,10 @@ class Kallsyms(interfaces.configuration.VersionableInterface): ) module_ptr = mod_tree_node.mod if not module_ptr.is_readable(): - vollog.error("Something went wrong") + vollog.warning("Modules latch tree seems corrupt") return None return module_ptr.dereference() - else: - raise NotImplementedError("FIXME") return None