binutils
GNU Binutils
用途
引导完成 binutils 工具集的使用,涵盖二进制操作:静态库管理、符号剥离、地址到源码映射、以及符号名反混淆。
触发场景
- "如何创建静态库?"
- "如何在保留调试文件的同时剥离二进制符号?"
- "我有一个崩溃地址,如何找到对应的源码行?"
- "如何对 C++ 符号名进行反混淆?"
- "如何提取或替换二进制文件中的节(section)?"
工作流程
1. ar — 静态库管理
# 创建静态库
ar rcs libfoo.a foo.o bar.o baz.o
# 列出内容
ar t libfoo.a
# 提取某个对象文件
ar x libfoo.a foo.o
# 添加/替换对象文件
ar r libfoo.a newbar.o
# 删除对象文件
ar d libfoo.a oldbar.o
# 显示符号索引
nm libfoo.a
# 重建符号索引(外部修改归档后使用)
ranlib libfoo.a
对于 LTO 归档,请使用 gcc-ar/gcc-ranlib 或 llvm-ar,而非普通 ar。
2. strip — 移除调试信息
# 剥离所有调试信息(缩减二进制体积)
strip --strip-all prog
# 仅剥离调试节(保留符号表)
strip --strip-debug prog
# 剥离不需要的符号(保留链接所需符号)
strip --strip-unneeded prog
# 原地操作
strip prog
# 输出到新文件
strip -o prog.stripped prog
3. objcopy — 二进制节操作
# 从二进制文件中分离调试信息
objcopy --only-keep-debug prog prog.debug
objcopy --strip-debug prog
# 添加 debuglink(GDB 可自动找到 prog.debug)
objcopy --add-gnu-debuglink=prog.debug prog
# 将二进制转换为其他格式
objcopy -O binary prog prog.bin # 原始二进制(嵌入式)
objcopy -O srec prog prog.srec # Motorola S-record
# 从文件添加一个节
objcopy --add-section .resources=data.bin prog
# 移除某个节
objcopy --remove-section .comment prog
# 修改节标志
objcopy --set-section-flags .data=alloc,contents,load,readonly prog
# 将二进制文件嵌入为符号
objcopy -I binary -O elf64-x86-64 \
--rename-section .data=.rodata,alloc,load,readonly,data,contents \
data.bin data.o
# 然后链接 data.o;通过 _binary_data_bin_start / _binary_data_bin_end 访问
4. addr2line — 地址转换为源码位置
# 将崩溃地址转换为源码行
addr2line -e prog -f 0x400a12
# 输出:
# my_function
# /home/user/src/main.c:42
# 多个地址
addr2line -e prog -f 0x400a12 0x400b34 0x400c56
# 内联帧(-i)
addr2line -e prog -f -i 0x400a12
# 常用方式:从回溯输出通过管道传入
cat crash.log | grep '0x[0-9a-f]' | grep -o '0x[0-9a-f]*' | \
addr2line -e prog -f -i
需要二进制文件包含调试信息(编译时加 -g)。对于已剥离的二进制,使用未剥离版本或 .debug 文件。
5. c++filt — C++ 符号反混淆
# 反混淆单个符号
c++filt _ZN3foo3barEv
# 输出:foo::bar()
# 对 nm 输出进行反混淆
nm prog | c++filt
# 对崩溃日志进行反混淆
cat crash.log | c++filt
替代方案:nm -C prog(在 nm 内部直接反混淆)。
6. strings — 提取可打印字符串
strings prog # 所有长度 >= 4 的字符串
strings -n 8 prog # 最小长度 8
strings -t x prog # 带偏移量(十六进制)
strings -t d prog # 带偏移量(十进制)
# 搜索特定字符串
strings prog | grep "version"
strings prog | grep "Copyright"
7. readelf 与 objdump 快速参考
(完整内容见 skills/binaries/elf-inspection)
# 通过崩溃地址查找符号(addr2line 的替代方式)
objdump -d -M intel prog | grep -A5 "400a12:"
# 查找哪个对象文件定义了某符号
objdump -t prog | grep my_function
8. 交叉编译(Cross-binutils)
交叉编译时,使用目标平台前缀版本:
aarch64-linux-gnu-strip prog
aarch64-linux-gnu-objcopy --only-keep-debug prog prog.debug
aarch64-linux-gnu-addr2line -e prog 0x400a12
arm-none-eabi-nm libfirmware.a
完整的命令速查表(涵盖 ar、strip、objcopy、addr2line、strings、c++filt),参见 references/cheatsheet.md。
相关技能
- 使用
skills/binaries/elf-inspection进行 readelf、nm、ldd、objdump 检查 - 使用
skills/binaries/linkers-lto了解链接器标志和 LTO - 使用
skills/debuggers/core-dumps结合objcopy --add-gnu-debuglink管理调试文件
More from killvxk/low-level-dev-skills-zh
ebpf
Linux 可观测性和网络的 eBPF 技能。适用场景:使用 libbpf 或 bpftrace 编写 eBPF 程序、挂载 kprobe/tracepoint/XDP 钩子、调试验证器错误、使用 eBPF map,或实现跨内核版本的 CO-RE 可移植性。触发条件:查询 eBPF、bpftool、bpftrace、XDP 程序、libbpf、验证器错误、eBPF map 或使用 BPF 进行内核追踪相关问题。
1clang
C/C++ 项目的 Clang/LLVM 编译器技能。适用场景:使用 clang 或 clang++ 进行诊断、sanitizer 插桩、优化备注、通过 clang-tidy 进行静态分析、通过 lld 实现 LTO,或从 GCC 迁移到 Clang。触发条件:涉及 clang 标志、clang-tidy、clang-format、更好的错误信息、Apple/FreeBSD 工具链或 LLVM 特定优化的查询。涵盖标志选择、诊断调优及与 LLVM 工具的集成。
1gcc
C/C++ 项目的 GCC 编译器技能。适用场景:选择优化级别、警告标志、调试构建、LTO、sanitizer 插桩,或诊断 GCC 编译错误。涵盖调试与发布构建的标志选择、ABI 问题、预处理器宏、配置引导优化(PGO)及与构建系统的集成。触发条件:涉及 gcc 标志、编译错误、性能调优、警告抑制或跨标准编译的查询。
1cmake
C/C++ 项目的 CMake 构建系统技能。适用场景:编写或重构 CMakeLists.txt、配置源外构建、选择生成器(Ninja、Make、VS)、使用 target_link_libraries 管理目标和依赖、通过 find_package 或 FetchContent 集成外部包、启用 Sanitizer、为交叉编译配置工具链文件,或导出 CMake 包。触发条件:涉及 CMakeLists.txt、cmake 配置错误、目标属性、安装规则、CPack 或 CMake Presets 的查询。
1cpp-modules
现代 C++ 项目的 C++20 模块技能。适用场景:使用命名模块、模块分区、头文件单元、CMake MODULE_SOURCES、Clang -fmodules-ts、BMI 缓存问题,或从头文件迁移到模块。触发条件:涉及 C++20 模块、import 语句、模块接口单元、头文件单元或 BMI 文件的查询。
1binary-hardening
二进制加固技能,用于安全加固的 C/C++ 构建。适用场景:启用 RELRO、PIE、栈金丝雀、FORTIFY_SOURCE、CFI sanitizers、影子栈,或 seccomp-bpf 系统调用过滤。涵盖 checksec 分析、用于加固构建的编译器和链接器标志,以及 NSA/CISA 推荐的缓解措施。触发条件:查询涉及二进制加固、checksec、RELRO、PIE、栈金丝雀、FORTIFY_SOURCE、CFI、影子栈,或 seccomp。
1