linux: module object extension: add method to know the module memory boundaries based on its symbols addresses and sizes

This commit is contained in:
Gustavo Moreira
2025-02-01 20:55:35 +11:00
parent 9175c1b1e9
commit 2af8b95ea4
@@ -270,6 +270,43 @@ class module(generic.GenericIntelProcess):
sym_address = elf_sym_obj.st_value & layer.address_mask
yield (sym_name, sym_address)
@functools.lru_cache
def get_module_address_boundaries(self) -> Tuple[int, int]:
"""Return the module address boundaries based on its symbol addresses"""
if not self.section_strtab or self.num_symtab < 1:
return None
elf_table_name = self.get_elf_table_name()
symbol_table_name = self.get_symbol_table_name()
is_64bit = symbols.symbol_table_is_64bit(self._context, symbol_table_name)
sym_name = "Elf64_Sym" if is_64bit else "Elf32_Sym"
sym_type = self._context.symbol_space.get_type(
elf_table_name + constants.BANG + sym_name
)
elf_syms = self._context.object(
symbol_table_name + constants.BANG + "array",
layer_name=self.vol.layer_name,
offset=self.section_symtab,
subtype=sym_type,
count=self.num_symtab,
)
# They should be sorted, but just in case
elf_syms_sorted = sorted(elf_syms, key=lambda x: x.st_value)
layer = self._context.layers[self.vol.layer_name]
# The first elf_sym is null
first_symbol = elf_syms_sorted[1]
last_symbol = elf_syms_sorted[-1]
minimum_address = first_symbol.st_value & layer.address_mask
maximum_address = (
last_symbol.st_value & layer.address_mask + last_symbol.st_size
)
return minimum_address, maximum_address
def get_symbol(self, wanted_sym_name) -> Optional[int]:
"""Get symbol address for a given symbol name"""
for sym_name, sym_address in self.get_symbols_names_and_addresses():