在Linux系统中,“节”(Section)通常指可执行文件、目标文件或共享库中的数据段,用于存储代码、数据、符号表等信息,查看节内容有助于分析程序结构、调试问题或理解文件布局,以下是常用工具及方法,结合实例说明如何查看节内容。
ELF文件与节的基本概念
Linux下的可执行文件多采用ELF(Executable and Linkable Format)格式,其结构包括ELF头、节头表(Section Header Table)和各节内容,节头表记录了每个节的名称、大小、偏移量等信息,是定位节内容的关键,常见节包括:
.text
:存储程序代码(可执行指令)。.data
:已初始化的全局变量和静态变量。.bss
:未初始化的全局变量和静态变量(运行时初始化为0)。.rodata
:只读数据(如字符串常量)。.symtab
:符号表(函数和变量名及其地址)。
的工具及方法
readelf
:查看ELF文件结构的核心工具
readelf
是专门分析ELF文件的工具,支持查看节头表、节内容、符号表等详细信息。
(1)查看节头表(列出所有节)
使用-S
或--section-headers
选项可显示节头表,包含节名、大小、偏移量等信息:
readelf -S example
输出示例(截取关键部分):
[Nr] Name Type Addr Off Size Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000040 000020 00 AX 0 0 4
[ 2] .data PROGBITS 00000020 000060 000010 00 WA 0 0 4
[ 3] .bss NOBITS 00000030 000070 000008 00 WA 0 0 1
[ 4] .rodata PROGBITS 00000000 000070 000005 00 A 0 0 1
Name
:节名(如.text
)。Type
:节类型(PROGBITS
为数据/代码,NOBITS
为.bss
等虚拟节)。Addr
:节在内存中的起始地址。Off
:节在文件中的偏移量。Size
:节的大小(字节)。Flg
:节属性(A
=可定位,X
=可执行,W
=可写)。
(2)查看指定节的原始内容
使用-x
或--hex-dump
选项可查看节的十六进制内容,需指定节索引(从0开始)或节名:
# 按节索引查看(如查看索引1的.text节) readelf -x 1 example # 按节名查看(如查看.rodata节) readelf -x .rodata example
输出示例(.rodata
):
Hex dump of section '.rodata':
0x00000070 48656c6c 6f20576f 726c6421 0a Hello World!.
(3)查看节中的字符串内容
使用-p
或--string-dump
选项可提取节中的字符串(适用于.rodata
、.comment
等节):
readelf -p .rodata example
输出:
String dump of section '.rodata':
[ 0] Hello World!
(4)查看符号表与节的关联
符号表(.symtab
或.dynsym
)记录了符号与节的对应关系,使用--syms
或-s
查看:
readelf -s example
输出示例:
Symbol table '.symtab' contains 4 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 1 main
2: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 2 data_var
3: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 3 bss_var
Ndx
列表示符号所属的节索引(如1
对应.text
,2
对应.data
)。
objdump
:反汇编与节内容查看
objdump
是二进制文件分析工具,支持反汇编和节内容转储。
(1)查看节头信息
使用-h
或--section-headers
选项:
objdump -h example
输出与readelf -S
类似,但格式略有不同。
(2)查看节内容(十六进制+ASCII)
使用-s
或--full-contents
选项:
objdump -s example
输出示例:
Contents of section .rodata:
0000 48656c6c 6f20576f 726c6421 0a Hello World!.
(3)反汇编代码节(.text
)
使用-d
或--disassemble
选项可反汇编.text
节:
objdump -d example
输出示例(汇编代码):
00000000 <main>:
0: push %rbp
1: mov %rsp,%rbp
4: sub $0x10,%rsp
8: lea 0x0(%rip),%rax # 12 <main+0x12>
a: mov %rax,-0x4(%rbp)
f: mov -0x4(%rbp),%rax
12: mov %rax,%rdi
15: call 0x20 <puts@plt>
1a: mov $0x0,%eax
1f: leave
20: ret
nm
:查看符号与节的映射
nm
用于显示文件的符号表,可结合节索引查看符号所属节:
nm example
输出示例:
0000000000000000 T main
0000000000000000 D data_var
0000000000000000 B bss_var
T
:符号在.text
节(代码)。D
:符号在.data
节(已初始化数据)。B
:符号在.bss
节(未初始化数据)。
size
:查看节大小统计
size
工具可快速显示各节的总大小(以字节为单位):
size example
输出示例:
text data bss dec hex filename
32 16 8 56 38 example
text
:.text
节大小(代码)。data
:.data
和.rodata
等已初始化数据节大小。bss
:.bss
节大小(未初始化数据)。
工具对比与使用场景
以下表格总结了各工具的功能特点及适用场景:
工具 | 主要功能 | 常用选项 | 适用场景 |
---|---|---|---|
readelf |
查看ELF文件结构、节头表、符号表 | -S (节头表)、-x (十六进制内容)、-p (字符串) |
精确分析节布局、调试符号问题 |
objdump |
反汇编、节内容转储、符号表查看 | -h (节头)、-s )、-d (反汇编) |
代码分析、查看二进制数据内容 |
nm |
显示符号表及所属节 | 无(默认显示所有符号) | 快速定位变量/函数所在的节 |
size |
统计节大小(text/data/bss) | 无(默认显示统计) | 快速了解程序内存占用分布 |
进阶技巧
- 结合
grep
过滤节名:若文件节较多,可通过管道过滤目标节,例如readelf -S example | grep "data"
。 - 查看动态节(共享库):对于动态链接的ELF文件,使用
readelf -d example
查看动态节(如.dynsym
、.dynstr
)。
相关问答FAQs
Q1: 如何查看ELF文件中某个特定节(如.rodata)的所有字符串?
A: 使用readelf
的-p
选项直接提取节中的字符串,查看example
文件中.rodata
节的字符串:
readelf -p .rodata example
若节名包含空格或特殊字符,需用引号包裹,例如readelf -p ".my data" example
。
Q2: readelf
和objdump
在查看节内容时有什么区别?
A: 两者均能查看节内容,但侧重点不同:
readelf
:专注于ELF文件结构分析,功能更全面(如节头表、符号表、重定位信息等),适合底层调试和文件格式研究。objdump
:更侧重于可读性,支持反汇编(-d
)和混合显示(十六进制+ASCII),适合代码分析和逆向工程。
查看.text
节时,readelf -x .text example
输出纯十六进制,而objdump -d example
直接反汇编为汇编指令,更易理解代码逻辑。
原创文章,发布者:酷番叔,转转请注明出处:https://cloud.kd.cn/ask/20954.html