A tool that utilizes SQLite's virtual table functionality to allow you to explore Linux ELF objects through SQL.
Traditionally exploring an ELF file was limited to tools such as objdump
or readelf
. While these tools are full featured in their parsing capability, the output format and ability to ask exploratory questions is limited.
SQL
is the lingua franca for asking questions in a declarative manner.
Let's enhance our ability to introspect binaries!
---
title: ELF Schema
---
erDiagram
ELF_HEADERS ||--o{ ELF_SECTIONS : contains
ELF_HEADERS {
string path
int type
int version
int machine
int entry
}
ELF_SECTIONS {
string path
string name
int offset
int size
int type
blob content
}
ELF_HEADERS ||--o{ ELF_SYMBOLS : contains
ELF_SECTIONS ||--o{ ELF_SYMBOLS : defined
ELF_SYMBOLS {
string path
string name
string demangled_name
bool imported
bool exported
int section
int size
}
ELF_HEADERS ||--o{ ELF_DYNAMIC_ENTRIES : defined
ELF_DYNAMIC_ENTRIES {
string path
string tag
string value
}
ELF_SECTIONS ||--o{ ELF_INSTRUCTIONS : contains
ELF_INSTRUCTIONS {
string path
string section
string mnemonic
string address
string operands
}
ELF_SECTIONS ||--o{ ELF_STRINGS : contains
ELF_STRINGS {
string path
string section
string value
}
This repository can easily be installed via source, you simply need to have Nix or NixOS installed.
Afterwards utilizing devenv you can enter a shell with all the dependencies provided.
❯ devenv shell
Building shell ...
Entering shell ...
❯ pip install --editable .
❯ sqlelf --help
❯ sqlelf --help
usage: sqlelf [-h] FILE [FILE ...]
Analyze ELF files with the power of SQL
positional arguments:
FILE The ELF file to analyze
options:
-h, --help show this help message and exit
Note: You may provide directories for FILE
. Avoid giving too many binaries though since they must all be parsed at startup.
You simply have to fire up sqlelf
and give it a list of binaries or directories and start exploring ELF via SQL.
Simple demo showing a simple SELECT
:
❯ sqlelf /usr/bin/ruby --sql "select * from elf_headers"
/usr/bin/ruby|DYNAMIC|x86_64|CURRENT|4400
❯ sqlelf /usr/bin/ruby /bin/ls
SQLite version 3.40.1 (APSW 3.40.0.0)
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .header ON
sqlite> select * from elf_headers;
path|type|machine|version|entry
/usr/bin/ruby|3|62|1|4400
/bin/ls|3|62|1|25040
A more intricate demo showing an INNER JOIN
, WHERE
and GROUP BY
across two tables which each represent different portions of the ELF format.
SQLite version 3.40.1 (APSW 3.40.0.0)
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .header ON
sqlite> SELECT elf_headers.path, COUNT(*) as num_sections
..> FROM elf_headers
..> INNER JOIN elf_sections ON elf_headers.path = elf_sections.path
..> WHERE elf_headers.type = 3
..> GROUP BY elf_headers.path;
path|num_sections
/bin/ls|31
/usr/bin/pnmarith|27
/usr/bin/ruby|28