Linux readelf 命令详解|ELF 文件逆向分析、二进制查看一站式教程
1. 命令简介
readelf 是一个用于显示 ELF(Executable and Linkable Format)格式文件详细信息的命令行工具。它可以显示 ELF 文件的各种头部信息、节(section)信息、段(segment)信息、符号表、重定位条目等。与 objdump 类似,但 readelf 不依赖于 BFD(Binary File Descriptor)库,因此能提供更底层、更精确的 ELF 信息,且不受 BFD 库潜在错误的影响。
主要用途:
- 分析可执行文件、共享库、目标文件和静态库的 ELF 结构。
- 调试和验证编译、链接过程。
- 检查文件的架构、字节序、入口点、节 / 段布局等。
支持的文件类型:
- 可重定位文件(Relocatable files,如 .o 文件)
- 可执行文件(Executable files,如 a.out)
- 共享目标文件(Shared object files,如 .so 文件)
- 包含 ELF 文件的静态库(如 .a 文件)
2. 语法格式
基本语法如下:
bash
运行
readelf [选项] elf-file(s)参数说明:
- elf-file (s):一个或多个 ELF 格式的目标文件。可以是可执行文件、共享库、目标文件或静态库。
- 除了 -v(版本)和 -H(帮助)选项外,必须至少指定一个其他选项来指定要显示的信息类型。
3. 常用选项及说明
表格
| 选项 | 长选项 | 说明 |
|---|---|---|
| -a | --all | 显示所有信息,等价于 -h -l -S -s -r -d -V -A -I。 |
| -h | --file-header | 显示 ELF 文件头(ELF header)信息。 |
| -l | --program-headers 或 --segments | 显示程序头表(段头)信息。 |
| -S | --section-headers 或 --sections | 显示节头表信息。 |
| -s | --syms 或 --symbols | 显示符号表信息。 |
| -e | --headers | 显示所有头部信息,等价于 -h -l -S。 |
| -r | --relocs | 显示重定位条目信息。 |
| -d | --dynamic | 显示动态段(Dynamic segment)信息。 |
| -n | --notes | 显示 NOTE 段信息(如内核注释)。 |
| -V | --version-info | 显示版本段信息。 |
| -A | --arch-specific | 显示 CPU 架构特定信息。 |
| -g | --section-groups | 显示节组信息。 |
| -t | --section-details | 显示节的详细信息(比 -S 更详细)。 |
| -u | --unwind | 显示 unwind 段信息(当前主要支持 IA64 架构)。 |
| -D | --use-dynamic | 使用动态段中的符号表显示符号,而不是默认的符号段。 |
| -x <number 或 name> | --hex-dump=<number 或 name> | 以十六进制转储指定节的内容。可通过节索引或节名指定。 |
| -w[liaprmfFsoR] | --debug-dump[=line,=info,...] | 显示调试段中的指定内容(如行号、宏、帧信息等)。 |
| -I | --histogram | 显示符号时,同时显示哈希桶长度的柱状图。 |
| -W | --wide | 宽行输出,避免因行长而截断。 |
| -v | --version | 显示 readelf 的版本信息。 |
| -H | --help | 显示帮助信息,列出所有支持的选项。 |
| @file | 从指定文件 file 中读取命令行选项(每行一个选项)。 |
4. 示例用法
示例 1:显示 ELF 文件头信息
查看可执行文件的基本信息,如文件类型、架构、入口点等。
bash
运行
readelf -h main输出示例:
plaintext
ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: Intel 80386 Entry point address: 0x8048580 ...示例 2:显示程序头(段)信息
查看可执行文件的段布局,了解加载到内存后的结构。
bash
运行
readelf -l main输出示例:
plaintext
Elf file type is EXEC (Executable file) Entry point 0x8048580 There are 8 program headers, starting at offset 52 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align PHDR 0x000034 0x08048034 0x08048034 0x00100 0x00100 R E 0x4 INTERP 0x000134 0x08048134 0x08048134 0x00013 0x00013 R 0x1 [Requesting program interpreter: /lib/ld-linux.so.2] LOAD 0x000000 0x08048000 0x08048000 0x00970 0x00970 R E 0x1000 ...示例 3:显示节头信息
查看文件的节(section)详细信息,包括代码、数据、调试节等。
bash
运行
readelf -S main输出示例:
plaintext
There are 29 section headers, starting at offset 0xca0: Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL NULL 00000000 000000 000000 00 0 0 0 [ 1] .interp PROGBITS 08048154 000154 000013 00 A 0 0 1 [ 2] .note.ABI-tag NOTE 08048168 000168 000020 00 A 0 0 4 [ 3] .note.gnu.build-id NOTE 08048188 000188 000024 00 A 0 0 4 ... (更多节信息)示例 4:显示符号表信息
查看文件中的符号,如函数名、变量名等。
bash
运行
readelf -s main输出示例:
plaintext
Symbol table '.dynsym' contains 5 entries: Num: Value Size Type Bind Vis Ndx Name 0: 00000000 0 NOTYPE LOCAL DEFAULT UND 1: 00000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.0 (2) 2: 00000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.0 (2) 3: 0804849c 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used 4: 080484a0 0 FUNC GLOBAL DEFAULT 14 _init ...5. 注意事项
- readelf 命令必须针对有效的 ELF 格式文件运行,否则会报错。请确保输入文件是 ELF 文件(如可执行文件、共享库等)。
- 除了 -v 和 -H 选项外,必须至少指定一个其他选项(如 -h、-l 等)来指定要显示的信息类型,否则命令可能无输出或报错。
- 对于大型或复杂的 ELF 文件(如包含大量符号或调试信息),某些选项(如 -a 或 -s)可能会产生非常长的输出,建议重定向到文件或使用分页工具(如 less)查看。
- 某些选项(如 -u 用于 unwind 信息)可能只在特定架构(如 IA64)上有效,在其他架构上输出可能有限或无输出。
- 使用 -x 选项转储节内容时,需指定节的索引或名称,确保节存在以避免错误。
- 如果需要分析静态库(.a 文件),readelf 会显示库中包含的每个 ELF 对象文件的信息,通常结合其他工具(如 ar)使用。
