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

linux程序分析命令(一)

linux程序分析命令(一)

  • **ldd:**用于打印共享库依赖。这个命令会显示出一个可执行文件所依赖的所有共享库(动态链接库),这对于解决运行时库依赖问题非常有用。
  • **nm:**用于列出对象文件的符号表。这个命令可以显示出定义和引用的符号,对于理解程序结构和调试非常有帮助。
  • objdump:显示二进制文件的信息。这个命令可以用来显示程序的汇编代码、段信息等,对于底层分析和调试很有用。
  • strace:跟踪系统调用。通过这个命令,你可以看到一个程序执行时所有的系统调用,这对于理解程序如何与操作系统交互非常重要。
  • ltrace:跟踪库函数调用。与strace类似,但是ltrace专注于跟踪程序调用库函数的情况。
  • gdb:GNU调试器。这是一个功能强大的调试工具,可以让你看到程序执行时的内部情况,比如变量的值、程序的执行流程等。
  • valgrind:内存调试工具。这个工具主要用于检测内存泄漏、内存损坏等问题,对于提高程序稳定性非常有帮助。
  • readelf:显示ELF格式文件的信息。这个命令可以显示出ELF格式的二进制文件(如Linux下的可执行文件和共享库)的详细信息,包括段、节、符号等。
  • file:确定文件类型。这个命令可以帮助你识别一个文件是二进制可执行文件、文本文件还是其他类型的文件。
  • size:显示二进制文件的段大小。这个命令会列出二进制文件各个段(如文本段、数据段)的大小,对于评估程序占用空间有一定帮助。

ldd命令

ldd命令是Linux下一个非常实用的工具,它用于显示一个可执行文件或共享库文件的依赖关系。基本上,它会列出程序运行所需要的所有共享库。

下面是ldd的基本用法和一些常见的使用场景。

基本用法

#命令格式:
ldd [选项] 文件...
#文件...:指定要检查的可执行文件或共享库文件。

最简单的用法是直接跟上你想要检查的文件名:

ldd /path/to/your/program
#这条命令会列出/path/to/your/program这个程序所依赖的所有共享库。

常见用法
检查可执行文件的依赖库:

ldd /usr/bin/ls
#这会显示ls命令所依赖的所有共享库。

检查动态库的依赖:

#如果你有一个共享库文件(例如,libexample.so),你可以使用ldd来查看它依赖哪些其他库:
ldd libexample.so

过滤输出:

#如果你只对特定的依赖感兴趣,可以使用管道和grep命令来过滤输出。例如,如果你只想看看是否依赖于libc.so.6:
ldd /path/to/your/program | grep libc.so.6

解决“不是动态可执行文件”错误:

如果你尝试对静态链接的可执行文件使用ldd,你可能会收到一个错误消息说“不是动态可执行文件”。这意味着该文件没有使用动态链接。在这种情况下,没有依赖关系可以显示。

使用ldd调试加载问题:

当你的程序因为缺少某个共享库而不能启动时,ldd可以帮助你快速识别缺少了哪个库。然后,你可以安装缺少的库或调整环境变量来解决问题。

高级用法

  1. 使用LD_TRACE_LOADED_OBJECTS环境变量
    ldd实际上是通过设置LD_TRACE_LOADED_OBJECTS=1环境变量来工作的。你可以直接使用这个环境变量来获取相同的输出,这在某些特殊情况下可能会有用:
LD_TRACE_LOADED_OBJECTS=1 /path/to/your/program
  1. 检查程序如何使用特定的共享库
    如果你想要检查一个程序是如何使用特定的共享库的,可以结合使用ldd和nm命令。首先使用ldd找出依赖,然后用nm检查符号信息:
ldd /path/to/your/program | grep libexample.so
nm -D /path/to/libexample.so
  1. 使用ldd进行安全检查
    虽然ldd主要用于依赖检查,但它也可以帮助识别潜在的安全风险。例如,通过检查程序依赖的库是否都来自可信路径,可以帮助识别可能的库劫持或路径注入问题。
ldd /path/to/your/program | grep -v "^/"
  1. 解决依赖问题
    当你遇到因缺少共享库而导致的程序启动问题时,ldd可以帮助你快速定位缺少哪个库。通过比较不同环境(例如,开发和生产)下的ldd输出,你可以找出缺失的依赖。

  2. 结合使用strace
    虽然不是ldd的直接用法,但结合使用strace可以帮助你深入了解程序在运行时的行为,包括它如何加载共享库。通过观察程序启动过程中的系统调用

    strace /path/to/your/program 2>&1 | grep openat  
    

nm 命令

nm命令在Linux中是一个非常有用的工具,它用于列出目标文件的符号表内容。符号表主要包含了程序中各种变量、函数的名称、类型、地址等信息。

下面是nm命令的一些基本用法:

查看目标文件的符号表:

nm 目标文件名

这将列出目标文件中所有符号的名称、类型和地址。

只显示未定义的符号:

nm -u 目标文件名

这个选项 (-u) 只会列出那些未定义的符号,这对于找出缺失的链接非常有用。

按大小排序显示符号:

nm --size-sort 目标文件名

使用 --size-sort 选项可以按照符号大小进行排序显示,这有助于分析哪些符号占用了较多空间。

只显示特定类型的符号:

nm --defined-only 目标文件名

通过 --defined-only 选项,可以只列出已定义的符号,忽略未定义的符号。

查看动态链接库中的符号:

 nm -D 动态链接库文件名

-D 或 --dynamic 选项用于查看动态链接库(.so 文件)中的符号。

过滤输出结果:

nm 目标文件名 | grep 符号名称

使用管道 (|) 和 grep 命令可以过滤输出结果,仅显示与特定符号名称相关的行。

查看C++程序的符号:

nm -C 目标文件名

-C 或 --demangle 选项用于显示C++程序中更易读的符号名称,因为C++编译器通常会改变函数名(名字修饰)以支持重载等特性。

解析C++的符号名:

C++程序中的符号名经过编译器处理后会变得难以阅读。使用c++filt工具可以将这些符号名解析成更易于理解的形式。

nm 目标文件名 | c++filt

这样可以使C++的复杂符号名变得可读。

使用正则表达式过滤符号:

nm命令支持使用正则表达式来过滤显示的符号,这在你想要查找符合特定模式的符号时非常有用。

nm 目标文件名 | grep '正则表达式'

例如,使用grep '^T’可以过滤出所有类型为T(即在文本段中的符号)的符号。

比较不同版本的二进制文件:
通过比较不同版本的二进制文件中的符号表,可以快速了解两个版本之间增加或删除了哪些功能。

nm -an 旧版本文件名 > old_symbols.txt
nm -an 新版本文件名 > new_symbols.txt
diff old_symbols.txt new_symbols.txt

这里,-a选项表示列出所有符号,包括调试符号;-n选项表示按照地址排序。

查看符号的大小:

#使用--print-size选项可以打印每个符号的大小,这对于分析程序占用空间非常有帮助。
nm --print-size 目标文件名

输出格式化的信息:

#nm命令允许通过--format或者-f选项指定输出格式,支持的格式包括bsd、sysv、posix等,这有助于根据需求调整输出信息的格式。
nm --format=sysv 目标文件名

查找静态库中未使用的函数:

#创建一个包含所有符号的列表,然后使用nm检查静态库(.a文件)中哪些函数未被使用。
nm --undefined-only 静态库文件名

这将列出所有未定义的符号,即可能未被使用的函数。

http://www.lryc.cn/news/347594.html

相关文章:

  • MYSQL数据库-SQL语句
  • MyBatis认识
  • 【WEEK11】 【DAY6】Employee Management System Part 7【English Version】
  • 【52】Camunda8-Zeebe核心引擎-Clustering与流程生命周期
  • 从零开始的软件测试学习之旅(八)jmeter线程组参数化及函数学习
  • 图文并茂:解析Spring Boot Controller返回图片的三种方式
  • 问题处理记录 | 表输出报错 Packet for query is too large (5,214,153 > 4,194,304).
  • 数据结构_栈和队列(Stack Queue)
  • 基于docker 的elasticsearch冷热分离及生命周期管理
  • pikachu靶场(xss通关教程)
  • 实验0.0 Visual Studio 2022安装指南
  • 数据结构之----线性表
  • thinkphp5.1 模型auto
  • 企业微信创建应用(一)
  • Cosmo Bunny Girl
  • 初始化linux数据盘(3TB)分区-格式化-挂载目录
  • NFS网络文件系统的应用
  • AttributeError: module ‘PIL.Image‘ has no attribute ‘ANTIALIAS‘
  • 进程的共享主存通信实验
  • 深度缓冲技术在AI去衣中的神奇作用
  • 能效?性能?一个关于Windows下使用openssl speed进行速度测试的诡异问题
  • block性能考虑和线程安全
  • 没有公网ip,如何实现外网访问内网?
  • Python中如何将小数转化为百分数进行输出
  • 加入全球少儿编程运动:Scratch让每个孩子都能成为创造者(Scratch最新版客户端和初/中/高级学习资料整理分享)
  • 引擎:主程渲染
  • Java 高级面试问题及答案
  • 邮件的安全认证(dkim/spf/dmarc)
  • 单调栈问题
  • Hexo博客重新部署与Git配置