假设我有一个/bin/cat
使用以下共享库的可执行文件:
linux-vdso.so.1
libc.so.6
/lib64/ld-linux-x86-64.so.2
Run Code Online (Sandbox Code Playgroud)
是否有可能以某种方式将这些东西“加入”在一起(可执行存档或类似的东西)?
我没有要执行此操作的程序的代码,因此我不能仅使用 -static 标志对其进行编译。
您可以将其所有库从其系统位置复制到可执行文件所在的子目录中,并使用patchelf使可执行文件在那里查找其 libdependencies 而不是系统 lib 目录。
例如:
相对化_libs:
#!/bin/bash -e
[ -n "$1" ] || set -- a.out
mkdir -p ./lib/ #<copy the libraries here
#use ldd to resolve the libs and use `patchelf --print-needed to filter out
# "magic" libs kernel-interfacing libs such as linux-vdso.so, ld-linux-x86-65.so or libpthread
# which you probably should not relativize anyway
join \
<(ldd "$1" |awk '{if(substr($3,0,1)=="/") print $1,$3}' |sort) \
<(patchelf --print-needed "$1" |sort) |cut -d\ -f2 |
#copy the lib selection to ./lib
xargs -d '\n' -I{} cp --copy-contents {} ./lib
#make the relative lib paths override the system lib path
patchelf --set-rpath "\$ORIGIN/lib" "$1"
Run Code Online (Sandbox Code Playgroud)
(我相信与LD_LIBRARY_PATH
黑客攻击不同,这也应该适用于 setuid 可执行文件)。
之后,您所要做的就是将该./lib
目录与可执行文件一起移动。
取决于您所说的“加入”是什么意思。最好的方法是将原始源重新编译为静态二进制文件。
但是,您可以将所有库包含在由应用程序控制的子目录中(/usr/share/myapp
例如),然后将该目录放入库搜索顺序中。一种方法是(在 Linux 中)使用LD_LIBRARY_PATH
:
LD_LIBRARY_PATH=/usr/share/myapp/lib:/usr/local/lib:/usr/lib/i686-linux-gnu:/lib/i686-linux-gnu
Run Code Online (Sandbox Code Playgroud)
在 Linux 中,你可以修改/etc/ld.so.conf
文件来做同样的事情——Ubuntu也会*.conf
在/etc/ld.so.conf.d
目录中添加文件。