elfpeek is a small ELF inspection tool written in Nia.
It is a Nia practice project inspired by Oblivionsage/elfpeek, with a focus on being a compact example of ELF parsing, CLI error handling, and standard-library usage in Nia.
The source entry point is src/main.nia. It reads an ELF file into one heap
buffer, parses ELF32/ELF64 headers in little or big endian, and exposes a few
quick inspection commands without a REPL.
This project is written in Nia. Follow the Nia
project's installation or development instructions so the nia command and the
matching standard library are available together.
src/main.nia- CLI parsing, file IO, and top-level resource cleanupsrc/elf.nia- ELF entry validation and command dispatchsrc/elf/types.nia- ELF constants, shared structs, and basic value helperssrc/elf/header.nia- ELF and program header parsing/printingsrc/elf/section.nia- section table parsing, dumps, and string extractionsrc/elf/symbol.nia- symbol table printing and address resolutionsrc/elf/reloc.nia- relocation table parsing/printingsrc/command.nia- command mode and parsed CLI request valuessrc/util.nia- byte-order readers and small output helperssrc/output.nia- standard-library stdout/stderr helpers and fixed formatting
nia check src/main.nia
nia emit --exe src/main.nia -o build/elfpeektests/run.shThe test fixtures cover small ELF32/ELF64 files in little and big endian plus a
few Linux ELF64 layout variants. They are copied from the MIT-licensed
Oblivionsage/elfpeek test corpus and committed directly under
tests/fixtures/.
./build/elfpeek <elf-file>
./build/elfpeek <elf-file> 0xaddr
./build/elfpeek <elf-file> dump <.section|@offset> [len]
./build/elfpeek <elf-file> strings [.section] [min-len]
./build/elfpeek <elf-file> relocsExample:
./build/elfpeek build/elfpeek
./build/elfpeek build/elfpeek dump .text 128
./build/elfpeek build/elfpeek strings .dynstr 4The input buffer is allocated through the Nia standard-library allocator based on
the file size and released after parsing. File IO and output use std::fs and
std::io; the project no longer declares libc bindings. Section data, symbol
names, dumps, strings, and relocations are read as slices over that buffer
instead of being copied into secondary storage.
ELF32 and ELF64 records are normalized into compact structs with u64 offsets
and addresses. Before any table entry is read, table_entry_offset checks both
index * entsize and base + relative; before a file slice is borrowed,
file_range checks offset + size and converts to usize bounds. Malformed
tables are truncated or skipped instead of driving unchecked reads.
ELF string tables stay in the byte/C-string domain. Section names, symbol names,
CLI paths, and raw dump targets are handled as CStr or &[u8] at the boundary
where that is the native representation; the tool only formats them after a NUL
terminator has been found inside the borrowed ELF string-table slice.
Output helpers return process::ExitCode!void, so write and flush failures are
propagated through .? style error handling rather than silently ignored. CLI
parse failures report usage errors instead of defaulting invalid numeric input to
zero.
MIT. See LICENSE.