已知指令虚拟地址与.text段加载地址,如何求其在二进制中的文件偏移?
计算指令在二进制文件中的文件偏移(适配addr2line)
要从指令的虚拟地址和.text段加载地址推导其在二进制文件中的文件偏移(即addr2line工具接受的偏移格式),按以下步骤操作:
1. 明确三个关键值
V:目标指令I的虚拟内存地址T_vma:.text段被加载到内存中的虚拟地址(即你提到的加载地址T)T_offset:.text段在二进制文件本身中的文件偏移(需要从文件的段表中读取)
2. 核心计算逻辑
文件偏移的计算公式为:
文件偏移 = (V - T_vma) + T_offset
解释:
V - T_vma是指令相对于.text段加载基址的偏移量(即指令在.text段内部的位置)- 加上.text段本身在文件中的偏移
T_offset,就得到了指令在二进制文件里的绝对偏移
3. 获取.text段的文件偏移T_offset
可以用以下工具从二进制文件中提取该值:
- 使用
readelf:执行readelf -S <你的二进制文件>,找到.text段对应的Offset列数值(十六进制) - 使用
objdump:执行objdump -h <你的二进制文件>,找到.text段的OFFSET字段数值(十六进制)
4. 示例验证
假设:
- 指令虚拟地址
V = 0x400520 - .text段加载地址
T_vma = 0x400400 - .text段文件偏移
T_offset = 0x100
计算过程:
(0x400520 - 0x400400) + 0x100 = 0x120 + 0x100 = 0x220
得到的0x220就是可直接传给addr2line的文件偏移,用法示例:
addr2line -e <你的二进制文件> 0x220
注意事项
- 确保二进制文件编译时添加了调试信息(如
-g参数),否则addr2line无法输出有效源码位置 - 如果系统开启了ASLR(地址空间随机化),需要关闭ASLR(如执行
echo 0 > /proc/sys/kernel/randomize_va_space)或通过调试器(如gdb的info files命令)获取进程实际加载后的.text段地址 - 对于PIE(位置无关可执行文件),加载基址是随机分配的,需先获取进程实际的.text加载地址再计算
内容的提问来源于stack exchange,提问作者BeeOnRope
相关产品推荐
相关产品推荐

