无法执行二进制文件: 可执行文件格式错误_几个命令了解ELF文件的”秘密“

前言

在Linux中,可执行文件的格式是ELF格式,而有一些命令可以帮助我们了解它们更多的“秘密”,以此来帮助我们解决问题。

8ced7398131fee6f433038083fb95cac.png

示例程序

我们的示例程序如下:

#include int main(int argc,char *argv[]) {        ntf("hello shouwangxiansheng");     return 0 ; } 

编译:

$ gcc -o hello hello.c 

得到hello可执行文件。

查看文件类型

file命令可以用来查看文件类型:

$ file hellohello: 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.chello.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:                             ELF64   Data:                              2's complement, little endian   Version:                           1 (current)   OS/ABI:                            UNIX - System V   ABI Version:                       0   Type:                              EXEC (Executable file)   Machine:                           Advanced Micro Devices X86-64 (略) 

可以看到它是EXEC,即可执行文件,且小端程序,运行于X86-64。在交叉编译的时候,这个文件头的信息也非常有用。例如你在x86的机器上交叉编译出powerpc的可执行文件,在powerpc上却不被识别,不能运行,不如用readelf看看它的Machine字段,是不是没有编译好。

查找ELF文件中的字符串

例如,你在文件中写入了版本号或者特殊字符串,可以通过strings命令搜索到:

$ strings hello|grep shouwanghello shouwangxiansheng 

查看ELF文件各段大小

$ size hello text       data     bss     dec     hex filename1210        552       8    1770     6ea hello 

这里可以看到代码段,数据段各自占多少,必要时候还可以根据需要优化代码,减少磁盘空间占用。

查看链接的动态库

运行时出现找不到动态库?不如看看它链接了哪些库吧:

$ ldd hello     linux-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 hellonm: hello: no symbols 

打印文件校验和

二进制文件传输过程中有没有被损坏或者是否是同一个版本,看看校验和以及程序块计数吧:

$ sum hello33513     7 

当然你也可以使用:

$ md5sum hello 521efed706c3b485dd3b5e96e48b138a  hello 

来比对md5值。

总结

ELF文件中隐藏了丰富的信息,只要使用得当,将会帮助我们更好地进行开发或者问题的定位。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这个报错信息是指在运行一个名称为cfw的可执行文件时,由于可执行文件格式错误无法运行。通常情况下,这可能是由于系统与可执行文件不兼容、缺少依赖项或者文件本身已经损坏。 * 如何解决这个问题? - 首先,检查可执行文件格式是否正确。可以使用file命令检查: $ file cfw cfw: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, not stripped 上述例子表示cfw是一个64位的Linux二进制文件。 如果格式正确,可以检查系统中是否已经安装了必要的依赖项。如果缺少依赖项,可以下载并安装它们。 如果以上两种方法都无效,可能就需要重新编译代码并生成新的可执行文件了。 总的来说,这个问题出现的原因可能有很多,需要根据具体情况采取相应的解决方案。 ### 回答2: 这个错误提示意味着尝试执行文件并不是有效的可执行二进制文件。这可能是由于多种原因引起的,例如: 1. 文件损坏:文件可能已损坏或下载过程中出现了错误,导致它不再是完整的可执行二进制文件。 2. 不兼容的体系结构:可执行文件可能是为其他体系结构编译的,不兼容当前的操作系统或硬件环境。 3. 没有运行权限:如果您尝试执行一个没有运行权限的文件,则会出现“无法执行二进制文件错误。 为了解决这个问题,您可以尝试以下一些方法: 1. 检查文件是否完整:尝试重新下载文件并检查其完整性,确保它没有损坏或缺失。 2. 检查文件类型:使用命令“file filename”来查看文件的类型和体系结构,确保它是适用于当前系统的有效可执行文件。 3. 设定执行权限:使用命令“chmod +x filename”来为文件添加执行权限,确保可以运行该文件。 4. 安装缺失的库:如果可执行文件需要依赖其他库文件,那么需要先安装这些库文件,以确保可执行文件可以正常运行。 总之, 您需要仔细检查文件的完整性,兼容性和权限,以确保该文件可以正常运行。 ### 回答3: 这个问题很可能是因为可执行文件对应平台不匹配导致的。在Linux系统中,可执行文件需要与当前运行的系统架构匹配,在32位系统上不能运行64位可执行文件,在64位系统上不能运行32位可执行文件。因此,当我们尝试运行一个不匹配的可执行文件时,就会出现类似于“bash: ./cfw:无法执行二进制文件: 可执行文件格式错误”的错误信息。 另外,一些其他的原因也可能引起这个问题,比如可执行文件没有执行权限或者文件本身损坏等。 解决这个问题的方法有以下几种: 1. 确认文件对应平台是否匹配。在Linux系统中,可以使用“uname -a”命令查看当前系统架构,并检查可执行文件是否有与之对应的版本。 2. 确认是否有执行权限。在Linux系统中,可以使用“ls -l filename”命令查看文件权限,使用“chmod +x filename”命令赋予可执行权限。 3. 确认文件是否损坏。在Linux系统中,可以使用“file filename”命令查看文件类型和属性,使用“md5sum filename”命令计算文件的MD5值,检查文件是否与原始文件一致。 4. 如果可执行文件是从其他系统中拷贝过来的,可以尝试重新编译一下程序,以确保在当前系统下可正常运行。 除此之外,在使用Linux系统时,我们也应该注意一些细节问题,比如不同版本系统之间的差异、文件系统类型、用户权限等等,这些都可能会影响可执行文件执行情况。如果问题无法解决,可以通过搜索或向社区求助等方式获取更多的帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值