ByteScope

ELF Inspector

Open an ELF, read every structure — the binary never leaves this tab.

Your files never leave your browser — all processing is local.

Drop an ELF binary

or click to browse — parsed in this tab, never uploaded

What this tool does not do

Nothing is uploaded. The binary is read in this tab and parsed in a Web Worker — opening a file makes no network request at all. For a CTF binary or a customer's firmware, that is the whole point.

  • This reads ELF metadata. It is not a disassembler and it decompiles nothing: it can tell you .text is 41 KiB starting at offset 0x1000, and it cannot tell you what those instructions are.
  • DWARF debug information is not parsed. .debug_info, .debug_line and the rest are listed with their sizes like any other section, and their contents are only ever shown as bytes.
  • A malformed or deliberately corrupted ELF is a normal input here — CTF binaries are often mangled on purpose — so parsing degrades to partial results plus a warning instead of a blank page. Every warning is shown, never swallowed.

About this tool

Drop an ELF here — an executable, a .so, a kernel module, a .o, a CTF binary, a firmware image — and you get what readelf -a would tell you, in two panes wired together. On the left the structure tree: the ELF header field by field, the program headers, the section table, .dynsym and .symtab kept separate, .dynamic, every relocation section, the notes and the version definitions and requirements. On the right the file's bytes. Click any row and exactly the bytes it was decoded from light up; click a byte and the innermost structure covering it is revealed and selected.

The summary card answers the questions people actually open a binary to settle, before any table is touched: is it ELF32 or ELF64, which architecture and endianness, EXEC or DYN or REL, where the entry point is, and — where the architecture has decoded e_flags, as RISC-V and MIPS both do — what those flags mean. Then the derived facts: statically or dynamically linked and which loader it asks for, stripped or not, PIE or not, the build ID from .note.gnu.build-id, and whether PT_GNU_STACK carries PF_X, which is a real security-relevant fact and is stated plainly rather than left for you to spot in a table.

Nothing is uploaded, and for this audience that is the point rather than a feature. A CTF binary is someone's unsolved challenge and a firmware image is often a customer's property; posting either to a stranger's server to read a section header is a bad trade. The file is read by the tab, handed to a Web Worker, and parsed in memory — there is no upload endpoint, and you can confirm it in DevTools: opening a binary produces no network request at all. Parsing runs in the worker so a 60 MB binary never freezes the tab, and files past 128 MiB are refused with the reason rather than accepted and hung on.

Every name this page prints — machine, type, section type, symbol type, bind and visibility, relocation type, dynamic tag — is GNU binutils readelf's own spelling, because the parser is tested against real readelf output rather than against its own expectations. A 1900-symbol binary is ordinary and a 400,000-symbol one exists, so symbol and relocation tables are filtered, sorted and paged where the data lives instead of being rendered row by row into the page.

Frequently asked questions

Is my binary uploaded anywhere?

No. The file is read in this tab, transferred to a Web Worker, and parsed there. This page makes no network request while you use it, so you can leave DevTools open on the Network tab and watch it stay empty. That matters here more than on most tools: the binaries people bring to an ELF viewer are unreleased firmware, a customer's build, or a CTF challenge that other people are still working on.

Is this a disassembler or a decompiler?

Neither, and it does not pretend to be. It reads ELF metadata: it can tell you that .text is 41 KiB of executable PROGBITS starting at file offset 0x1000, that puts comes from libc.so.6 through a R_X86_64_JUMP_SLOT relocation, and that the entry point is at 0x1140 — and it cannot tell you what any of those instructions do. For that you want objdump, Ghidra, Binary Ninja or IDA, and none of them run in a browser tab.

Which architectures does it read?

All of them, because ELF's structure does not change with the target. x86-64, i386, ARM, AArch64, RISC-V, MIPS in both byte orders, PowerPC, S390, SPARC, Xtensa, AVR and the rest decode the same way; only the relocation type names and the meaning of e_flags are architecture-specific, and those come from a per-machine table. A machine the table does not know still parses in full and reports its raw e_machine number instead of inventing a name.

How large a binary can it open?

128 MiB. The whole file sits in the tab's memory to be parsed, and an object is built per symbol and per relocation on top of that, so peak usage is a multiple of the file size. Past this ceiling a tab is killed mid-parse, which to you looks like the page hanging, so the tool refuses the file and says so instead. Anything that large is usually an unstripped debug build — run readelf or objdump on it locally, or strip the debug sections first.

It says the binary is stripped. Where did the symbols go?

A stripped binary has no .symtab, which is where local and static function names live; strip removes that section outright. What survives is .dynsym, the dynamic symbol table, because the loader needs it to resolve imports and exports at run time — so you still see which libraries and which functions the binary calls, and the names of anything it exports, but not the names of its own internal functions. The summary card says which of the two you are looking at and how many symbols each holds.

The file is damaged and it still showed me something. Is that a bug?

It is the design. A truncated download, a hand-patched header, a section table that points past the end of the file — all of these are normal inputs for CTF work, and a viewer that answers a mangled ELF with a blank error page is useless exactly when you need it most. Whole-file problems (no ELF magic, an impossible class or byte order) still stop the parse, but a bad section, symbol or relocation degrades to a warning, and every warning is shown on the page instead of being swallowed.