Linux下二进制可执行文件分析 (nm,readelf,objdump 命令使用)

news/2024/7/5 7:43:32/文章来源:https://www.cnblogs.com/peifx/p/18278192

最近在调试一些问题,发现几个命令很实用,记录一下。

一  背景

        也许大家都遇到过这种场景,就是有二进制代码,比如深度分析下此文件到底是什么格式的图片等,这篇文章就记录我分析下二进制可执行文件的过程,已经自己读写二进制文件的一些坑。分析的二进制执行文件为linux下的可执行文件。

二  常用二进制文件静态分析命令

 2.1 file基本信息查看

     Linux下有个最常用的通用命令,来分析任何文件的基本格式,那就是file,来看下:

    可以看到基本信息,比如是什么类型文件,只是概述,还有些其他选项,可以用 -h 查看。

2.2 ldd动态链接库信息

 动态链接库,即没有在编译链接的时候直接打入到程序中的,而是运行时候动态加载了,从而节省内存,通过动态链接库,我们可以知道这个可执行文件用了哪些动态库,方法也比较简单。

 这是我写的一个小程序的动态链接库信息,通过链接库分析的信息也同样比较少,用这个命令多查看依赖链接库找不到的问题。

2.3 nm符号查看

nm可以列出二进制可执行文件,动态库,静态库中的符号信息,包括符号的类型,符号名称,比如函数名,全局变量等,通过这些信息可以看到不少有用的信息,通过函数名猜函数功能,使用的帮助如下:

配合grep信息可以很方便的进行符号搜索:

对于一些动态库,直接nm可能查不到信息,可以通过 nm -D 命令查看。

2.4 strings 查看二进制文件中的字符串

strings信息可以打印二进制文件中的字符串信息,结合grep进行搜索,用grep命令其实可以直接在二进制文件中搜索内容,但是不够直观,用strings看起来的更直观些:

strings 会把任何可打印字符串都显示出来,比nm的内容更多,截取部分如下:

2.5 objdump 将二进制代码转汇编指令

objdump是个值得深入学习的指令,不光可以还原汇编指令,还可以读取二进制中特定段的信息,更可怕的是,如果我们的程序是以-g -o0等调试不优化的情况下,用objdump -S指令可能尽可能地还原源代码信息(没看错,是还原出源代码信息),其实也可以理解这些信息是完整的在可执行文件中的,要不然gdb调试的时候没办法单步追踪了,测试如下:

参数选项:

复制代码
  1 --archive-headers 
  2 -a 
  3 显示档案库的成员信息,类似ls -l将lib*.a的信息列出。 
  4  
  5 -b bfdname 
  6 --target=bfdname 
  7 指定目标码格式。这不是必须的,objdump能自动识别许多格式,比如: 
  8  
  9 objdump -b oasys -m vax -h fu.o 
 10 显示fu.o的头部摘要信息,明确指出该文件是Vax系统下用Oasys编译器生成的目标文件。objdump -i将给出这里可以指定的目标码格式列表。 
 11  
 12 -C 
 13 --demangle 
 14 将底层的符号名解码成用户级名字,除了去掉所开头的下划线之外,还使得C++函数名以可理解的方式显示出来。 
 15  
 16 --debugging 
 17 -g 
 18 显示调试信息。企图解析保存在文件中的调试信息并以C语言的语法显示出来。仅仅支持某些类型的调试信息。有些其他的格式被readelf -w支持。 
 19  
 20 -e 
 21 --debugging-tags 
 22 类似-g选项,但是生成的信息是和ctags工具相兼容的格式。 
 23  
 24 --disassemble 
 25 -d 
 26 从objfile中反汇编那些特定指令机器码的section。 
 27  
 28 -D 
 29 --disassemble-all 
 30 与 -d 类似,但反汇编所有section. 
 31  
 32 --prefix-addresses 
 33 反汇编的时候,显示每一行的完整地址。这是一种比较老的反汇编格式。 
 34  
 35 -EB 
 36 -EL 
 37 --endian={big|little} 
 38 指定目标文件的小端。这个项将影响反汇编出来的指令。在反汇编的文件没描述小端信息的时候用。例如S-records. 
 39  
 40 -f 
 41 --file-headers 
 42 显示objfile中每个文件的整体头部摘要信息。 
 43  
 44 -h 
 45 --section-headers 
 46 --headers 
 47 显示目标文件各个section的头部摘要信息。 
 48  
 49 -H 
 50 --help 
 51 简短的帮助信息。 
 52  
 53 -i 
 54 --info 
 55 显示对于 -b 或者 -m 选项可用的架构和目标格式列表。 
 56  
 57 -j name
 58 --section=name 
 59 仅仅显示指定名称为name的section的信息 
 60  
 61 -l
 62 --line-numbers 
 63 用文件名和行号标注相应的目标代码,仅仅和-d、-D或者-r一起使用使用-ld和使用-d的区别不是很大,在源码级调试的时候有用,要求编译时使用了-g之类的调试编译选项。 
 64  
 65 -m machine 
 66 --architecture=machine 
 67 指定反汇编目标文件时使用的架构,当待反汇编文件本身没描述架构信息的时候(比如S-records),这个选项很有用。可以用-i选项列出这里能够指定的架构. 
 68  
 69 --reloc 
 70 -r 
 71 显示文件的重定位入口。如果和-d或者-D一起使用,重定位部分以反汇编后的格式显示出来。 
 72  
 73 --dynamic-reloc 
 74 -R 
 75 显示文件的动态重定位入口,仅仅对于动态目标文件意义,比如某些共享库。 
 76  
 77 -s 
 78 --full-contents 
 79 显示指定section的完整内容。默认所有的非空section都会被显示。 
 80  
 81 -S 
 82 --source 
 83 尽可能反汇编出源代码,尤其当编译的时候指定了-g这种调试参数时,效果比较明显。隐含了-d参数。 
 84  
 85 --show-raw-insn 
 86 反汇编的时候,显示每条汇编指令对应的机器码,如不指定--prefix-addresses,这将是缺省选项。 
 87  
 88 --no-show-raw-insn 
 89 反汇编时,不显示汇编指令的机器码,如不指定--prefix-addresses,这将是缺省选项。 
 90  
 91 --start-address=address 
 92 从指定地址开始显示数据,该选项影响-d、-r和-s选项的输出。 
 93  
 94 --stop-address=address 
 95 显示数据直到指定地址为止,该项影响-d、-r和-s选项的输出。 
 96  
 97 -t 
 98 --syms 
 99 显示文件的符号表入口。类似于nm -s提供的信息 
100  
101 -T 
102 --dynamic-syms 
103 显示文件的动态符号表入口,仅仅对动态目标文件意义,比如某些共享库。它显示的信息类似于 nm -D|--dynamic 显示的信息。 
104  
105 -V 
106 --version 
107 版本信息 
108  
109 --all-headers 
110 -x 
111 显示所可用的头信息,包括符号表、重定位入口。-x 等价于-a -f -h -r -t 同时指定。 
112  
113 -z 
114 --disassemble-zeroes 
115 一般反汇编输出将省略大块的零,该选项使得这些零块也被反汇编。 
116  
117 @file 
118 可以将选项集中到一个文件中,然后使用这个@file选项载入。
复制代码

关于符号表字段下面直接只介绍部分常用的:

复制代码
 1 .text:已编译程序的机器代码。
 2 .rodata:只读数据,比如printf语句中的格式串和开关(switch)语句的跳转表。
 3 .data:已初始化的全局C变量。局部C变量在运行时被保存在栈中,既不出现在.data中,也不出现在.bss节中。
 4 .bss:未初始化的全局C变量。在目标文件中这个节不占据实际的空间,它仅仅是一个占位符。目标文件格式区分初始化和未初始化变量是为了空间效率在:在目标文件中,未初始化变量不需要占据任何实际的磁盘空间。
 5 .symtab:一个符号表(symbol table),它存放在程序中被定义和引用的函数和全局变量的信息。一些程序员错误地认为必须通过-g选项来编译一个程序,得到符号表信息。实际上,每个可重定位目标文件在.symtab中都有一张符号表。然而,和编译器中的符号表不同,.symtab符号表不包含局部变量的表目。
 6 .rel.text:当链接噐把这个目标文件和其他文件结合时,.text节中的许多位置都需要修改。一般而言,任何调用外部函数或者引用全局变量的指令都需要修改。另一方面调用本地函数的指令则不需要修改。注意,可执行目标文件中并不需要重定位信息,因此通常省略,除非使用者显式地指示链接器包含这些信息。
 7 .rel.data:被模块定义或引用的任何全局变量的信息。一般而言,任何已初始化全局变量的初始值是全局变量或者外部定义函数的地址都需要被修改。
 8 .debug:一个调试符号表,其有些表目是程序中定义的局部变量和类型定义,有些表目是程序中定义和引用的全局变量,有些是原始的C源文件。只有以-g选项调用编译驱动程序时,才会得到这张表。
 9 .line:原始C源程序中的行号和.text节中机器指令之间的映射。只有以-g选项调用编译驱动程序时,才会得到这张表。
10 .strtab:一个字符串表,其内容包括.symtab和.debug节中的符号表,以及节头部中的节名字。字符串表就是以null结尾的字符串序列。
复制代码

 

2.6 readelf 读取ELF文件格式

如果二进制文件是ELF格式的,通过 file 文件可以查看文件格式.使用 readelf 指令可以方便分析ELF文件的结构,比如节信息,elf头文件信息,比如我们在分析文件是否为病毒文件的时候,需要读取 elf 文件头信息,做一些特征的判断,或作为特征参与机器学习的判断。

 readelf读取文件头

还有些其他命令,有兴趣的小伙伴,可以通过-h命令还原看下。

三 动态查看文件结构

3.1 ltrace 跟踪进程调用库函数过程

这也是一个很棒的命令,我们可以查看程序执行的时候调用库函数信息,还可以在线查看执行的进程的库函数调用情况,找几个比较典型的命令,测试的代码比较简单如下:

复制代码
 1 #include <stdlib.h>
 2 #include <stdio.h>
 3 
 4 int main(void)
 5 {
 6    short shs[5] ={1,234,567,789,890};
 7    int   ins[5] ={890,88111,23333,7777,6666};
 8    FILE * fp = fopen("a.bin","wb");
 9    for (int i = 0; i < 5; i++) {
10        fwrite(&shs[i],sizeof(short),1,fp);
11        fwrite(&ins[i],sizeof(int),1,fp);
12    }
13    printf("read....\n");
14    fclose(fp);
15    fp = fopen("a.bin","rb");
16    short a;
17    int b;
18   for (int i = 0; i <5;i++) {
19      fread(&a,sizeof(short),1,fp);
20      fread(&b,sizeof(int),1,fp);
21      printf("i:%d a:%d,b:%d\n", i,a,b);
22   }
23    fclose(fp);
24   return 0;
25 }
复制代码

3.1.1 ltrace 查看库函数调用情况

ltrace 查看库函数调用情况

3.1.2 ltrace 查看库函数调用占用时间

这在查看系统调用耗时很有用。

1 # -T 是查看调用时间开销
2 ltrace -T
3 #-t -tt -ttt 是查看调用绝对时间,t越多越精确
4 ltrace -t

ltrace 查看绝对时间。

3.1.3 ltrace 查看系统调用信息

1 ltrace -S

系统调用信息显然比库函数显示更多,追踪更复杂的情况可以使用。

还有 -p pid 追踪具体的进行id的调用情况也很有用,这里面就不举例子了。如果没有这个命令,如果是centos环境可以通过yum install -y ltrace安装。

3.2 strace

strace和ltrace的命令差不多,strace更偏向于系统调用的追踪或信号产生的情况。安装命令yum -y install strace

强大地方在于可以指定系统调用的类型:

复制代码
 1 -e trace=set 
 2 只跟踪指定的系统 调用.例如:-e trace=open,close,rean,write表示只跟踪这四个系统调用.默认的为set=all. 
 3 -e trace=file 
 4 只跟踪有关文件操作的系统调用. 
 5 -e trace=process 
 6 只跟踪有关进程控制的系统调用. 
 7 -e trace=network 
 8 跟踪与网络有关的所有系统调用. 
 9 -e strace=signal 
10 跟踪所有与系统信号有关的 系统调用 
11 -e trace=ipc 
12 跟踪所有与进程通讯有关的系统调用 
13 -e abbrev=set 
14 设定 strace输出的系统调用的结果集.-v 等与 abbrev=none.默认为abbrev=all. 
15 -e raw=set 
16 将指 定的系统调用的参数以十六进制显示. 
17 -e signal=set 
18 指定跟踪的系统信号.默认为all.如 signal=!SIGIO(或者signal=!io),表示不跟踪SIGIO信号. 
19 -e read=set 
20 输出从指定文件中读出 的数据.例如: 
21 -e read=3,5 
22 -e write=set 
复制代码

比如以下命令:

还有很多有用的选项,有兴趣的可以尝试下。

四 图形化界面分析二进制执行文件

网上找到一个图形化界面分析二进制程序的,名字叫Relyze 虽然是收费的,但是可以正常用一段时间,一段时间后才提示,界面如下,强大之处在于可以显示调用关系信息等。其实原理都类似,没有比命令行更多的功能,只是看起来更方便而已。

4.1 基本文件信息

 

可执行文件基本信息

4.2 头和段信息查看

 

头和段信息

4.3 搜索

 

字符信息搜索

4.4 调用关系图

双击可以看到调用关系图信息,便于做进一步分析。

 

其他的也没啥特殊点了,有兴趣的朋友可以下载试试。

 

 参考文章:

https://blog.csdn.net/mseaspring/article/details/110359312

objdump 命令解析:

https://blog.csdn.net/q2519008/article/details/82349869

简书--使用 readelf 和 objdump 解析目标文件:

https://www.jianshu.com/p/863b279c941e

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/735824.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

hypernetwork在SD中是怎么工作的

大家在stable diffusion webUI中可能看到过hypernetwork这个词,那么hypernetwork到底是做什么用的呢?大家在stable diffusion webUI中可能看到过hypernetwork这个词,那么hypernetwork到底是做什么用的呢? 简单点说,hypernetwork模型是用于修改样式的小型神经网络。 什么是…

使用 ROS2的多机器人探索

原文链接:https://www.youtube.com/watch?v=J0RZP_xJ3XA This video shows a demonstration of the SOS project, dedicated to forest fire detection using a fleet of robots. Several important issues are addressed. 这段视频展示了SOS项目的演示,该项目致力于使用机…

企业生产环境Nacos集群部署示例

Nacos运行环境需要jdk环境,集群各节点服务器需安装jdk1.8: jdk-8u341-linux-x64.tar 第一步:上次安装包 第二步:解压 sudo tar -zxvf jdk-8u341-linux-x64.tar.gz 第三步: 配置环境变量sudo vim /etc/profile 第四步:添加以下内容 export JAVA_HOME=/usr/local/jdk1.8.0…

Identity-aware Graph Neural Networks

目录概ID-GNNYou J., Gomoes-Selman J., Ying R. and Leskovec J. Identity-aware graph neural networks. AAAI, 2021.概 提出了一种能够超越 1-WL-Test 的 GNN. ID-GNNID-GNN 的 motivation 主要如下:主要到, 传统的 MPNN, 即第 \(k\) 层: \[\mathbf{m}_u^{(k)} = \text{MSG}…

AMM论文阅读笔记

AMM: Attentive Multi-field Matching for News Recommendation论文阅读笔记 Abstract 现存的问题: ​ 个性化新闻推荐是帮助用户找到感兴趣新闻的关键技术,而如何精确匹配用户兴趣和候选新闻是新闻推荐的核心。现有研究一般通过聚合用户浏览过的新闻来学习用户的兴趣向量,…

没有MAC电脑,如何申请苹果开发证书、上架APP Store?

【引言】 使用uni-app进行跨平台APP开发时,苹果ios平台最终还是要通过APP Store渠道发布,调试时uni-app基座也必须使用开发者证书签名后才能安装。对于使用MAC电脑的开发者,倒也不存在什么大障碍,照着文档操作就行,但是对于不使用MAC电脑,身边也没有MAC电脑,采购预算又紧…

知网文献下载助手 ——油猴脚本推荐

知网文献下载收费太贵了,只能逼我去找脚本来下载了。 在Greasyfork尝试了很多个脚本,坑爹的比较多,对比下来,我觉得这个“知网下载助手”比较容易用, 当然是纯免费的,需要的可以试试:知网下载助手https://greasyfork.org/zh-CN/scripts/492511

类人型自主机器人会打太极拳,但功夫很弱-斯坦福HumanPlus机器人

原文链接:https://newatlas.com/robotics/autonomous-humanoid-robot-shadows-humans/ The HumanPlus, with a 0-0 record, lands a 1, 2 left, right punch Stanford Humanplus HumanPlus以0比0的战绩,命中了1次左、右两拳。 斯坦福…

Rougamo、Fody 实现静态Aop

最近在看项目,看到别人使用Rougamo框架,好奇花了点时间仔细研究了,在这里记录一下。 0. 静态编织 Aop 首先,我们先了解什么是Aop? Aop 是指面向切面编程 (Aspect Oriented Programming),而所谓的切面,可以认为是具体拦截的某个业务点。 我们常用的aop框架是 AspectCore,…

WhaleStudio 2.6正式发布,WhaleTunnel同步性能与连接器数量再创新高!

在这个数据驱动的大模型时代,数据集成的作用和意义愈发重要。数据不仅仅是信息的载体,更是推动企业决策和创新的关键因素。作为全球最流行的批流一体数据集成工具,WhaleTunnel随着WhaleStudio 2.6版本正式发布,带来了多项功能增强和新特性,性能大幅提升,连接器和功能方面…

代码随想录算法训练营第四十二天 | 1049最后一块石头的重量II 494.目标和 474.一和零

1049.最后一块石头的重量 题目链接 文章讲解 视频讲解解题思路:将石头尽量分为相等的两堆,两堆最差即为所求结果石头的重量就是石头的价值动规五部曲:dp[j]:表示背包容量为j时可以装的石头的总价值 递推公式:dp[j] = max(dp[j], dp[j-stones[i]] + stones[i] 初始化:均初…

Apache DolphinScheduler社区又一PMC获推选通过!

PROFILE姓名:程鑫 公司:阿里云 职位:开发工程师 Github ID: rickchengx 从事领域:大数据调度系统开发 兴趣爱好:健身推举理由 他于2022年8月2日开始了他的DolphinScheduler之旅,在社区工作了将近两年,并于2023年5月12日成为Committer。成为Committer后的一年里,他继续保…

BOSHIDA 探讨DC/AC电源模块为绿色能源应用提供可靠的转换解决方案

BOSHIDA 探讨DC/AC电源模块为绿色能源应用提供可靠的转换解决方案 DC/AC电源模块是一种能够将直流电源转换为交流电源的装置。随着绿色能源的不断发展和应用,DC/AC电源模块在可再生能源、电动车辆、太阳能发电等领域中扮演着重要的角色。本文将着重探讨DC/AC电源模块为绿色能源…

Centos7 安装Rabbitmq3.9.11

安装erlang 安装依赖包yum -y install gcc glibc-devel make ncurses-devel openssl-devel xmlto perl wget gtk2-devel binutils-devel下载wget https://github.com/erlang/otp/releases/download/OTP-24.1.7/otp_src_24.1.7.tar.gz解压tar -zxvf otp_src_24.1.7.tar.gz转移到…

mysql数据库简介

一、数据库介绍 1.数据库基本概念 数据(Data) 描述事物的符号记录 包括数字,文字、图形、图像、声音、档案记录等 以“记录”形式按统一的格式进行存储 表 将不同的记录组织在一起 用来存储具体数据 数据库 表的集合,是存储数据的仓库 以一定的组织方式存储的相互有关的数据…

mac 电脑查看已安装的谷歌插件

1、打开谷歌浏览器 地址栏上面输入  chrome://version/ 2、找到 个人资料路径: /Users/admin/Library/Application Support/Google/Chrome/Default3、打开个新窗口 地址了上输入:个人资料路径 ,并找到 Extensions/ 文件夹 4、里面都是已安装的谷歌插件, 想要哪个插件…

Nordic nRF Connect SDK(NCS) VS Code 安装记录

1.Nordic SDK Nordic有2套并存的SDK:老的nRF5 SDK和新的nRF Connect SDK(NCS),两套SDK相互独立,大家选择其中一套进行开发即可。 一般而言,如果你选择的芯片是nRF51或者nRF52系列,那么推荐使用nRF5 SDK。 如果你选择的是Nordic最新产品系列,比如nRF53或者nRF9160,那么…

浅谈 K8s Service 网络机制

浅谈 K8s Service 网络机制 云原生运维圈 2024-07-01 12:03 上海 1人听过以下文章来源于腾讯云原生 ,作者王成腾讯云原生. 云原生技术交流阵地,汇聚云原生最新技术资讯、文章、活动,以及云原生产品及用户最佳实践内容。王成,腾讯云研发工程师,Kubernetes member,从事数据…

全新升级!中央集中式架构功能测试为新车型保驾护航

目前,文中所述功能测试新方案均已应用于国内多款新架构车型的研发,得到了广泛认可。 “软件定义汽车”新时代下,整车电气电气架构向中央-区域集中式发展已成为行业共识,车型架构的变革带来更复杂的整车功能定义、更多的新技术的应用(如SOA服务化、智能配电等)和更…

江门MES制造执行系统:助力工厂实现智能化管理

江门MES制造执行系统(MES)在工厂实现智能化管理方面发挥着重要作用,以下是它的一些助力方面: 实时监控与控制:江门MES系统可以实时监控生产过程中的各个环节,包括设备状态、生产进度、质量指标等,帮助工厂管理人员及时了解生产情况并做出相应的调整和控制。生产计划与排程…