ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Linux nm 命令详解:从符号表剖析二进制目标文件

Linux nm 命令详解:从符号表剖析二进制目标文件 文档教程【免费下载链接】linux-commandLinux命令大全搜索工具内容包含Linux命令手册、详解、学习、搜集。https://git.io/linux项目地址https://gitcode.com/GitHub_Trending/linux/linux-command点击查看免费下载nm是 GNU binutils 工具集中的核心成员用于显示二进制目标文件可执行文件、静态库、共享库的符号表。在 Linux 开发、逆向分析与程序调试场景中通过nm可以快速了解一个二进制文件定义了哪些全局函数、变量引用了哪些外部符号是理解程序链接关系与代码结构的高效入口。本文以 linux-command 仓库中的 nm 命令文档 为主体结合仓库内objdump、readelf等关联文档系统讲解nm的语法、选项、典型场景与源码级佐证帮助你读完即可上手分析手头的.o、.a、.so与可执行文件。一、命令简介符号表是什么nm命令被用于显示二进制目标文件的符号表。所谓符号表可以理解为二进制文件中记录名字 ↔ 地址/属性映射的清单一个程序经过编译后函数名、全局变量名都会被转换为符号symbol并记录在符号表段中。对 ELF 格式的文件而言符号表位于.symtab静态符号表或.dynsym动态符号表等段中正如仓库中 readelf 命令文档 所展示的使用readelf -S可以查看目标文件的节信息其中.symtab类型为SYMTAB和.dynsym类型为DYNSYM即存放符号的段。nm正是将这些符号段中的条目以易读的文本形式导出常见的输出格式为三列地址(十六进制) 符号类型(字母) 符号名称例如仓库中 objdump 命令文档 给出的nm -s mytest.o输出[rootlocalhost test]# nm -s mytest.o 0000000c T _Z10printTest2v 00000000 T _Z9printTestv U __gxx_personality_v0可以看到T表示位于文本段代码段的全局符号U表示未定义符号即本文件引用但未定义、需要链接时由其他模块提供的符号。符号前缺省显示为 8 位十六进制地址U类符号没有地址属正常现象。二、语法nm(选项)(参数)选项原文档给出的四个核心选项如下-A每个符号前显示文件名 -D显示动态符号 -g仅显示外部符号 -r反序显示符号表。在此基础上GNUnm还提供了一组常用选项配合上述四个选项可覆盖绝大多数分析需求-a显示调试符号等所有符号不忽略任何类型 -C将 C 底层修饰名mangled name解码为可读的用户级函数名如 _Z9printTestv 显示为 printTest() -s若目标文件是归档库.a显示库的索引armap即归档中定义符号的成员映射 -u仅显示未定义符号undefined symbols常与 -C 组合用于排查缺失的链接符号 -n按地址数值顺序排序符号而不是默认的字母顺序 -p不做排序保持符号表中符号的原始出现顺序 --defined-only仅显示已定义符号 --undefined-only仅显示未定义符号同 -u -l同时显示定义符号的源文件与行号需要目标文件带调试信息 -S显示符号大小大小存于符号表时 --size-sort按符号大小排序输出 -s显示归档库的符号索引。参数目标文件二进制目标文件通常是库文件和可执行文件。具体包含四类可重定位目标文件.o编译但未链接可执行文件如编译生成的a.out、/bin/ls静态库文件.a由ar打包多个.o而成共享库文件.so动态链接库。三、符号类型速查读懂 nm 的第二列nm输出第二列的字母表示符号类型大小写约定为大写代表全局符号、小写代表局部符号。常用类型如下符号类型含义A绝对值符号值固定不变不会被链接过程改变B / b位于未初始化数据段BSS的符号C公共common符号多目标文件可合并D / d位于已初始化数据段.data的符号G / g位于小对象全局区small object的符号I / i间接引用符号对某些架构而言N调试符号R / r只读数据段.rodata符号T / t文本段代码段 .text符号U未定义符号需从其他模块解析V / v弱对象weak object符号W / w弱符号链接时若存在同名强符号则被覆盖?未知类型需用nm --help或目标文件文档进一步确认对照 objdump 命令文档 中objdump -t mytest.o的输出可以看到objdump -t--syms显示文件符号表入口提供的信息与nm -s类似两者可互为验证手段。四、实战示例1. 查看可执行文件的所有符号nm /bin/ls输出将列出/bin/ls的全部符号地址 类型 名称。若符号数量庞大可配合管道过滤nm /bin/ls | head -n 20 nm /bin/ls | grep -i main2. 每个符号前显示文件名-A当同时分析多个目标文件时-A会在每个符号前标明其来源文件避免混淆nm -A *.o nm -A /usr/lib/x86_64-linux-gnu/libc.a | head3. 仅查看外部全局符号-g静态分析库文件对外暴露的 API 时-g非常实用它只显示全局符号隐藏内部局部符号nm -g libmylib.a nm -g mylib.so | grep T T大写表示该符号是文本段中全局定义的函数即对外可链接的接口U则是该库依赖的外部符号。4. 查看动态符号表-D对动态链接库.so而言真正参与动态链接的是动态符号表.dynsym而非静态符号表。-D选项用于显示动态符号nm -D /usr/lib/x86_64-linux-gnu/libc.so.6 | head -n 20 nm -D 可执行文件 | grep U 在 readelf 命令文档 中可以看到.dynsym与.symtab同时存在于共享目标文件的节表中同样地objdump -T--dynamic-syms显示的信息与nm -D类似详见 objdump 命令文档。5. 反序显示符号表-r-r反序显示符号表通常与排序选项组合使用才更有意义例如按地址数值排序后反序让地址最大的符号排在最前nm -n -r mylib.so nm -r -C mylib.a6. 排查未定义符号-u 与 -C 组合链接报undefined reference时可用以下命令快速列出某个目标文件缺失的外部符号-C让 C 符号保持可读nm -u -C mytest.o对应 objdump 命令文档 中nm -s mytest.o输出的U __gxx_personality_v0——这就是一个典型的未定义符号需要在链接时由运行时库提供。7. 静态库符号索引-s对ar生成的静态库-s显示归档文件的符号索引表相当于ranlib生成的映射快速定位某个符号定义在哪个成员.o中nm -s libmy2.a8. 反汇编与符号的交叉验证符号地址可以作为反汇编的起点。仓库的 objdump 命令文档 展示了完整的配合流程先用nm拿到函数符号_Z9printTestv的地址00000000 T再通过objdump -d -l mytest.o反汇编.text段即可将机器码与源码行一一对应这正是符号表在源码级调试中的价值。五、与 objdump、readelf、strings 的协同定位在 GNU binutils 工具链中nm与三个兄弟命令职责互补仓库中均有对应文档命令职责对应文档nm提取并显示符号表核心就是本文主题command/nm.mdobjdump反汇编、查看段信息与符号表-t/-T/-s与nm输出互通command/objdump.mdreadelf查看 ELF 文件头、节表、程序头等底层结构符号所在段靠它定位command/readelf.mdstrings从二进制中抽取可打印字符串辅助识别符号名之外的文本信息command/strings.md典型工作流是readelf -S确认.symtab/.dynsym是否存在 →nm或objdump -t导出符号清单 →nm -D/objdump -T查看动态符号 → 结合objdump -d反汇编到符号地址展开指令级分析。六、在本仓库中的定位与阅读指引linux-command 仓库收录了 600 多个 Linux 命令文档见 README.mdnm是其中文件分析工具类目的重要一员文档源文件位于 command/nm.md站点数据索引记录在 dist/data.json 中nm条目为{n: nm, p: /nm, d: 显示二进制目标文件的符号表}页面路径为/nmscripts/dash.mjs 展示了仓库如何把dist/data.json中的命令条目构建为可检索的 Dash/Zeal docsetcreateDatabase将每条命令以name type path写入 SQLite 的searchIndex表也就是说nm等命令文档可直接离线检索使用。如果你希望在同一套文档体系中继续深入 ELF 结构与反汇编推荐依次阅读 readelf 命令文档文件头、节表、程序头与 objdump 命令文档-t符号表、-d反汇编、-S源码级反汇编它们与nm的输出互相印证构成完整的二进制分析知识闭环。七、使用注意事项nm对符号表被剥离stripped的二进制如发布版可执行文件通常只能显示动态符号此时应使用-D或搭配objdump -T-r反序本身不改变排序规则与-n按地址排序组合效果最佳静态库.a是多个.o的归档nm lib.a默认按成员逐一输出可用-A区分成员来源C 程序的符号名默认带修饰mangled分析时加上-C可显著提升可读性若目标文件格式特殊非本机 ELF 格式可参考readelf文档先确认文件类型必要时结合strings与file做初步判断。赞分享文档教程【免费下载链接】linux-commandLinux命令大全搜索工具内容包含Linux命令手册、详解、学习、搜集。https://git.io/linux项目地址https://gitcode.com/GitHub_Trending/linux/linux-command点击查看免费下载相关推荐od 命令详解以八进制、十六进制等格式查看二进制文件内容Linux 命令大全od 命令详解以八进制、十六进制等格式查看二进制文件内容Linux 命令大全 od 命令用于将文件内容按八进制、十六进制、十进制、ASCII 等格式重新编文档教程Linux chmod 命令详解符号模式、八进制模式与权限管理实战linux-command 项目Linux chmod 命令详解符号模式、八进制模式与权限管理实战linux command 项目 本篇技术指南以当前仓库 linux command h文档教程Linux Command 手册hostid 命令详解——显示主机十六进制标识符Linux Command 手册hostid 命令详解——显示主机十六进制标识符 本文是 linux command 项目 README.md https:文档教程上一篇三步在 Proteus 里点亮 LCD12864下一篇NPK 游戏资源编辑器不用写代码三步跑通创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表