elf-inspection

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

ELF Inspection

ELF文件检查

Purpose

用途

Guide agents through inspecting Linux ELF binaries: symbol tables, section layout, dynamic linking, debug info, and diagnosing linker errors.
指导Agent检查Linux ELF二进制文件:包括符号表、段布局、动态链接、调试信息,以及诊断链接器错误。

Triggers

触发场景

  • "What libraries does this binary depend on?"
  • "Why is this binary so large?"
  • "I have an
    undefined reference
    or symbol not found at runtime"
  • "How do I check if debug info is in this binary?"
  • "How do I find what symbols a library exports?"
  • "How do I check if a binary is PIE / has RELRO?"
  • "这个二进制文件依赖哪些库?"
  • "为什么这个二进制文件这么大?"
  • "我遇到了
    undefined reference
    或运行时符号未找到的错误"
  • "如何检查这个二进制文件中是否包含调试信息?"
  • "如何查看一个库导出了哪些符号?"
  • "如何检查一个二进制文件是否为PIE/是否启用RELRO?"

Workflow

操作流程

1. Quick overview:
file
and
size

1. 快速概览:使用
file
size
命令

bash
file prog                    # type, arch, linkage, stripped or not
size prog                    # section sizes: text, data, bss
size --format=sysv prog      # detailed per-section breakdown
bash
file prog                    # 查看文件类型、架构、链接方式、是否已剥离符号
size prog                    # 查看段大小:text、data、bss
size --format=sysv prog      # 按段详细分解大小

2. Dynamic dependencies:
ldd

2. 动态依赖检查:使用
ldd
命令

bash
ldd ./prog                   # show all shared lib dependencies
ldd -v ./prog                # verbose: include symbol versions
bash
ldd ./prog                   # 显示所有共享库依赖
ldd -v ./prog                # 详细模式:包含符号版本信息

Check why a library is loaded

检查某个库被加载的原因

ldd ./prog | grep libssl
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:

```bash
export LD_LIBRARY_PATH=/path/to/libs:$LD_LIBRARY_PATH
ldd ./libfoo.so

如果`ldd`显示`not found`,说明该共享库不在`LD_LIBRARY_PATH`或`/etc/ld.so.conf`配置的路径中。

修复方法:

```bash
export LD_LIBRARY_PATH=/path/to/libs:$LD_LIBRARY_PATH

Or install the library and run ldconfig

或者安装库后运行ldconfig

sudo ldconfig
undefined
sudo ldconfig
undefined

3. Symbols:
nm

3. 符号分析:使用
nm
命令

bash
nm 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
bash
nm prog                       # 显示所有符号(T=代码段、D=已初始化数据段、U=未定义等)
nm -D ./libfoo.so             # 仅显示动态符号
nm -C prog                    # 还原C++符号名称
nm --defined-only prog        # 仅显示已定义符号
nm -u prog                    # 仅显示未定义(需要外部提供的)符号
nm -S prog                    # 包含符号大小

Search for a symbol

搜索特定符号

nm -D /usr/lib/libssl.so | grep SSL_read

Symbol type codes:

- `T` / `t` — text (code): global / local
- `D` / `d` — data (initialised): global / local
- `B` / `b` — BSS (uninitialised): global / local
- `R` / `r` — read-only data: global / local
- `U` — undefined (needs to be provided at link time)
- `W` / `w` — weak symbol
nm -D /usr/lib/libssl.so | grep SSL_read

符号类型代码说明:

- `T` / `t` — 代码段:全局/局部
- `D` / `d` — 已初始化数据段:全局/局部
- `B` / `b` — 未初始化数据段(BSS):全局/局部
- `R` / `r` — 只读数据段:全局/局部
- `U` — 未定义(链接时需要外部提供)
- `W` / `w` — 弱符号

4. Sections:
readelf

4. 段信息查看:使用
readelf
命令

bash
readelf -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
bash
readelf -h prog               # ELF头信息(架构、类型、入口点)
readelf -S prog               # 显示所有段
readelf -l prog               # 程序头(段加载信息)
readelf -d prog               # 动态段信息(类似ldd但为原始数据)
readelf -s prog               # 符号表
readelf -r prog               # 重定位信息
readelf -n prog               # 注释信息(Build ID、ABI标签)
readelf --debug-dump=info prog | head -100  # DWARF调试信息
readelf -a prog               # 显示以上所有信息

5. Disassembly and source:
objdump

5. 反汇编与源码关联:使用
objdump
命令

bash
undefined
bash
undefined

Disassemble all code sections

反汇编所有代码段

objdump -d prog objdump -d -M intel prog # Intel syntax
objdump -d prog objdump -d -M intel prog # 使用Intel语法反汇编

Disassemble + intermix source (needs -g at compile time)

反汇编并混合显示源码(编译时需添加-g参数)

objdump -d -S prog
objdump -d -S prog

Disassemble specific symbol

反汇编特定符号

objdump -d prog | awk '/^[0-9a-f]+ <main>:/,/^$/'
objdump -d prog | awk '/^[0-9a-f]+ <main>:/,/^$/'

All sections (including data)

反汇编所有段(包括数据段)

objdump -D prog
objdump -D prog

Header info

头信息查看

objdump -f prog objdump -p prog # private headers (including needed libs)
undefined
objdump -f prog objdump -p prog # 私有头信息(包括依赖的库)
undefined

6. Binary hardening check

6. 二进制加固检查

bash
undefined
bash
undefined

Check for PIE, RELRO, stack canary, NX

检查PIE、RELRO、栈保护、NX位

Use checksec (install separately)

使用checksec工具(需单独安装)

checksec --file=prog
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)
undefined
readelf -h prog | grep Type # ET_DYN = PIE,ET_EXEC = 非PIE readelf -d prog | grep GNU_RELRO # 存在RELRO readelf -d prog | grep BIND_NOW # 完全RELRO readelf -s prog | grep __stack_chk # 存在栈保护 readelf -l prog | grep GNU_STACK # NX位(RW=不可执行栈,RWE=可执行栈)
undefined

7. Section size analysis (binary bloat)

7. 段大小分析(二进制膨胀排查)

bash
undefined
bash
undefined

Detailed section sizes

详细段大小

size --format=sysv prog | sort -k2 -nr | head -20
size --format=sysv prog | sort -k2 -nr | head -20

Per-object contribution (with -Wl,--print-map or bloaty)

各目标文件的贡献(使用-Wl,--print-map或bloaty工具)

Bloaty (install separately): https://github.com/google/bloaty

Bloaty工具(需单独安装):https://github.com/google/bloaty

bloaty prog
bloaty prog

Check stripped vs not

检查是否已剥离符号

file prog strip --strip-all -o prog.stripped prog ls -lh prog prog.stripped
undefined
file prog strip --strip-all -o prog.stripped prog ls -lh prog prog.stripped
undefined

8. Build ID

8. Build ID 查看

Build IDs uniquely identify a binary/library build, enabling
debuginfod
lookups.
bash
readelf -n prog | grep 'Build ID'
Build ID可唯一标识二进制文件/库的构建版本,支持通过
debuginfod
查找调试信息。
bash
readelf -n prog | grep 'Build ID'

or

file prog | grep BuildID
undefined
file prog | grep BuildID
undefined

9. Common diagnosis flows

9. 常见诊断流程

"undefined symbol at runtime"
bash
undefined
“运行时出现未定义符号错误”
bash
undefined

Which library was expected to provide it?

检查哪个库应该提供该符号

nm -D libfoo.so | grep mysymbol
nm -D libfoo.so | grep mysymbol

Is the library in the runtime path?

检查该库是否在运行时路径中

ldd ./prog | grep libfoo
ldd ./prog | grep libfoo

Check LD_PRELOAD / LD_LIBRARY_PATH

检查LD_PRELOAD / LD_LIBRARY_PATH环境变量


**"binary is too large"**

```bash
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.

**“二进制文件过大”**

```bash
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
快速参考请查看references/cheatsheet.md

Related skills

相关技能

  • Use
    skills/binaries/linkers-lto
    for linker flags and LTO
  • Use
    skills/binaries/binutils
    for
    ar
    ,
    strip
    ,
    objcopy
    ,
    addr2line
  • Use
    skills/debuggers/core-dumps
    for build ID and debuginfod usage
  • 链接器标志和LTO相关内容,请使用
    skills/binaries/linkers-lto
    技能
  • ar
    strip
    objcopy
    addr2line
    等工具相关内容,请使用
    skills/binaries/binutils
    技能
  • Build ID和debuginfod使用相关内容,请使用
    skills/debuggers/core-dumps
    技能