Linux

修復執行檔的硬編碼動態連結

  • June 10, 2018

我有一個名為reg的執行檔,它具有以下共享庫依賴項:

[terminal]$ ldd ./reg
linux-vdso.so.1 => (0x00007ffc40d90000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003be0c00000)
/usr/dep/packages/opt/intel/mkl/10.0.2.018/lib/em64t/libmkl_intel_lp64.so => not found

執行二進製文件時,我得到以下資訊:

[terminal]$ ./reg
./reg: error while loading shared libraries: /usr/dep/packages/opt/intel/mkl/10.0.2.018/lib/em64t/libmkl_intel_lp64.so: cannot open shared object file: No such file or directory.

問題是我沒有創建指定目錄路徑並將庫放在那裡的管理權限。此外,我沒有原始碼,所以我也無法重新編譯它,但我確實有libmkl_intel_lp64.so庫儲存在其他地方。我嘗試使用LD_PRELOAD環境變數,但它仍然需要該特定位置的庫。有沒有辦法解決這個問題?

謝謝!

我沒有與您相同的二進製文件,但我做了一些測試,似乎patchelf可以在這里工作。我有一個使用和作為依賴hello項編譯的二進製文件:-Wl,-rpath=/home/ja/c/hello-puts/make/lib``libtest.so

$ ldd hello
       linux-vdso.so.1 (0x00007ffedb4f0000)
       libtest.so => /home/ja/c/hello-puts/make/lib/libtest.so (0x00007f04a2437000)
       libc.so.6 => /lib64/libc.so.6 (0x00007f04a200f000)
       /lib64/ld-linux-x86-64.so.2 (0x0000564a42e36000)

patchelf使用https://github.com/dezgeg/patchelf/執行:--make-needed-absolute_patchelf

$ patchelf --make-needed-absolute hello
$ ldd hello
       linux-vdso.so.1 (0x00007fff9baa3000)
       /home/ja/c/hello-puts/make/lib/libtest.so (0x00007f81bd0e2000)
       libc.so.6 => /lib64/libc.so.6 (0x00007f81bccba000)
       /lib64/ld-linux-x86-64.so.2 (0x0000556714bb5000)

我認為這就是你所擁有的。我複製hello到其他機器並且:

$ ldd ./hello
       linux-vdso.so.1 =>  (0x00007fff92e7d000)
       /home/ja/c/hello-puts/make/lib/libtest.so => not found
       libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff381c9b000)
       /lib64/ld-linux-x86-64.so.2 (0x00007ff382065000)

我首先刪除了一個需要的libtest.so依賴項:

$ patchelf --remove-needed /home/ja/c/hello-puts/make/lib/libtest.so hello
$ ldd hello
       linux-vdso.so.1 =>  (0x00007ffdcedfb000)
       libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f60705c5000)
       /lib64/ld-linux-x86-64.so.2 (0x00007f607098f000)

我嘗試執行hello,它開始了,但由於解釋器完成了惰性綁定,只顯示了預期輸出的第一行:

$ ./hello
hello world
./hello: symbol lookup error: ./hello: undefined symbol: foo

libtest.so再次添加但沒有絕對路徑:

$ patchelf --add-needed libtest.so hello
$ ldd hello
       linux-vdso.so.1 =>  (0x00007ffda155c000)
       libtest.so => not found
       libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffbdb8c3000)
       /lib64/ld-linux-x86-64.so.2 (0x00007ffbdbc8d000)

我複製libtest.so$PWD並能夠開始hello

$ LD_LIBRARY_PATH=. ./hello
hello world
inside foo()

引用自:https://unix.stackexchange.com/questions/448789