From 558b860626d89e7b142e6ecab2c4ebd8b69a627c Mon Sep 17 00:00:00 2001 From: Farid Zakaria Date: Mon, 25 Sep 2023 02:12:24 +0000 Subject: [PATCH] added elf_version_definitions table Added the elf_version_definitions table which correlates to .gnu.version_d. Not 100% sure this table is needed since we capture the version information in the symbol table as well, but this is a closer approximation to the ELF format itself which should help others navigate. It would be great to have a foreign key reference here as well perhaps i the future. --- README.md | 6 ++++++ sqlelf/elf.py | 32 +++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9e77906..0f58902 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,12 @@ erDiagram string file string name } + ELF_HEADERS ||--o{ ELF_VERSION_DEFINITIONS : contains + ELF_VERSION_DEFINITIONS { + string path + string name + int flags + } ``` ## Installation diff --git a/sqlelf/elf.py b/sqlelf/elf.py index f686e30..0ea3bcf 100644 --- a/sqlelf/elf.py +++ b/sqlelf/elf.py @@ -221,7 +221,8 @@ def symbols_generator() -> Iterator[dict[str, Any]]: def make_version_requirements(binaries: list[lief.Binary]) -> Generator: """Create the ELF version requirements virtual table. - This should match the values found in .gnu.version_r section.""" + This should match the values found in .gnu.version_r section. + It's not 100% clear whether this table is needed since it's in the symbol table.""" def version_requirements_generator() -> Iterator[dict[str, Any]]: for binary in binaries: @@ -241,6 +242,34 @@ def version_requirements_generator() -> Iterator[dict[str, Any]]: return Generator.make_generator(version_requirements_generator) +def make_version_definitions(binaries: list[lief.Binary]) -> Generator: + """Create the ELF version requirements virtual table. + + This should match the values found in .gnu.version_d section. + It's not 100% clear whether this table is needed since it's in the symbol table""" + + def version_definitions_generator() -> Iterator[dict[str, Any]]: + for binary in binaries: + # super important that these accessors are pulled out of the tight loop + # as they can be costly + binary_name = binary.name + symbol_version_def = binary.symbols_version_definition # type: ignore + for version_definition in symbol_version_def: + flags = version_definition.flags + for aux_definition in version_definition.auxiliary_symbols: + yield { + "path": binary_name, + "name": aux_definition.name, + "flags": flags, + } + + return Generator( + ["path", "name", "flags"], + apsw.ext.VTColumnAccess.By_Name, + version_definitions_generator, + ) + + def symbols(binary: lief.Binary) -> Sequence[lief.ELF.Symbol]: """Use heuristic to either get static symbols or dynamic symbol table @@ -272,6 +301,7 @@ def register_virtual_tables( (make_strings_generator, "elf_strings"), (make_symbols_generator, "raw_elf_symbols"), (make_version_requirements, "elf_version_requirements"), + (make_version_definitions, "elf_version_definitions"), ] for factory, name in factory_and_names: generator = factory(binaries)