欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Linux二进制文件操作工具

程序员文章站 2022-04-11 10:22:16
...

1 快速查看工具

可以利用file和size来简单直接的查看二进制文件的细节。

1.1 file

命令行工具file可以用于查看几乎任何类型文件的详细信息。如 Linux二进制文件操作工具

1.2 size

命令行工具size能够快速地获取ELF节的字节长度。
Linux二进制文件操作工具

2 详细信息分析工具

可以使用binutils的工具集合获取有关二进制文件属性的详细信息。下面介绍ldd,nm,objdump,readelf工具。

2.1 ldd

ldd命令可以显示出二进制文件启动时需要静态加载的动态库的完整列表(加载时依赖项)。
链接器会将直接依赖项的列表写入二进制文件的ELF格式字段中,在分析加载时依赖项时,ldd首先会扫描二进制文件并尝试找到这些信息。通过递归搜索完成后,ldd会收集找到的依赖项,然后去掉重复项,将结果打印出来。
ldd搜索顺序:
如果指定了RUNPATH字段(即DT_RUNPATH字段非空)

  1. LD_LIBRARY_PATH。
  2. runpath(DT_RUNPATH)。
  3. ld.so.cache。
  4. 默认库路径(/lib64和/usr/lib64)。
    如果未指定RUNPATH字段(即DT_RUNPATH字段为空)
  5. 被加载库的RPATH,然后是二进制文件的RPATH,直到可执行文件或者动态库将这些库全部加载完毕。
  6. LD_LIBRARY_PATH。
  7. ld.so.cache。
  8. 默认库路径(/lib64和/usr/lib64)。
ldd rocketmq

Linux二进制文件操作工具
由于在一些环境下,ldd会尝试执行程序获取依赖信息,不够安全,可采用下面方法:

objdump –p /path/to/program |grep NEEDED

Linux二进制文件操作工具

readelf –d  /path/to/program |grep NEEDED

Linux二进制文件操作工具
但是这两个命令提供的依赖项列表远不如ldd提供的完整。

2.2 nm

nm可以列出二进制文件的符合列表。该工具可以输出符合并显示出对应的符合类型。如果二进制文件包含C++代码,默认会打印出经过名称修饰之后的符号名。下面介绍几种常用用法:
nm <二进制文件路径>:列出二进制文件的所有符合。对于共享库而言,不仅会列出导出的符号,也会列出其他所有符号,如果使用strip去除了库文件的某些符号,那么在不使用-D参数时,nm将找不到这些去除的符号。
nm –D <二进制文件路径>:只列出动态节中的符号(即动态库中导出的或对外可见的符号)。

nm -D rocketmq

Linux二进制文件操作工具

nm –C<二进制文件路径>:列出未经过名称修饰的格式。

nm -C rocketmq

Linux二进制文件操作工具

nm –C —no-demangle<二进制文件路径>:打印出共享库中名称修饰后的动态符号。

nm -C --no-demangle rocketmq

Linux二进制文件操作工具

nm –A <库文件路径>/*|grep symbol-name:当你在相同目录下的二进制文件中搜索符号时,该命令非常有用,因为-A选项会将所有在库中找到的符号名打印出来。
nm –u <二进制文件路径>:列出库中未定义的符号。

2.3 objdump

objdump功能最丰富的二进制分析工具,不仅支持ELF格式,还有大概50中其他格式。
1) 解析ELF头
objdump命令的-f选项可以用来获取目标文件头信息。ELF头提供了大量有用的信息。尤其可以通过ELF头信息快速获取二进制文件的类型和入口点信息。查看静态库时,会打印出在库中找到的每个目标文件的ELF头信息。

objdump -f rocketmq
objdump -f a.exe
 objdump -f librocketmq.so

Linux二进制文件操作工具

objdump -f libhiredis.a

Linux二进制文件操作工具

2) 列出并查看节信息

objdump -h rocketmq

Linux二进制文件操作工具

3) 列出所有符号

objdump -t rocketmq

Linux二进制文件操作工具
Linux二进制文件操作工具

4) 只列出动态符号

objdump -T rocketmq

Linux二进制文件操作工具

5) 查看动态节
主要关注后半部分的输出。

objdump -p rocketm

Linux二进制文件操作工具
Linux二进制文件操作工具

6) 查看重定位节

objdump -R rocketmq

Linux二进制文件操作工具

7) 查看节中的数据

objdump -s -j .got rocketmq

Linux二进制文件操作工具

8) 列出并查看段

objdump -p rocketmq

Linux二进制文件操作工具
第一部分为段的名称

9) 反汇编代码

objdump -d -s -M intel  rocketmq |grep -A 10 "doConsumeMessage"

Linux二进制文件操作工具

  1. objdump和nm的等价功能
    nm <二进制文件路径> 等价于 objdump –t <二进制文件路径>
    nm –D <二进制文件路径> 等价于 objdump –T <二进制文件路径>
    nm –C <二进制文件路径> 等价于 objdump –C <二进制文件路径>

2.4 readelf

readelf和objdump功能类似,区别在于,只支持ELF二进制格式;不依赖于二进制文件描述库。
1) 解析ELF头
readelf –h命令行选项用于获取目标文件头信息。ELF头提供了大量有用的信息。尤其可以通过ELF头信息快速获取二进制文件的类型和入口点信息。查看静态库时,会打印出在库中找到的每个目标文件的ELF头信息。

readelf -h rocketmq

Linux二进制文件操作工具

readelf -h librocketmq.so

Linux二进制文件操作工具

readelf -h libhiredis.a

Linux二进制文件操作工具

2) 列出并查看节信息

readelf -S rocketmq

Linux二进制文件操作工具

3) 列出所有符号

readelf --symbols rocketmq

Linux二进制文件操作工具

4) 只列出动态符号

readelf --dyn-syms rocketmq

Linux二进制文件操作工具

5) 查看动态节

readelf -d rocketmq

Linux二进制文件操作工具

6) 查看重定位节

readelf -r rocketmq

Linux二进制文件操作工具

7) 查看节中数据

readelf -x .got rocketmq

Linux二进制文件操作工具

8) 列出并查看段

readelf --segments rocketmq

Linux二进制文件操作工具

9) 检测二进制文件是否包含调试信息

readelf --debug-dump rocketmq

Linux二进制文件操作工具

由于有可能打印会特别多,可使用统计行数查看
readelf --debug-dump rocketmq |wc –l
Linux二进制文件操作工具

3 部署阶段工具

3.1 chrpath

chrpath可以修改ELF文件的rpath(DT_RPATH字段)。
可以在DT_RPATH原始字符串长度的范围内对其进行修改。
可以删除原有的DT_RPATH字段。
如果原始是空的,不能使用任何的非空字符串替代原有字段。
可以将DT_RPATH转换成DT_RUNPATH。
用于替换的字符串长度不能超过原始长度。
修改:

 readelf -d rocketmq |grep RPATH
 chrpath -r /bin ./rocketmq 
 readelf -d rocketmq |grep RPATH

Linux二进制文件操作工具
删除

 readelf -d rocketmq |grep RPATH
 chrpath -d rocketmq
 readelf -d rocketmq |grep RPATH

Linux二进制文件操作工具

3.3 strip

可以清楚所有动态加载过程中不需要的库文件符号。

 strip teststrip.so 
 nm teststrip.so

Linux二进制文件操作工具

3.4 ldconfig

将共享库文件的路径作为输入参数传递给ldconfig时,ldconfig会搜索共享库路径,并更新用于记录这些信息的文件:
/etc/ld.so.conf文件:包含了一组目录列表,默认会扫描里面的库文件。
/etc/ld.so.cache文件:将多个路径作为输入参数传递给ldconfig时,ldconfig会将整个扫描过程中查找到动态库的文件名以ASCII文本列表的形式写入这个文件。

  ldd rocketmq 
  ldconfig /mnt/hgfs/share/tool/
  ldd rocketmq

Linux二进制文件操作工具Linux二进制文件操作工具