Physical Address:
ChongQing,China.
WebSite:
本博客内容属于个人原创,由于能力有限,难免存有错误,还请各位不吝指正。
如需转载,请注明出处。
对于Linux或者Android系统开发者而言,经常会使用一些共享库(.so)。而如果你是C/C++开发者,类似于二进制文件(.bin),目标文件(.o)也会经常遇见。有些时候我们需要借助一些工具来帮忙检测这些文件,以确定其是否满足我们的使用需求。常见的场景如下:
你需要与人合作开发某个功能,当双方约定好接口后对方将会以.so的形式提供可执行文件,而你则需要引用该so,在使用时则通过接口调用完成交互。那么,当你拿到对方提供的so时,你需要先检查该so是否满足你的使用需求,你需要关注的信息包括:
在这种场景下,我们可以运用一些工具来对so库进行检测。以下是我个人日常比较喜欢的工具:
1.readelf工具
readelf是一个专门用于解析ELF(Executable and Linkable Format)文件的工具,elf文件包括.o文件、.so文件.elf文件等。如果你的系统内未安装readelf工具,请使用sudo apt install binutils命令进行安装。安装后可以通过readelf –help命令查看使用规则。如果你需要详细的说明,请使用man readelf命令进行查看。以下是一些常用的命令参数:
readelf -a *.so //查看so库的所有信息
readelf -s *.so //查看so库提供的外部接口
readelf -d *.so //查看so库提供的动态信息
那么,在本场景中,我们可以使用readelf -d *.so查看so库的一些基本信息,如下所示(示例中的so库为Ubantu中随便找的一个):
我们需要关注的字段包括:
NEEDED:表明该库所依赖的库,如果系统中不存在其所依赖的库,是无法编译成功的
SONAME:表明该so库的模块名称,如果你在编译时引用该so库的名称与此不一致,则会导致编译失败
此外,使用readelf -s *.so查看so库所提供的外部接口:
我们可以通过该命令查看so库是否按照双方的约定完成接口,如果so库中未提供所有你需要的接口,在编译时是无法通过的。
通过readelf -a *.so查看更多信息:
2.objdump工具
objdump是一个专门用于分析目标文件(object files)的工具,与readelf一样,其可以通过 sudo apt install binutils 进行安装。objdump相对于readelf并不是那么好用,其主要是用于汇编指令相关信息的查询,但是对于so我们还是可以通过objdump工具查询一些信息。如图所示:
3.nm工具
nm也是一个从object files中获取符号symbol的工具,与readelf和objdump相比,其功能没那么丰富,但是有一些差异化的特性。其常用的参数表如下:
nm [-A|-o|--print-file-name] [-a|--debug-syms]
[-B|--format=bsd] [-C|--demangle[=style]]
[-D|--dynamic] [-f<format>|--format=<format>]
[-g|--extern-only] [-h|--help]
[-l|--line-numbers] [-n|-v|--numeric-sort]
[-P|--portability] [-p|--no-sort]
[-r|--reverse-sort] [-S|--print-size]
[-s|--print-armap] [-t <radix>|--radix=<radix>]
[-u|--undefined-only] [-V|--version]
[-X 32_64] [--defined-only] [--no-demangle]
[--plugin <name>] [--size-sort] [--special-syms]
[--synthetic] [--target=bfdname]
[objfile...]
在日常使用中,一般使用-D参数获取符号表,如下图所示:
以上就是我们在开发过程中可以用于帮助我们解析可执行文件的一些工具。总结一下这三个工具: