skills/binaries/elf-inspection/SKILL.md
ELF binary inspection skill for Linux. Use when examining ELF executables or shared libraries with readelf, objdump, nm, or ldd to understand symbol visibility, section layout, dynamic dependencies, build IDs, or relocation entries. Activates on queries about ELF format, shared library dependencies, symbol tables, section sizes, DWARF debug info in binaries, binary bloat analysis, or undefined symbol errors.
npx skillsauth add mohitmishra786/low-level-dev-skills elf-inspectionInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Guide agents through inspecting Linux ELF binaries: symbol tables, section layout, dynamic linking, debug info, and diagnosing linker errors.
undefined reference or symbol not found at runtime"file and sizefile prog # type, arch, linkage, stripped or not
size prog # section sizes: text, data, bss
size --format=sysv prog # detailed per-section breakdown
lddldd ./prog # show all shared lib dependencies
ldd -v ./prog # verbose: include symbol versions
# Check why a library is loaded
ldd ./prog | grep libssl
# For a library (not an executable)
ldd ./libfoo.so
If ldd shows not found, the shared library is missing from LD_LIBRARY_PATH or /etc/ld.so.conf.
Fix:
export LD_LIBRARY_PATH=/path/to/libs:$LD_LIBRARY_PATH
# Or install the library and run ldconfig
sudo ldconfig
nmnm prog # all symbols (T=text, D=data, U=undefined, etc.)
nm -D ./libfoo.so # dynamic symbols only
nm -C prog # demangle C++ symbols
nm --defined-only prog # only defined symbols
nm -u prog # only undefined (needed) symbols
nm -S prog # include symbol size
# Search for a symbol
nm -D /usr/lib/libssl.so | grep SSL_read
Symbol type codes:
T / t — text (code): global / localD / d — data (initialised): global / localB / b — BSS (uninitialised): global / localR / r — read-only data: global / localU — undefined (needs to be provided at link time)W / w — weak symbolreadelfreadelf -h prog # ELF header (arch, type, entry point)
readelf -S prog # all sections
readelf -l prog # program headers (segments)
readelf -d prog # dynamic section (like ldd but raw)
readelf -s prog # symbol table
readelf -r prog # relocations
readelf -n prog # notes (build ID, ABI tag)
readelf --debug-dump=info prog | head -100 # DWARF info
readelf -a prog # all of the above
objdump# Disassemble all code sections
objdump -d prog
objdump -d -M intel prog # Intel syntax
# Disassemble + intermix source (needs -g at compile time)
objdump -d -S prog
# Disassemble specific symbol
objdump -d prog | awk '/^[0-9a-f]+ <main>:/,/^$/'
# All sections (including data)
objdump -D prog
# Header info
objdump -f prog
objdump -p prog # private headers (including needed libs)
# Check for PIE, RELRO, stack canary, NX
# Use checksec (install separately)
checksec --file=prog
# Manual checks:
readelf -h prog | grep Type # ET_DYN = PIE, ET_EXEC = non-PIE
readelf -d prog | grep GNU_RELRO # RELRO present
readelf -d prog | grep BIND_NOW # full RELRO
readelf -s prog | grep __stack_chk # stack protector
readelf -l prog | grep GNU_STACK # NX bit (RW = no exec, RWE = exec stack)
# Detailed section sizes
size --format=sysv prog | sort -k2 -nr | head -20
# Per-object contribution (with -Wl,--print-map or bloaty)
# Bloaty (install separately): https://github.com/google/bloaty
bloaty prog
# Check stripped vs not
file prog
strip --strip-all -o prog.stripped prog
ls -lh prog prog.stripped
Build IDs uniquely identify a binary/library build, enabling debuginfod lookups.
readelf -n prog | grep 'Build ID'
# or
file prog | grep BuildID
"undefined symbol at runtime"
# Which library was expected to provide it?
nm -D libfoo.so | grep mysymbol
# Is the library in the runtime path?
ldd ./prog | grep libfoo
# Check LD_PRELOAD / LD_LIBRARY_PATH
"binary is too large"
size --format=sysv prog | sort -k2 -nr | head
nm -S --defined-only prog | sort -k2 -nr | head -20
objdump -d prog | awk '/^[0-9a-f]+ </{fn=$2} /^[0-9a-f]/{count[fn]++} END{for(f in count) print count[f], f}' | sort -nr | head -20
For a quick reference, see references/cheatsheet.md.
skills/binaries/linkers-lto for linker flags and LTOskills/binaries/binutils for ar, strip, objcopy, addr2lineskills/debuggers/core-dumps for build ID and debuginfod usagedevelopment
QEMU/KVM skill for virtualization and kernel development. Use when running qemu-system-x86_64 with KVM, configuring virtio devices, VFIO passthrough, QMP monitor, libvirt, or booting custom kernels. Activates on queries about QEMU, KVM, virtio, VFIO, virsh, virt-install, or -kernel -append.
development
Hardware virtualization internals skill for Intel VT-x and AMD-V. Use when studying VMCS/VMCB, EPT/NPT page tables, VMEXIT handling, APIC virtualization, or building minimal hypervisors. Activates on queries about VMX, SVM, VMCS, EPT, NPT, VMEXIT, or type-1 hypervisor.
testing
Linux containers internals skill for namespaces, cgroups, and OCI. Use when understanding clone/unshare namespaces, cgroups v2 limits, overlayfs, runc, seccomp profiles, capabilities, or escape mitigations. Activates on queries about namespaces, cgroups, overlayfs, runc, seccomp-bpf, OCI spec, or container escape.
tools
Reverse engineering skill for binary analysis. Use when decompiling with Ghidra, analyzing with radare2, scripting RE tools, triaging with strings/file/xxd, or diffing binaries. Activates on queries about Ghidra, radare2, r2, decompiler, Binary Ninja, Diaphora, or stripped binary analysis.