Skip to content

Commit

Permalink
Added offset to elf_strings
Browse files Browse the repository at this point in the history
the offset column in elf_strings lets us do a join with the
elf_dynamic_entries table for things like DT_NEEDED
  • Loading branch information
fzakaria committed Sep 26, 2023
1 parent d3bae7a commit 5a1264d
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 3 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,26 @@ For instance, the blow assumes the module name is `extension` from the
```
</details>

<details>
<summary>Determine the NEEDED entries for a program</summary>

_This may be improved in the future but for now there is a little knowledge of the
polymorphic nature of the dynamic entries needed_.

```console
sqlelf extension.cpython-311-x86_64-linux-gnu.so \
> --sql "SELECT elf_strings.path, elf_strings.value
FROM elf_dynamic_entries
INNER JOIN elf_strings ON elf_dynamic_entries.value = elf_strings.offset
WHERE elf_dynamic_entries.tag = 'NEEDED'"
┌───────────────────────────────────────────┬───────────────┐
│ path │ value │
│ extension.cpython-311-x86_64-linux-gnu.so │ libcblas.so.3 │
│ extension.cpython-311-x86_64-linux-gnu.so │ libc.so.6 │
└───────────────────────────────────────────┴───────────────┘
```
</details>

## Development

You may want to install the package in _editable mode_ as well to make development easier
Expand Down
29 changes: 26 additions & 3 deletions sqlelf/elf.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,15 +175,38 @@ def strings_generator() -> Iterator[dict[str, Any]]:
# Python also treats the final null in the string by creating
# an empty item so we chop it off.
# https://stackoverflow.com/a/18970869
for string in str(strtab.content[1:-1], "utf-8").split("\x00"):
yield {"path": binary_name, "section": strtab.name, "value": string}
strtab_name = strtab.name
for offset, string in split_with_index(
str(strtab.content[1:-1], "utf-8"), "\x00"
):
yield {
"path": binary_name,
"section": strtab_name,
"value": string,
# we add one from the offset since we removed the
# null byte at the start of the STRTAB
"offset": offset + 1,
}

return Generator.make_generator(
["path", "section", "value"],
["path", "section", "value", "offset"],
strings_generator,
)


def split_with_index(str: str, delimiter: str) -> list[tuple[int, str]]:
"""Split a string with the delimiter and return the index
of the start of the split."""
start = 0
result = []
for i, c in enumerate(str):
if c == delimiter:
result.append((start, str[start:i]))
start = i + 1
result.append((start, str[start:]))
return result


def make_symbols_generator(binaries: list[lief.Binary]) -> Generator:
"""Create the ELF symbols virtual table."""

Expand Down

0 comments on commit 5a1264d

Please sign in to comment.