该程序如何静态链接到非默认路径中的 .so

该程序如何静态链接到非默认路径中的 .so

我正在使用的程序只能通过自定义安装程序(IDA Freeware Demo)进行安装。我已将其安装在我的主目录中,一切运行正常。

现在我注意到,当使用 ldd 检查程序时:它附带了自己的 Qt 库,这些库作为共享库放在其安装目录中(因此其主可执行文件位于同一目录中,而不是 /usr/lib 或类似的目录中)。

$ ldd ida64
    linux-vdso.so.1 =>  (0x00007ffec5fb9000)
    libida64.so => /home/asdf/idafree-7.0/./libida64.so 
    libQt5PrintSupport.so.5 => /home/asdf/idafree-7.0/./libQt5PrintSupport.so.5
    libQt5Widgets.so.5 => /home/asdf/idafree-7.0/./libQt5Widgets.so.5 
....

(安装目录 = /home/asdf/idafree-7.0/)

现在我想知道:它是怎么做到的?我直接执行该程序,没有任何 LD_LIB_PATH 魔法。

答案1

这与静态链接完全不同,也毫不相关。虽然我猜想包装器脚本可以在启动程序之前修改 LD_LIBRARY_PATH,但 IDA 不会这么做。

当共享库首次从其组成对象文件链接时,可以指定运行时路径,即--set-rpath(简称-r)标志。这会通知加载器在查找其他地方之前先查找指定的目录。该路径可能是硬编码的,也可以使用标志$ORIGIN

$ORIGIN标志允许加载程序解析可执行文件的当前文件路径,从而允许 rpath 更轻松地从任何目录工作。IDA 可能只是使用诸如 之类的标志构建的-Wl,-r,$ORIGIN。如果 Qt 库位于子目录中,它就只是-Wl,-r,$ORIGIN/qtlibdir

还有一些实用程序可以在链接后编辑该字段,例如 patchelf。

所有这些信息都可以在 ld 手册中找到。 https://man7.org/linux/man-pages/man1/ld.1.html

答案2

简单解释一下如何运行需要唯一 LD_LIBRARY_PATH 的可执行文件,例如当前目录中的 libs 路径/:

简短:export LD_LIBRARY_PATH=.其中点() 表示‘当前目录’

通常还需要包括系统 LD_LIBRARY_PATH:export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

例如“硬编码” ida64:可执行文件中首先要运行的函数是设置唯一的LD_LIBRARY_PATH。……其他示例:firefox

相关内容