几个命令查看ELF文件的“秘密”
首发:公众号【编程珠玑】
作者:守望先生
网站:https://www.yanbinghu.com/2019/10/13/54745.html
前言
在Linux中,可执行文件的格式是ELF格式,而有一些命令可以帮助我们了解它们更多的“秘密”,以此来帮助我们解决问题。
示例程序
我们的示例程序如下:
//来源:公众号【编程珠玑】
//hello.c
#include<stdio.h>
int main(int argc,char *argv[])
{printf("hello shouwangxiansheng\n");return 0 ;
}
编译:
$ gcc -o hello hello.c
得到hello可执行文件。
查看文件类型
file命令可以用来查看文件类型:
$ file hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 2.6.32, BuildID[sha1]=8f1de0f59bdfe9aaff85ade6898173aa436b296a, not stripped
从结果中,我们可以知道,它是ELF可执行文件,且是64位程序,有动态链接,最后的not stripped也表明了它保留了符号表信息或者调试信息。
如果不是可执行文件,它的信息是怎样的呢?举个例子:
$ file hello.c
hello.c: C source, UTF-8 Unicode text
看到了吧。
查看ELF头
readelf用于查看ELF文件,而:
$ readelf -h hello
ELF Header:Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64Data: 2's complement, little endianVersion: 1 (current)OS/ABI: UNIX - System VABI Version: 0Type: EXEC (Executable file)Machine: Advanced Micro Devices X86-64
(略)
可以看到它是EXEC,即可执行文件,且小端程序,运行于X86-64。在交叉编译的时候,这个文件头的信息也非常有用。例如你在x86的机器上交叉编译出powerpc的可执行文件,在powerpc上却不被识别,不能运行,不如用readelf看看它的Machine字段,是不是没有编译好。
查找ELF文件中的字符串
例如,你在文件中写入了版本号或者特殊字符串,可以通过strings命令搜索到:
$ strings hello|grep shouwang
hello shouwangxiansheng
查看ELF文件各段大小
$ size hellotext data bss dec hex filename1210 552 8 1770 6ea hello
这里可以看到代码段,数据段各自占多少,必要时候还可以根据需要优化代码,减少磁盘空间占用。
查看链接的动态库
运行时出现找不到动态库?不如看看它链接了哪些库吧:
$ ldd hellolinux-vdso.so.1 => (0x00007ffd16386000)libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f507e083000)/lib64/ld-linux-x86-64.so.2 (0x00007f507e44d000)
可以看到它链接的动态库是/lib/x86_64-linux-gnu/libc.so.6,而如果该文件不存在,则运行时将会出错。这里也可以参考《动态库的制作和使用》。
查看符号表
新加的函数或者全局变量不知道有没有编译进去?如何看看符号表里有没有吧(前提是符号表没有被去掉):
$ nm hello |grep main #符号表中查找main函数U __libc_start_main@@GLIBC_2.2.5
0000000000400526 T main
如果没有找到或者前面是U,没有地址,表明在这个elf文件中没有定义这个函数。
链接出问题的时候很有用奥。
为ELF文件瘦身
前面通过file查看文件时,看到有not stripped的字样,由于它里面包含了一些符号表信息,因为文件会稍大,如果去掉,二进制文件将会变小,但是里面的符号表信息也就没有了,将会影响问题定位。
$ ls -lh hello #瘦身前
-rwxrwxr-x 1 root root 8.4K
$ strip hello
$ ls -lh hello #瘦身后
-rwxrwxr-x 1 root root 6.2K
可以看到,瘦身后二进制文件变得更小。当可执行文件越大时,瘦身效果就会更明显了。当然放心,这不会影响程序的正常运行,只是对调试和问题定位有影响。
这个时候再看符号表:
$ nm hello
nm: hello: no symbols
打印文件校验和
二进制文件传输过程中有没有被损坏或者是否是同一个版本,看看校验和以及程序块计数吧:
$ sum hello
33513 7
当然你也可以使用:
$ md5sum hello
521efed706c3b485dd3b5e96e48b138a hello
来比对md5值。
总结
ELF文件中隐藏了丰富的信息,只要使用得当,将会帮助我们更好地进行开发或者问题的定位。
相关阅读:
Linux常用命令-开发调试篇
静态库和动态库
如何制作属于自己的静态库?
关注公众号【编程珠玑】,获取更多Linux/C/C++/Python/Go/算法/工具等原创技术文章。后台免费获取经典电子书和视频资源
几个命令查看ELF文件的“秘密”相关推荐
- windows用 tree命令查看目录文件夹结构
windows用 tree命令查看目录文件夹结构 ## 查看帮助 tree --helptree --dirsfirst --filelimit 6 -h -t –dirsfirst 目录优先展示 – ...
- 利用adb命令查看apk文件包名的一些方法
利用adb命令查看apk文件包名的一些方法 前提是已经下载android SDK并配好环境变量! 在控制台输入命令$adb shell pm 可以看到adb shell pm的相关用法,详细信息请自己 ...
- linux 查看文件哈希码,使用linux的sha1sum命令查看效验文件哈希值命令
服务器 今天小编给大家分享的是使用linux的sha1sum命令查看效验文件哈希值命令,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧.一定会有所收获的哦. sha1 ...
- 使用ls命令查看Linux的目录结构,linux ls命令查看目录文件详解
首页 > Linux教程 > 常用命令 > ls 查看目录文件 linux ls命令查看目录文件详解 linux中ls命令用来查看目录中的所有文件和子目录,可选的参数比较多,本文筛选 ...
- linux zcat 使用方法,使用linux的zcat命令查看压缩文件的内容
服务器 本篇文章和大家了解一下使用linux的zcat命令查看压缩文件的内容.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. zcat命令用于不真正解压缩文件,就能显示压缩包中文件的 ...
- readelf命令和ELF文件详解
ELF(Executable and Linking Format)是一个定义了目标文件内部信息如何组成和组织的文件格式.内核会根据这些信息加载可执行文件,内核根据这些信息可以知道从文件哪里获取代码, ...
- Linux 如何通过命令查看一个文件的某几行(中间几行或最后几行)
linux 如何显示一个文件的某几行(中间几行) [一]从第3000行开始,显示1000行.即显示3000~3999行 cat filename | tail -n +3000 | head -n 1 ...
- Linux如何通过命令查看日志文件的某几行(中间几行或最后几行)
linux 如何显示一个文件的某几行(中间几行) [一]从第3000行开始,显示1000行.即显示3000~3999行 cat filename | tail -n +3000 | head -n 1 ...
- Linux书签(05)用linux more命令查看日志文件
楔子:作为一名经常开车的老司机,查看日志文件是一种家常便饭.Linux more 命令就是这样一道非常下饭的菜,学会用它查看日志文件,也许会让很多问题及时被发现和定位. Linux more 命令 L ...
最新文章
- centos下wget时提示unable to resolve host address ...
- Cinder 组件详解 - 每天5分钟玩转 OpenStack(47)
- [翻译中] 使用Wayland替代X, 大幅提高图形速度
- Sonatype Nexus 库被删除的恢复方法
- 新浪微博视频批量上传大师 v3.1
- 三方协议接收节点不存在_【花开法务】没有保密协议是否意味着员工不存在保密义务?...
- JSTL获取session中的值
- elementui el-radio-group 分组排序问题
- JAVA Maven和ANT 安装 Linux(Ubuntu/Centos),Mac
- 电脑蓝牙在哪里打开_华为手机与华为Matebook笔记本如何通过蓝牙传输文件
- Git管理工具SourceTree文件预览乱码问题
- 机械工程专业英语词汇
- LayIM 3.9.1与ASP.NET SignalR实现Web聊天室快速入门(一)之效果展示与关键技术简介
- CFA一级考试题型是什么?好不好考?
- 怎么用dos命令打开计算机,如何使用DOS命令打开C盘下的文件夹dos如何打开文件夹...
- 如何在新的Apple TV遥控器上调整触摸灵敏度
- 在docker中运行自己的eureka服务端
- 【githubboy】一项视频自动抠图技术,强大、实时、高分辨率的人物视频抠图方法
- 《认知天性》让学习轻而易举的心理学规律
- Gamma 分布和Beta 分布简介
热门文章
- vue改变class内的属性_vue 绑定 添加class 属性 4种方法 添加style 3中方法 v-bind /:...
- 第一阶段:Java基础总复习一一一和一一一面向对象OOP总复习
- js html页面切换效果,jQuery实现切换页面过渡动画效果
- EXFS的块分配策略
- freetype 使用解析---矢量字体
- Codeforces Sereja and Mirroring
- 【测试招聘】资深面试官的测试工程师面试心得
- 雪花飘落-面向对象编程
- rank over pation
- 0x0EA772D7 (msvcr80.dll) 处有未经处理的异常: 0xC000041D: 用户回调期间遇到未经处理的异常。。