了解ELF文件“秘密”的几个命令。示例程序我们的示例程序如下:#includeintmain(intargc,char*argv[]){printf("helloshouwangxiansheng\n");return0;}编译:$gcc-ohellohello.cgetshelloto成为可执行文件。查看文件类型file命令可以查看文件类型:$filehellohello:ELF64-bitLSBexecutable,x86-64,version1(SYSV),dynamicallylinked,interpreter/lib64/l,forGNU/Linux2.6.32,BuildID[sha1]=8f1de0f59bdfe9aaff85ade6898173aa436b296a,notstripped从结果可以知道是一个ELF可执行文件,而且是一个64位的动态链接程序。最后一个notstripped也说明它保留了符号表信息或者调试信息。如果不是可执行文件,它的信息是什么?比如:$filehello.chello.c:Csource,UTF-8Unicodetext,看吧。查看ELF头readelf用于查看ELF文件,同时:$readelf-hhelloELFHeader:Magic:7f454c46020101000000000000000000Class:ELF64Data:2'scomplement,littleendianVersion:1(current)OS/ABI:UNIX-SystemVABIVersion:0Type:EXEC(XDev8Micevancedach:EXEC(XDev8Micevancedmachine:Advanced)-64(略)可以看出是EXEC,就是一个可执行文件,是一个小端程序,运行在X86-64上,这个文件头的信息也很有用交叉编译。比如你在x86机器上交叉编译了一个powerpc可执行文件,但是在powerpc上不被识别,不能运行,那么最好用readelf查看它的Machine字段,看看是不是没有编译好。在ELF文件中查找字符串。比如文件中写了版本号或者特殊字符串,可以通过strings命令搜索:$stringshelo|grepshouwanghelloshouwangxiansheng查看ELF文件各段大小$sizehellotextdatabssdechexfilename1210552817706eahello这里可以看到代码segment,data每个segment占用多少,如果需要可以根据需要优化代码,减少磁盘空间占用。检查链接动态库时,运行时找不到动态库?为什么不检查它链接了哪些库:$lddhellolinux-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、如果文件不存在,运行时会报错。另请参阅此处的《动态库的制作和使用》。检查符号表中新增的函数或全局变量。不知道有没有编译进去?如何查看符号表中是否有(前提是符号表没有被移除):$nmhello|grepmain#在符号表中搜索main函数U__libc_start_main@@如果没有找到或者前面有GLIBC_2.2.50000000000400526Tmain通过U并且没有地址,这意味着这个函数没有在这个elf文件中定义。当链接有问题时很有用。瘦身ELF文件通过文件查看文件的时候,看到了notstripped的字样,因为里面包含了一些符号表信息,因为文件会稍微大一些,如果去掉,二进制文件会变小,但是符号表inside的信息就没有了,影响问题定位。$ls-lhhello#瘦身前-rwxrwxr-x1rootroot8.4K$striphello$ls-lhhello#瘦身后-rwxrwxr-x1rootroot6.2K可以看到瘦身后二进制文件变小了。当可执行文件较大时,瘦身效果会更加明显。当然放心,这不会影响程序的正常运行,只是影响调试和问题定位。这个时候再看看符号表:$nmhellonm:hello:nosymbols打印文件校验和和二进制文件是否损坏或者传输时是否是同一个版本,检查校验和和程序块数:$sumhello335137当然是你您也可以使用:$md5sumhello521efed706c3b485dd3b5e96e48b138ahello来比较md5值。综上所述,ELF文件中隐藏着丰富的信息,只要使用得当,将有助于我们更好的开发或定位问题。