mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-09-08 02:37:39 +02:00
linux: kallsyms api: Added support for older kernels lacking mod_tree. Enhanced module address search performance by using the new module memory boundaries function
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user