当前位置: 首页 > news >正文

C++(Qt)软件调试---binutils工具集详解(39)

C++(Qt)软件调试—binutils工具集详解(39)


文章目录

  • C++(Qt)软件调试---binutils工具集详解(39)
    • @[toc]
    • 1 概述🐜
    • 2 binutils包含的工具
    • 3 主要工具详细说明
      • 3.1 ld - GNU 链接器
      • 3.2 as - GNU 汇编器
      • 3.3 gold - GNU 链接器(快速版)
    • 4 其他工具详细说明
      • 4.1 addr2line
      • 4.2 ar
      • 4.3 c++filt
      • 4.4 dlltool
      • 4.5 elfedit
      • 4.6 gprof
      • 4.7 gprofng
      • 4.8 nlmconv
      • 4.9 nm
      • 4.10 objcopy
      • 4.11 objdump
      • 4.12 ranlib
      • 4.13 readelf
      • 4.14 size
      • 4.15 strings
      • 4.16 strip
      • 4.17 windmc
      • 4.18 windres
    • 5 地址

更多精彩内容
👉内容导航 👈
👉C++软件调试 👈

1 概述🐜

binutils(Binary Utilities)是一套用于处理二进制目标文件的工具集合,主要面向编译器和链接器生成的目标文件和可执行文件。

是GCC编译器套件的重要组成部分,广泛应用于Linux、BSD等类Unix系统以及嵌入式开发环境中;

部分工具可用于Windows,不过在Windows中支持不完整。


学习 Binutils 有以下几个重要原因(还有其他更多的用途这里不列出来):

  1. 理解程序构建过程

    • 编译链接原理:Binutils 包含了 as(汇编器)、ld(链接器)等工具,帮助理解代码如何从源文件转换为可执行文件

    • 目标文件分析:通过 objdumpreadelf 等工具可以深入理解 ELF 文件格式和程序结构

  2. 调试和性能优化

    • 调试支持addr2linenm 等工具可以帮助定位程序问题和分析符号信息

    • 性能分析:通过分析目标文件和符号表,可以进行程序大小优化和性能调优

    • 内存布局:理解程序在内存中的布局和加载过程

  3. 逆向工程和安全研究

    • 二进制分析:安全研究人员需要使用 Binutils 中的工具来分析恶意软件或进行漏洞研究

    • 反汇编objdump 可以用来反汇编程序,分析其行为

环境说明
系统ubuntu20.04、windows10

2 binutils包含的工具

主要工具

  • ld - GNU 链接器
  • as - GNU 汇编器
  • gold - 一种新的、更快的、仅支持 ELF 的链接器

其他工具

  • addr2line - 将地址转换为文件名和行号
  • ar - 用于创建、修改和提取档案文件的工具
  • c++filt - 用于解码 C++ 符号的过滤器
  • dlltool - 创建用于构建和使用 DLL 的文件
  • elfedit - 允许修改 ELF 格式文件
  • gprof - 显示性能分析信息
  • gprofng - 收集并显示应用程序性能数据
  • nlmconv - 将目标代码转换为 NLM 格式
  • nm - 列出目标文件中的符号
  • objcopy - 复制和转换目标文件
  • objdump - 显示目标文件中的信息
  • ranlib - 为档案文件内容生成索引
  • readelf - 显示任何 ELF 格式目标文件中的信息
  • size - 列出目标文件或档案文件的节大小
  • strings - 列出文件中的可打印字符串
  • strip - 丢弃符号
  • windmc - Windows 兼容的消息编译器
  • windres - Windows 资源文件编译器

相关库文件

  • libbfd - 用于操作多种不同格式二进制文件的库
  • libctf - 用于操作 CTF 调试格式的库
  • libopcodes - 用于汇编和反汇编多种不同汇编语言的库
  • libsframe - 用于操作 SFRAME 调试格式的库

3 主要工具详细说明

3.1 ld - GNU 链接器

GNU Binutils 中的链接器,用于将编译后的目标文件(.o)和库文件(.a/.so)链接成可执行文件或共享库。它主要负责地址分配、符号解析和重定位。

实际中通常使用编译器完成链接,会自动调用 ld 并设置必要的参数。

主要功能

  • 符号解析:解析不同目标文件中的符号引用和定义
  • 重定位:调整代码和数据的地址引用
  • 段合并:将输入文件中的段合并到输出文件中
  • 库处理:链接静态库和动态库

使用场景

  • 将编译后的目标文件合并为最终可执行程序
  • 创建共享库(.so文件)
  • 处理符号解析和重定位

使用方法

ld [选项] 目标文件... -o 输出文件

3.2 as - GNU 汇编器

as 命令是 GNU 汇编器(GNU Assembler)的命令行工具,用于将汇编语言源代码编译成目标文件。

它是 GNU Binutils 工具集的一部分,通常与 gcc 编译器一起使用。

  • 通常由 gcc 自动调用,用户无需直接使用;
  • 生成的目标文件需要通过 ld 链接器进行链接;
  • 可以与 objdumpnm 等工具配合分析目标文件;

主要功能

  • 汇编翻译:将汇编语言代码转换为机器码格式的目标文件
  • 符号处理:处理汇编代码中的标签、变量名等符号
  • 重定位信息生成:为目标文件生成重定位信息,供链接器使用

使用场景

  • 编译汇编语言程序
  • 将.s或.S文件转换为.o目标文件
  • 嵌入到编译流程中处理内联汇编

使用方法

as [选项] 源文件.s -o 输出文件.o

3.3 gold - GNU 链接器(快速版)

gold 是一个更快的链接器实现,专门针对大型应用程序进行了优化;

它在链接速度方面比传统 ld 链接器有显著提升,特别是在处理大量目标文件时表现优异;

GNU ld 的替代品;

性能优势

  • 快速链接:比传统 ld 链接器快得多,特别是在大型项目中
  • 并行处理:能够利用多核处理器提高链接速度
  • 内存效率:更有效地管理内存使用
  • 增量链接:支持更快的增量构建

使用场景

  • 大型项目链接加速
  • 需要更快链接速度的构建环境
  • 仅处理 ELF 格式的系统(如Linux)

使用方法

gold [选项] 输入文件... -o 输出文件

或通过 gcc 调用:

gcc -fuse-ld=gold [其他选项] 文件...

4 其他工具详细说明

4.1 addr2line

addr2line 是一个 GNU binutils 工具集中的命令行工具,主要用于将程序的内存地址转换为对应的源代码文件名和行号。

这对于调试程序、分析崩溃日志或性能分析非常有用。

功能

  • 地址到源码映射:将二进制程序中的内存地址转换为源代码位置(文件名:行号)
  • 调试信息解析:利用程序中的调试信息(如 DWARF)进行地址解析

使用场景

  • 程序崩溃调试:当程序产生段错误(core dump)时,根据栈回溯中的地址定位具体出错位置
  • 性能分析:配合性能分析工具,将采样地址映射到源代码
  • 调试辅助:在没有完整调试环境时提供地址解析功能
  • 逆向工程:帮助理解二进制程序的行为和结构

使用方法

# 将地址转换为文件名和行号
addr2line -e myprogram 0x400526# 显示地址、函数名和源码位置
addr2line -a -f -e myprogram 0x400526# 只显示文件名(不包含路径)和行号
addr2line -s -e myprogram 0x400526

在这里插入图片描述

常用选项

  • -e --exe=<executable>:指定要分析的可执行文件(默认为 a.out)
  • -b --target=<bfdname>:设置二进制文件格式(如 elf64-x86-64)
  • -j --section=<name>:读取相对于指定段的偏移量而非绝对地址
  • -a --addresses:显示原始地址
  • -f --functions:显示函数名称
  • -s --basenames:只显示文件名,去除目录路径
  • -p --pretty-print:以更易读的格式显示输出
  • -i --inlines:展开内联函数信息
  • -C --demangle[=style]:将 C++ 符号名还原为可读格式,可选 demangle 风格
  • -R --recurse-limit:启用 demangle 时的递归限制(默认启用)
  • -r --no-recurse-limit:禁用 demangle 时的递归限制

注意事项

  • 调试信息要求:目标程序必须在编译时包含调试信息(使用 -g 选项)
  • 地址格式:地址应为虚拟内存地址,通常以 0x 开头
  • stripped 程序:对于去除了符号表的程序,功能会受限
  • PIE 程序:对于位置无关可执行程序,可能需要考虑加载基址

4.2 ar

功能

ar (archiver) 是创建和维护静态库(.a文件)的工具,可以将多个目标文件打包成一个档案文件。

使用场景

  • 构建静态链接库供其他程序使用
  • 管理大型项目的目标文件集合
  • 创建备份档案文件

使用方法

ar [选项] 归档文件名 [成员文件...]
# 创建一个包含多个目标文件的静态库
ar rcs libmylib.a file1.o file2.o file3.o
# 列出库中包含的所有文件
ar t libmylib.a
# 从库中提取特定文件
ar x libmylib.a file1.o
# 向已存在的库中添加新文件
ar r libmylib.a newfile.o

常用操作符:

  • r 插入文件到档案中(替换已存在的文件)
  • c 创建档案文件
  • s 写入索引(相当于运行ranlib)
  • t 列出档案内容
  • x 提取文件

4.3 c++filt

功能

c++filt 用于解码C++编译器产生的修饰(mangled)符号名,将其转换为人类可读的形式。

使用场景

  • 链接错误分析:解读链接器报告的未解析符号
  • 调试符号分析:理解符号表中的C++函数名
  • 反汇编分析:将汇编代码中的修饰符号还原

使用方法

c++filt [options] [mangled_names...]
echo "_ZNSsD1Ev" | c++filt  # 通过管道解码
nm executable | c++filt     # 解码nm输出中的符号

在这里插入图片描述

常用选项:

  • -_ 允许下划线开头的符号
  • -n 不省略下划线前缀
  • -p 不解码函数参数和返回值类型

4.4 dlltool

功能

dlltool 是一个用于创建 DLL (动态链接库) 相关文件的工具,主要在 MinGW 和 Cygwin 环境中使用。

使用场景

  • 在MinGW/MSYS环境下开发Windows DLL
  • 创建与Windows DLL交互的导入库
  • 生成DEF文件定义DLL导出符号

使用方法

dlltool [options] [--input-def def-file] [--output-lib lib-file] [--dllname dll-name]
dlltool --def mydll.def --dllname mydll.dll --output-lib libmydll.a

主要选项:

  • --def 指定DEF文件
  • --output-lib 生成导入库
  • --dllname 指定目标DLL名称
  • --export-all-symbols 导出所有全局符号

4.5 elfedit

功能

elfedit 是一个用于编辑 ELF (Executable and Linkable Format) 文件的工具。ELF 是 Unix 和类 Unix 系统(如 Linux)中标准的可执行文件、目标代码、共享库和核心转储文件格式。

使用场景

  • 跨平台兼容性调整,将二进制文件标记为适用于不同架构
  • 调整交叉编译后生成的目标文件属性,确保生成的可执行文件符合目标系统的 ABI 要求
  • 更改目标文件类型以配合调试工具,修改 OSABI 以匹配特定运行环境
  • 分析恶意软件时修改其标识信息,绕过基于 ELF 头信息的简单安全检查
  • 准备适用于特定容器环境的可执行文件,调整二进制文件以适应不同的虚拟化平台
  • 学习 ELF 文件格式的实验工具,验证不同属性对程序加载的影响

使用方法

elfedit [options] elf-file# 修改 ELF 文件的机器类型
elfedit --input-mach i386 --output-mach x86_64 program.elf# 修改 ELF 文件的 OSABI
elfedit --output-osabi linux program.elf# 启用 x86 特性
elfedit --enable-x86-feature feature_name program.elf

主要命令:

  • --input-mach <machine>: 设置输入文件的机器类型
  • --output-mach <machine>: 设置输出文件的机器类型
  • --input-type <type>: 设置输入文件的文件类型
  • --output-type <type>: 设置输出文件的文件类型
  • --input-osabi <osabi>: 设置输入文件的 OSABI (Operating System Application Binary Interface)
  • --output-osabi <osabi>: 设置输出文件的 OSABI
  • --enable-x86-feature <feature>: 启用指定的 x86 特性
  • --disable-x86-feature <feature>: 禁用指定的 x86 特性

4.6 gprof

功能

gprof 是 GNU 的性能分析工具,用于分析 C、C++ 等程序的执行性能。它通过收集程序运行时的函数调用信息和执行时间数据,帮助开发者找出程序中的性能瓶颈。

gprof 更适合传统的应用程序分析和教学用途,而 perf 是现代 Linux 系统下的首选性能分析工具。

基本工作原理

  1. 编译时插桩: 程序需要用 -pg 选项编译,会在每个函数中插入分析代码
  2. 运行时数据收集: 程序运行时会生成 gmon.out 文件,记录函数调用关系和时间信息
  3. 数据分析: gprof 读取可执行文件和 gmon.out 数据,生成性能分析报告

使用场景

  • 程序性能优化:识别热点函数和瓶颈
  • 算法效率分析:比较不同实现的性能特征
  • 程序行为研究:了解函数调用模式

使用方法

# 1. 编译程序时添加 -pg 选项
gcc -pg -o myprogram myprogram.c# 2. 运行程序生成 gmon.out
./myprogram# 3. 使用 gprof 分析性能
gprof myprogram gmon.out > analysis.txt# 只显示扁平性能分析,不显示调用图
gprof -p myprogram gmon.out# 设置最小调用次数阈值
gprof -m 10 myprogram gmon.out# 排除特定函数
gprof -e init_function myprogram gmon.out# 显示所有函数包括未调用的
gprof -z myprogram gmon.out# 生成带注释的源代码
gprof -S myprogram gmon.out

输出包括:

  • 扁平概要:每个函数的时间消耗
  • 调用图:函数间的调用关系和时间分布

4.7 gprofng

功能

  • gprofng 是 Oracle 开发的新一代性能分析工具,是传统 gprof 工具的现代化替代品。
  • 它提供了更强大、更灵活的性能分析能力,并解决了传统 gprof 的许多限制。
  • gprofng 采用了现代性能分析的理念,使用采样(sampling)而非插桩(instrumentation)的方式来收集性能数据,避免了传统 gprof 对程序性能的巨大影响。
  • 主要在 Solaris 和 illumos 系统上可用。

主要特点

  1. 低侵入性

    • 无需重新编译程序(不需要 -pg 选项)

    • 对程序运行性能影响极小

    • 可以分析正在运行的进程

  2. 多维度分析

    • 支持用户空间和内核空间分析

    • 提供多种数据视图(火焰图、调用树等)

    • 支持多线程和多进程分析

  3. 现代化界面

    • 提供图形化用户界面

    • 支持命令行界面

    • 可生成交互式 HTML 报告

使用场景

  • 更精确的性能测量
  • 多线程应用性能分析
  • 更详细的调用栈跟踪

使用方法

# 收集指定程序的性能数据
gprofng collect your_program# 收集正在运行的进程数据
gprofng collect -p PID# 收集系统范围的性能数据
gprofng collect -s# 分析收集到的数据
gprofng display experiment_name# 生成火焰图
gprofng display -flamegraph experiment_name# 生成调用树
gprofng display -calltree experiment_name

4.8 nlmconv

功能

nlmconv 将通用目标文件转换为NetWare Loadable Module(NLM)格式。

使用场景

  • 开发NetWare服务器应用程序
  • 移植Unix/Linux程序到NetWare平台
  • 创建NetWare服务模块

使用方法

nlmconv [options] input-file
nlmconv -T nlm32-i386 input.o output.nlm

4.9 nm

功能

nm 是一个用于列出目标文件中符号表的命令行工具,在 Unix 和类 Unix 系统(如 Linux)中广泛使用。

它可以帮助开发者查看可执行文件、目标文件(.o 文件)、静态库(.a 文件)和共享库(.so 文件)中的符号信息。

使用场景

  • 调试程序: 检查可执行文件是否包含预期的函数和变量
  • 库开发: 验证库导出了正确的符号
  • 链接问题诊断: 查找未解析的符号或重复定义的符号
  • 逆向工程: 分析二进制文件的结构和依赖关系

使用方法

nm [options] object-file...
nm executable                    # 显示所有符号
nm -D shared_library.so          # 显示动态符号表
nm -g executable                 # 只显示全局符号

主要选项说明

  • -a, --debug-syms:显示仅供调试器使用的符号

  • -A, --print-file-name:在每个符号前打印输入文件名

  • -D, --dynamic:显示动态符号而非普通符号

  • --defined-only:仅显示已定义的符号

  • -g, --extern-only:仅显示外部符号

  • -u, --undefined-only:仅显示未定义的符号

  • --special-syms:在输出中包含特殊符号

  • --synthetic:同时显示合成符号

  • -B:等同于 --format=bsd

  • -f, --format=FORMAT :使用指定的输出格式,可选:

    • bsd(默认)
    • sysv
    • posix
  • -P, --portability:等同于 --format=posix

  • -o:等同于 -A

  • -n, --numeric-sort:按地址数值排序符号

  • -p, --no-sort:不对符号排序

  • -r, --reverse-sort:反向排序

  • --size-sort:按符号大小排序

  • -C, --demangle[=STYLE]:将低级符号名解码为用户级名称

    • STYLE 可选:auto(默认)、gnulucidarmhpedggnu-v3javagnat
  • --no-demangle:不解码低级符号名

  • --recurse-limit:启用解码递归限制(默认)

  • --no-recurse-limit:禁用解码递归限制

  • -l, --line-numbers:使用调试信息查找每个符号的文件名和行号

  • -S, --print-size:打印已定义符号的大小

  • -s, --print-armap:包含归档成员符号的索引

  • -t, --radix=RADIX:使用指定进制打印符号值

  • --target=BFDNAME:指定目标对象格式

  • --with-symbol-versions:在符号名后显示版本字符串

  • --plugin NAME:加载指定插件

  • -h, --help:显示此帮助信息

  • -V, --version:显示程序版本号

符号类型标记:

  • T/t 文本段中的符号
  • D/d 数据段中的符号
  • B/b BSS段中的符号
  • U 未定义符号
  • W/w 弱符号

在这里插入图片描述

注意事项

  • 对于剥离了符号表的二进制文件(使用 strip 命令处理过),nm 可能无法显示有意义的信息
  • 不同架构的目标文件可能需要特定版本的 nm 工具
  • 在交叉编译环境中,需要使用对应目标平台的 nm 工具

4.10 objcopy

功能

objcopy 是 GNU Binutils 工具集中的一个重要工具,用于复制和转换目标文件(object files)。

它可以在不同格式之间转换二进制文件,并对文件内容进行各种修改。

使用场景

  • 删除或保留特定段(sections)
  • 操作符号表(添加、删除、重命名符号)
  • 修改段属性和地址
  • 填充数据间隙
  • 分离调试信息以便调试时使用
  • 发布版本时去除调试信息和其他不需要的信息
  • 在嵌入式开发中,经常需要将可执行文件转换为适合烧录的格式
  • 创建适合特定内存布局的内核模块

使用方法

objcopy [options] infile outfile
objcopy -O binary executable bootsect.bin  # 转换为原始二进制格式
objcopy --strip-debug executable stripped  # 去除调试信息
objcopy --only-section=.text input output  # 只保留.text段

在这里插入图片描述

常用选项

  • -I, --input-target <bfdname>:指定输入文件格式

  • -O, --output-target <bfdname>:指定输出文件格式

  • -F, --target <bfdname>:同时设置输入和输出格式

  • -B, --binary-architecture <arch>:当输入无架构信息时设置输出架构

  • -S, --strip-all:移除所有符号和重定位信息

  • -g, --strip-debug:移除所有调试符号和段

  • -N, --strip-symbol <name>:不复制指定符号

  • -K, --keep-symbol <name>:保留指定符号(不被strip)

  • -L, --localize-symbol <name>:将符号标记为本地符号

  • -G, --keep-global-symbol <name>:除指定符号外,其他都本地化

  • -W, --weaken-symbol <name>:将符号标记为弱符号

  • -x, --discard-all:移除所有非全局符号

  • -X, --discard-locals:移除编译器生成的符号

  • -j, --only-section <name>:只复制指定段到输出

  • -R, --remove-section <name>:从输出中移除指定段

  • --keep-section <name>:不strip指定段

  • --only-keep-debug:只保留调试信息

  • --extract-symbol:移除段内容但保留符号

  • --set-start <addr>:设置起始地址

  • --change-start <incr>:将起始地址增加指定值

  • --change-addresses <incr>:将LMA、VMA和起始地址都增加指定值

  • --change-section-address <name>{=|+|-}<val>:修改指定段的LMA和VMA

  • --change-section-lma/vma <name>{=|+|-}<val>:单独修改段的LMA或VMA

  • --gap-fill <val>:用指定值填充段之间的空隙

  • --pad-to <addr>:将最后一段填充到指定地址

  • --set-section-alignment <name>=<align>:设置段的对齐方式

  • -p, --preserve-dates:保留修改/访问时间戳

  • -w, --wildcard:允许在符号比较中使用通配符

  • -v, --verbose:显示详细处理信息

  • --add-section <name>=<file>:从文件中添加新段

  • --dump-section <name>=<file>:将段内容转储到文件

  • --rename-section <old>=<new>[,<flags>]:重命名段

  • --redefine-sym <old>=<new>:重新定义符号名

注意事项

  1. 备份原文件:某些操作会修改原文件,建议先备份
  2. 格式兼容性:不是所有格式之间都能相互转换
  3. 符号依赖:移除关键符号可能导致程序无法运行
  4. 地址对齐:修改地址时需考虑处理器的对齐要求
  5. 权限问题:某些操作可能需要特殊权限
  6. 交叉编译环境:确保使用正确的目标平台格式

4.11 objdump

功能

objdump 是一个用于显示目标文件(object files)信息的命令行工具,属于 GNU Binutils 套件的一部分。

它可以用来查看可执行文件、目标文件和库文件的详细信息,包括文件头、节头、符号表、反汇编代码等。

主要用途

  • 文件分析:查看目标文件的结构和内容
  • 调试支持:显示调试信息和符号表
  • 反汇编:将机器码转换为汇编代码
  • 格式检查:验证文件格式和架构兼容性

使用场景

  • 程序调试:分析可执行文件结构和符号信息
  • 逆向工程:查看程序的汇编代码实现
  • 开发支持:检查编译器输出的目标文件
  • 系统分析:分析库文件和系统二进制文件

使用方法

objdump [options] object-file...
# 反汇编可执行文件
objdump -d program# 显示文件头信息
objdump -f program# 显示所有节头信息
objdump -h program# 混合显示源码和反汇编
objdump -S program# 只反汇编特定函数
objdump --disassemble=main program

常用选项

  • -f, --file-headers:显示文件头信息

  • -h, --headers:显示节头信息

  • -p, --private-headers:显示特定格式的文件头

  • -d, --disassemble:反汇编可执行节

  • -D, --disassemble-all:反汇编所有节

  • -S, --source:混合显示源代码和反汇编

  • -t, --syms:显示符号表

  • -g, --debugging:显示调试信息

  • -r, --reloc:显示重定位信息

  • -j, --section=NAME:只处理指定节

  • -C, --demangle:解码修饰的符号名

  • -M, --disassembler-options:传递反汇编器选项

注意事项

  • 必需选项:至少需要指定一个主选项(如 -d-h 等)才能执行
  • 文件格式:支持多种目标文件格式(ELF、PE等)
  • 架构相关:需要与目标文件的架构匹配
  • 权限要求:需要对目标文件有读取权限
  • 大文件处理:对于大型文件可能需要较长时间处理
  • 输出格式:某些选项会产生大量输出,建议配合管道使用

4.12 ranlib

功能

ranlib 是一个用于处理静态库(archive)的工具,主要功能是为静态库生成索引以加快访问速度。

使用场景

  • 创建静态库后必须运行以生成索引
  • 更新档案文件后重新生成索引
  • 保证链接器能正确找到库中符号

使用方法

ranlib archive-file
ar rcs libname.a *.o  # ar的s选项会自动调用ranlib

主要选项

  • @<file>:从指定文件中读取选项参数
  • --plugin <name>:加载指定的插件
  • -D:在符号映射中使用零作为时间戳(默认行为)
  • -U:在符号映射中使用实际的时间戳
  • -t:更新静态库符号映射的时间戳
  • -h, --help:显示帮助信息
  • -v, --version:显示版本信息

4.13 readelf

功能

readelf 专门用于显示ELF格式目标文件的详细信息,比objdump更专注于ELF结构。

readelf 主要用于查看 ELF 文件的各种元数据信息,包括但不限于:

  • ELF 文件头
  • 程序头表(段)
  • 节区头表
  • 符号表
  • 重定位信息
  • 动态链接信息
  • 调试信息(DWARF)

使用场景

  • 调试与逆向工程
    • 分析可执行文件结构
    • 查看符号表和重定位信息
    • 检查动态链接依赖关系
  • 编译构建过程分析
    • 验证目标文件是否正确生成
    • 检查节区布局和内存映射
    • 分析程序加载和运行机制
  • 系统级编程
    • 理解 ELF 文件格式细节
    • 分析共享库和可执行文件的内部结构
    • 排查链接和加载问题
  • 安全审计
    • 检查二进制文件属性
    • 分析潜在的安全特性(如 NX、PIE 等)

使用方法

readelf [options] elf-file
# 显示文件头信息
readelf -h a.out # 显示所有节区信息
readelf -S a.out # 显示符号表
readelf -s a.out # 显示动态段信息
readelf -d a.out # 以十六进制显示 .text 节内容
readelf -x .text a.out # 显示所有调试信息
readelf -w a.out 

在这里插入图片描述

注意事项

  • 输入文件要求
    • 只能处理符合 ELF 格式的文件
    • 对于非 ELF 文件会提示错误
  • 权限限制
    • 需要有读取目标文件的权限
  • 输出量控制
    • 某些选项会产生大量输出,建议配合管道使用(如 lessgrep
  • 版本差异
    • 不同版本的 readelf 可能存在选项差异
    • 建议查阅当前系统上的具体帮助信息
  • 特殊格式支持
    • 对某些特殊的 ELF 扩展格式可能需要特定版本的支持

4.14 size

功能

size 命令的主要功能是显示目标文件或可执行文件中各节区的大小,包括文本段(代码)、数据段(已初始化数据)、BSS段(未初始化数据)等。

这对于了解程序的内存分布和优化程序大小很有帮助。

使用场景

  • 程序大小分析
    • 评估程序的整体大小
    • 分析代码段、数据段和BSS段的占比
  • 嵌入式开发
    • 监控程序占用的Flash和RAM大小
    • 优化资源受限环境下的程序尺寸
  • 性能调优
    • 识别占用空间较大的节区
    • 分析内存布局对性能的影响
  • 构建系统集成
    • 在Makefile中检查生成文件大小
    • 自动化构建过程中监控二进制文件增长
  • 比较不同版本
    • 对比不同编译选项产生的文件大小差异
    • 追踪代码变更对二进制大小的影响

使用方法

size [options] object-file...
# 基本用法,显示默认格式
size a.out# 使用 System V 格式显示详细节区信息
size -A a.out# 以十六进制显示数值
size -x a.out# 显示多个文件并计算总计(Berkeley 格式)
size -t *.o# 显示 COMMON 符号大小
size --common test.o# 指定特定目标格式
size --target=elf32-i386 program.bin

在这里插入图片描述

注意事项

  • 默认文件行为
    • 如果没有指定文件,会尝试读取 a.out
  • 格式兼容性
    • 不同输出格式提供的信息详略程度不同
    • Berkeley 格式简洁,System V 格式详细
  • 目标平台相关
    • 输出结果与目标平台架构有关
    • 同一源码在不同平台上可能产生不同大小
  • 符号处理
    • COMMON 符号的处理可能因选项而异
    • 使用 --common 选项可以获得更准确的统计
  • 文件格式支持
    • 确保输入文件格式在支持列表中
    • 必要时使用 --target 指定正确的格式

4.15 strings

功能

strings 是一个用于从二进制文件中提取可打印字符串的实用工具,主要用于分析和调试二进制程序。

  • 从二进制文件中提取可打印的字符串序列
  • 默认查找至少4个字符长度的NUL终止字符串
  • 支持多种文件格式和编码方式
  • 常用于逆向工程、恶意软件分析和程序调试

使用场景

  • 程序分析: 从编译后的程序中提取硬编码的字符串
  • 安全分析: 检查二进制文件中是否包含可疑字符串
  • 调试辅助: 查看程序中包含的文本信息
  • 逆向工程: 理解未知二进制文件的功能
  • 恶意软件检测: 搜索潜在的恶意URL或命令

使用方法

strings [options] file...
# 提取文件中的所有字符串(至少4个字符)
strings myfile# 提取至少8个字符长度的字符串
strings -n 8 myfile# 显示字符串在文件中的位置(十六进制)
strings -t x myfile# 只扫描数据段并显示文件名
strings -d -f myfile# 指定字符编码(16位小端)
strings -e l myfile

常用选项

  • -a, --all: 扫描整个文件(默认行为)
  • -d, --data: 仅扫描文件的数据段
  • -f, --print-file-name: 在每个字符串前打印文件名
  • -n NUMBER, --bytes=NUMBER: 设置最小字符串长度(默认为4)
  • -t {o,d,x}, --radix={o,d,x}: 以八进制、十进制或十六进制显示字符串位置
  • -e ENCODING, --encoding=ENCODING: 指定字符编码格式
  • -T TARGET, --target=BFDNAME: 指定二进制文件格式
  • -h, --help: 显示帮助信息
  • -v, -V, --version: 显示版本信息

注意事项

  1. 默认行为: 默认只查找至少4个字符的字符串,可通过 -n 选项调整
  2. 文件格式支持: 支持多种目标格式(elf64-x86-64, elf32-i386等)
  3. 编码处理: 对于非ASCII编码的字符串可能需要指定 -e 选项
  4. 性能考虑: 对于大文件,使用 -d 选项可以提高扫描速度
  5. 输出控制: 可使用 -s 选项自定义字符串分隔符

4.16 strip

功能

strip 是一个用于从目标文件中删除符号表和调试信息的工具,常用于减小可执行文件或共享库的大小。

使用场景

  • 发布版本优化
    • 移除调试信息减小可执行文件大小
    • 提高程序运行效率
  • 保护源码
    • 删除符号信息增加逆向工程难度
  • 嵌入式开发
    • 减少存储空间占用
    • 优化内存使用

使用方法

strip [options] file...
# 基本使用:移除所有符号信息
strip program# 保留调试信息
strip --only-keep-debug program.debug# 移除调试信息但保留符号表
strip --strip-debug program# 保留特定符号
strip -K main -K important_func program# 移除指定节区
strip -R .comment -R .note program

注意事项

  1. 备份原始文件:strip 操作不可逆,建议先备份重要文件
  2. 调试影响:剥离后的文件无法进行源码级调试
  3. 动态链接:过度剥离可能导致动态链接失败
  4. 符号依赖:某些符号对程序运行是必需的,不能随意移除
  5. 平台兼容性:不同平台支持的目标格式可能不同

4.17 windmc

功能

windmc.exe 是一个用于处理消息编译(Message Compiler)的工具,主要用于将 .mc 文件编译成资源文件和头文件。

使用场景

  • 开发Windows应用程序的本地化支持
  • 创建多语言版本的应用程序
  • 管理程序中的错误和状态消息

使用方法

windmc [options] msgfile.mc
# 基本编译
windmc messages.mc# 指定头文件输出目录
windmc -h include messages.mc# 指定资源文件输出目录
windmc -r resources messages.mc# 使用UTF16输入和详细模式
windmc -u -v messages.mc

主要选项

  • -a, --ascii_in: 指定输入文件为 ASCII 格式

  • -A, --ascii_out: 以 ASCII 格式写入二进制消息

  • -u, --unicode_in: 指定输入文件为 UTF16 格式

  • -U, --unicode_out: 以 UTF16 格式写入二进制消息

  • -b, --binprefix: 为生成的 [.bin](javascript:void(0)) 文件添加前缀以确保唯一性

  • -e, --extension=<extension>: 设置导出头文件的扩展名

  • -h, --headerdir=<directory>: 设置头文件的导出目录

  • -r, --rcdir=<directory>: 设置资源文件(.rc)的导出目录

  • -x, --xdbg=<directory>: 指定创建 .dbg C 包含文件的目录,该文件将消息 ID 映射到符号名称

  • -C, --codepage_in=<val>: 设置读取 .mc 文本文件时使用的代码页

  • -O, --codepage_out=<val>: 设置写入文本文件时使用的代码页

  • -d, --decimal_values: 以十进制格式打印值到文本文件

  • -m, --maxlength=<val>: 设置允许的最大消息长度

  • -n, --nullterminate: 自动为字符串添加零终止符

  • -o, --hresult_use: 使用 HRESULT 定义而不是状态码定义

  • -c, --customflag: 为消息设置自定义标志

  • -F, --target <target>: 指定输出目标的字节序(endianness)

  • -H, --help: 显示帮助信息

  • -v, --verbose: 详细模式,显示处理过程信息

  • -V, --version: 显示版本信息

4.18 windres

功能

windres 是一个用于处理 Windows 资源文件的工具,通常与 MinGW 或 Strawberry Perl 等 Windows 开发环境一起使用。

使用场景

  • 为Windows应用程序添加图标、菜单、对话框等资源
  • 编译Windows版本程序所需的各种资源
  • 国际化支持:编译不同语言的资源文件

使用方法

windres [options] input-file output-file
windres resource.rc resource.o    # 编译资源文件
windres -i input.rc -o output.o   # 指定输入输出文件

参数说明

  • -i, --input=<file>:指定输入文件名

  • -o, --output=<file>:指定输出文件名

  • -J, --input-format=<format>:指定输入格式

  • -O, --output-format=<format>:指定输出格式

  • -F, --target=<target>:指定 COFF 目标格式

  • --preprocessor=<program>:指定用于预处理 .rc 文件的程序

  • --preprocessor-arg=<arg>:添加预处理器参数

  • -I, --include-dir=<dir>:添加预处理时的包含目录

  • -D, --define <sym>[=<val>]:在预处理时定义符号

  • -U, --undefine <sym>:在预处理时取消定义符号

  • -v, --verbose:详细模式,显示处理过程

  • -c, --codepage=<codepage>:指定默认代码页

  • -l, --language=<val>:设置读取 .rc 文件时的语言

  • --use-temp-file:使用临时文件而不是 popen 来读取预处理器输出

  • --no-use-temp-file:使用 popen(默认行为)

  • -r:为了与 Windows 的 rc 工具兼容而被忽略

  • @<file>:从文件中读取选项

  • -h, --help:显示帮助信息

  • -V, --version:显示版本信息

格式说明

支持的格式包括:

  • rc:资源脚本文件
  • res:编译后的资源文件
  • coff:COFF 对象文件

5 地址

  • GNU Binutils
  • Binutils - GNU 项目 - 自由软件基金会
  • 下载地址


http://www.dtcms.com/a/477910.html

相关文章:

  • Qt 项目国际化从零到一:用 Qt Linguist 实现多语言动态切换(含源码与踩坑指南)
  • GitPuk入门到实战(8) - 使用GitPuk + Arbess进行CICD自动化部署
  • 网站后台登录地址修改怎么查询一个网站有没有做竞价
  • 《Qt应用开发》笔记p5
  • 【AI4S】AI设计小分子药物的三大底层逻辑
  • 网站建设费入什么科目2018把网站做静态化是什么意思
  • Node.js 事件循环(Event Loop)
  • C语言结构体详解:从定义、内存对齐到位段应用
  • 单片机进入 B. 中断无限循环异常解决方法
  • 探索Apache APISIX:动态高性能API网关
  • 【储能学习】电力基础知识
  • 2025 年项目管理转型白皮书:AI 驱动下的能力重构与跨域突破
  • linux网站建设技术指南台州 网站建设
  • AI超级智能体学习笔记
  • 海量域名SSL证书的免费批量签发
  • 基于 PyTorch 的手写数字识别
  • 悟空 AI CRM 中的线索功能:开启销售增长新引擎
  • 网站建设和维护方案吉林省城乡建设厅网站6
  • 互联网视频推拉流平台EasyDSS视频转码有哪些技术特点和应用?
  • 肥城网站建设费用lol做框网站
  • 微信小程序入门学习教程,从入门到精通,电影之家小程序项目知识点详解 (17)
  • CoRL2025口头报告:基于最优传输对齐人类视角和机器人视角的多模态数据,真正解决跨模态数据融合的问题
  • 线程进阶:线程池、单例模式与线程安全深度解析
  • ELK运维之路(Logstash7Kibana接入ES集群-7.17.24)
  • # Pandas 与 Spark 数据操作完整教程
  • 大数据实战项目-基于K-Means算法与Spark的豆瓣读书数据分析与可视化系统-基于python的豆瓣读书数据分析与可视化大屏
  • AI 数字人小程序功能全拆解:从用户体验到商业落地的产品设计逻辑
  • Agent 开发设计模式(Agentic Design Patterns )第 6 章:规划设计模式 Planning
  • 厦门做网站xm37如何增加网站内链建设
  • css变量的使用。