在 Linux 下进行反汇编(比如用 objdump、gdb、objdump -d、readelf、nm 等)时,“偏移”通常出现在几个不同的语境里。下面按常见场景说明怎么看、怎么理解。
含义:在二进制文件(ELF)中的字节位置
用途:调试、patch、对照节区内容
readelf -S ./a.out
会看到类似:
[Nr] Name Type Address Off Size
[14] .text PROGBITS 0000000000401050 001050 0001a2
Off = 0x1050 → .text 在文件中的偏移Address = 0x401050 → 加载到内存中的虚拟地址✅ 文件偏移 ≠ 内存地址(除非是可执行文件且未重定位)
含义:程序运行时的内存地址
objdump -d ./a.out
输出:
0000000000401050 <main>:
401050: 55 push %rbp
401051: 48 89 e5 mov %rsp,%rbp
401050 是 虚拟地址(VMA)401051 = main + 1常见于:
call 401060 <foo>
或
jmp 12 <main+0x12>
含义:
main+0x12 → 相对于 main 函数起始地址偏移 0x12main地址 + 0x12在 gdb 中:
p/x &main
得到 main 地址,再加偏移即可。
有时你会看到:
.text+0x20
意思是在 .text 节内偏移 0x20
换算成文件偏移:
文件偏移 = .text 节文件偏移 + 0x20
disassemble main
输出:
0x0000000000401050 <+0>: push %rbp
0x0000000000401051 <+1>: mov %rsp,%rbp
<+0>、<+1> 就是 函数内偏移查看符号地址:
info address main
如果是 .o 文件:
objdump -r file.o
会显示:
REL32 .text+0x10
表示在 .text+0x10 处需要重定位。
| 偏移类型 | 工具 | 说明 |
|---|---|---|
| 文件偏移 | readelf / objdump | ELF 文件中位置 |
| 虚拟地址 | objdump -d | 运行时地址 |
| 函数内偏移 | gdb / objdump | func+offset |
| 节内偏移 | readelf -S | section+offset |
| 重定位偏移 | objdump -r | 链接时修正 |
如果你有具体反汇编片段(比如某条指令或 objdump 输出),可以直接贴出来,我可以帮你逐字段解释。