Linux so加载顺序

背景

使用gcc8.2编译a.out,机器安装默认的版本为gcc3.4。使用ldd打印so依赖列表,此时libstdc++.so位于/usr/lib64目录下

Linux so加载顺序

打印程序运行时加载的so库列表,显示加载的是/home/xxx/gcc-8.2/lib/目录下的libstdc++.so

Linux so加载顺序使用默认版本编译的程序,运行时加载的时/usr/lib64目录下的libstdc++库

Linux so加载顺序

此时的环境变量LD_LIBRARY_PATH未设值

分析()

对比两个进程ldd的结果,可以看到ld-linux-x86-64.so.2是不一样的。加载器的路径是gcc写入到二进制文件中的,可以通过命令strings查看这个路径。修改gcc的spec文件可以重新指定加载器路径。

Linux so加载顺序

使用strings 查看两个ld-linux-x86-64.so的内容,可以看到内置的加载路径信息

Linux so加载顺序环境中/opt/comiler/gcc-8.2其实指向/home/xxx/gcc-8.2的符号链接

动态库查找顺序

编译时,ld-linux.so查找共享库的顺序:

  • ld-linux.so由gcc的spec文件中所设定
  • gcc --print-search-dirs所打印出的路径,主要是libgcc_s.so等库。可以通过GCC_EXEC_PREFIX来设定
  • LIBRARY_PATH环境变量中所设定的路径,或编译的命令行中指定的-L/usr/local/lib
  • binutils中的ld所设定的缺省搜索路径顺序,编译binutils时指定。(可以通过“ld --verbose | grep SEARCH”来查看)
  • 二进制程序的搜索路径顺序为PATH环境变量中所设定。一般/usr/local/bin高于/usr/bin
  • 编译时的头文件的搜索路径顺序,与library的查找顺序类似。一般/usr/local/include高于/usr/include

运行时,ld-linux.so查找共享库的顺序:

  • ld-linux.so在可执行的目标文件中被指定,可用readelf命令查看
  • 在ld-linux.so内置的lib路径下查找(猜的)
  • 在缺省/usr/lib和lib中搜索;当glibc安装到/usr/local下时,它查找/usr/local/lib
  • LD_LIBRARY_PATH环境变量中所设定的路径
  • /etc/ld.so.conf(或/usr/local/etc/ld.so.conf)中所指定的路径,由ldconfig生成二进制的ld.so.cache中

查看最终运行时加载的库

ld-linux.so加载器其实是个可执行程序,使用--list选项可以得到与ldd类似的结果,不过这个输出更加接近运行时的结果(还可以通过修改环境变量改变)。Linux so加载顺序

 

上一篇:Python 中 字符串、List、np.array 的互相转化


下一篇:中间件漏洞篇 iis短文件名漏洞与iis远程代码执行漏洞