ldd 為 64 位 ELF 返回“不是動態執行檔”,即使 objdump 和 readelf 不一致
(這個問題是我之前已經解決的問題的間接延續。)
我正在嘗試做的事情的小總結
我有一個以
pin_sim.so
建築模擬器 snipersim ( http://www.snipersim.org ) 命名的 .so 文件。該庫基本上實現了模擬所使用的英特爾 PIN 儀器庫的包裝器。該文件在主應用程序開始模擬之前動態載入。由於仿真目標執行檔必須載入與 相同的庫版本
pin_sim.so
,並pin_sim.so
打包一些版本的庫,在仿真開始之前,它會檢查 pin_sim.so 使用 載入的庫版本ldd
。問題
在我的家庭桌面(執行 Linux Mint 17.2)上,這可以正常工作。
ldd pin_sim.so
返回:linux-vdso.so.1 => (0x00007ffcd75a3000) libpython2.7.so.1.0 => /usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0 (0x00007fdd19d08000) librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fdd19b00000) libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fdd198e6000) libsqlite3.so.0 => /usr/lib/x86_64-linux-gnu/libsqlite3.so.0 (0x00007fdd1962d000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fdd19429000) libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fdd19124000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fdd18e1e000) libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fdd18c08000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fdd18842000) /lib64/ld-linux-x86-64.so.2 (0x00007fdd1ae55000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fdd18624000) libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007fdd18421000)
但是,在我有權訪問的執行 OpenSUSE 13.1 的計算集群上,此命令會返回(無論我是複製文件還是重新編譯它):
not a dynamic executable
此外,我無法正確執行狙擊手(模擬永遠不會執行,我認為這與 pin_sim.so 未正確載入有關)。
如果我在集群中編譯文件,然後復製到我家的機器上,ldd 像以前一樣正常工作。我在 ldd 上嘗試過的所有其他文件(甚至是主狙擊二進製文件)都可以正常工作,只有 pin_sim.so 失敗。
更多資訊
file pin_sim.so
在我的家用機器上(集群上相同,如果沒有重新編譯):pin_sim.so: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=4ac6397fefb655c475b5a941cef726183d3e3710, not stripped
file pin_sim.so
在集群上(重新編譯):pin_sim.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, not stripped
objdump -p pin_sim.so | grep NEEDED
在兩台機器上(即使在集群上重新編譯):NEEDED libpython2.7.so.1.0 NEEDED librt.so.1 NEEDED libz.so.1 NEEDED libsqlite3.so.0 NEEDED libdl.so.2 NEEDED libstdc++.so.6 NEEDED libm.so.6 NEEDED libgcc_s.so.1 NEEDED libc.so.6 NEEDED ld-linux-x86-64.so.2
readelf -d pin_sim.so | grep NEEDED
在兩台機器上(即使在集群上重新編譯):0x0000000000000001 (NEEDED) Shared library: [libpython2.7.so.1.0] 0x0000000000000001 (NEEDED) Shared library: [librt.so.1] 0x0000000000000001 (NEEDED) Shared library: [libz.so.1] 0x0000000000000001 (NEEDED) Shared library: [libsqlite3.so.0] 0x0000000000000001 (NEEDED) Shared library: [libdl.so.2] 0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6] 0x0000000000000001 (NEEDED) Shared library: [libm.so.6] 0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1] 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] 0x0000000000000001 (NEEDED) Shared library: [ld-linux-x86-64.so.2]
ldd --version
在我的家用機器上:ldd (Ubuntu EGLIBC 2.19-0ubuntu6.6) 2.19
ldd --version
在集群上:ldd (Gentoo 2.20-r2 p4) 2.20
我嘗試過的/我的想法
我對linux動態連結過程不是很熟悉,所以沒怎麼嘗試。
我環顧網路,我只能找到在非常舊的二進製文件(在將 ldd 支持添加到 ELF 格式之前編譯)或在沒有 64 位系統的 32 位二進製文件上執行 ldd已安裝 32 位系統庫。由於這個二進製文件是由我編譯的,並且是 64 位的,我不知道為什麼 ldd 可能會失敗。
我正在考慮將狙擊手中的版本檢查器從使用 ldd 切換到使用 readelf/objdump ,但我仍然對 ldd 像這樣失敗感到驚訝。
有任何想法嗎?我在集群中沒有 root 訪問權限。
編輯 1:Strace
我在集群機器上做了兩個系統呼叫跟踪。一個在 sniper 二進製文件上(其中 ldd 成功),一個在 pin_sim.so 二進製文件上(其中 ldd 失敗)。
我切斷了開頭,直到他們開始分歧的有趣部分。
編輯 2:現在 strace -f
strace -f ldd sniper
:faccessat(AT_FDCWD, "./sniper", R_OK) = 0 faccessat(AT_FDCWD, "./sniper", X_OK) = 0 faccessat(AT_FDCWD, "/lib/ld-linux.so.2", X_OK) = -1 ENOENT (No such file or directory) faccessat(AT_FDCWD, "/lib64/ld-linux-x86-64.so.2", X_OK) = 0 pipe([3, 4]) = 0 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 rt_sigprocmask(SIG_BLOCK, [INT CHLD], [], 8) = 0 lseek(255, -52, SEEK_CUR) = 5706 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x359287389d0) = 21112 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 rt_sigaction(SIGCHLD, {0x6f679b3710, [], SA_RESTORER|SA_RESTART, 0x35927cffc20}, {0x6f679b3710, [], SA_RESTORER|SA_RESTART, 0x35927cffc20}, 8) = 0 close(4) = 0 read(3, Process 21112 attached <unfinished ...> [pid 21112] close(255) = 0 [pid 21112] rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 [pid 21112] rt_sigaction(SIGTSTP, {SIG_DFL, [], SA_RESTORER, 0x35927cffc20}, {SIG_DFL, [], 0}, 8) = 0 [pid 21112] rt_sigaction(SIGTTIN, {SIG_DFL, [], SA_RESTORER, 0x35927cffc20}, {SIG_DFL, [], 0}, 8) = 0 [pid 21112] rt_sigaction(SIGTTOU, {SIG_DFL, [], SA_RESTORER, 0x35927cffc20}, {SIG_DFL, [], 0}, 8) = 0 [pid 21112] rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x35927cffc20}, {SIG_DFL, [], SA_RESTORER, 0x35927cffc20}, 8) = 0 [pid 21112] rt_sigaction(SIGQUIT, {SIG_DFL, [], SA_RESTORER, 0x35927cffc20}, {SIG_IGN, [], SA_RESTORER, 0x35927cffc20}, 8) = 0 [pid 21112] rt_sigaction(SIGCHLD, {SIG_DFL, [], SA_RESTORER|SA_RESTART, 0x35927cffc20}, {0x6f679b3710, [], SA_RESTORER|SA_RESTART, 0x35927cffc20}, 8) = 0 [pid 21112] rt_sigaction(SIGCHLD, {0x6f679b3710, [], SA_RESTORER|SA_RESTART, 0x35927cffc20}, {SIG_DFL, [], SA_RESTORER|SA_RESTART, 0x35927cffc20}, 8) = 0 [pid 21112] rt_sigaction(SIGINT, {0x6f679ce1a0, [], SA_RESTORER, 0x35927cffc20}, {SIG_DFL, [], SA_RESTORER, 0x35927cffc20}, 8) = 0 [pid 21112] dup2(4, 1) = 1 [pid 21112] close(4) = 0 [pid 21112] close(3) = 0 [pid 21112] rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0 [pid 21112] rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x35927cffc20}, {0x6f679ce1a0, [], SA_RESTORER, 0x35927cffc20}, 8) = 0 [pid 21112] rt_sigaction(SIGQUIT, {SIG_DFL, [], SA_RESTORER, 0x35927cffc20}, {SIG_DFL, [], SA_RESTORER, 0x35927cffc20}, 8) = 0 [pid 21112] rt_sigaction(SIGCHLD, {SIG_DFL, [], SA_RESTORER|SA_RESTART, 0x35927cffc20}, {0x6f679b3710, [], SA_RESTORER|SA_RESTART, 0x35927cffc20}, 8) = 0 [pid 21112] execve("/lib64/ld-linux-x86-64.so.2", ["/lib64/ld-linux-x86-64.so.2", "--verify", "./sniper"], [/* 51 vars */]) = 0 [pid 21112] brk(0) = 0x2d9db43c910 [pid 21112] open("./sniper", O_RDONLY|O_CLOEXEC) = 3 [pid 21112] read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\2\0>\0\1\0\0\0\321\307@\0\0\0\0\0"..., 832) = 832 [pid 21112] fstat(3, {st_mode=S_IFREG|0775, st_size=46853390, ...}) = 0 [pid 21112] getcwd("/path/to/sniper/lib", 128) = 52 [pid 21112] mmap(0x400000, 3837952, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0) = 0x400000 [pid 21112] mmap(0x9a8000, 626688, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3a8000) = 0x9a8000 [pid 21112] mmap(0xa41000, 32872, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xa41000 [pid 21112] close(3) = 0 [pid 21112] exit_group(0) = ? [pid 21111] <... read resumed> "", 128) = 0 [pid 21112] +++ exited with 0 +++ --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=21112, si_uid=169971, si_status=0, si_utime=0, si_stime=0} --- wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WNOHANG, NULL) = 21112 wait4(-1, 0x3e3bd435d80, WNOHANG, NULL) = -1 ECHILD (No child processes) rt_sigreturn() = 0 close(3) = 0 *** TRACE CONTINUES, no longer important because the other one has already errored out by this point ***
strace ldd -f pin_sim.so
:faccessat(AT_FDCWD, "./pin_sim.so", R_OK) = 0 faccessat(AT_FDCWD, "./pin_sim.so", X_OK) = 0 faccessat(AT_FDCWD, "/lib/ld-linux.so.2", X_OK) = -1 ENOENT (No such file or directory) faccessat(AT_FDCWD, "/lib64/ld-linux-x86-64.so.2", X_OK) = 0 pipe([3, 4]) = 0 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 rt_sigprocmask(SIG_BLOCK, [INT CHLD], [], 8) = 0 lseek(255, -52, SEEK_CUR) = 5706 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x36aaed959d0) = 21099 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 rt_sigaction(SIGCHLD, {0x798dd3a710, [], SA_RESTORER|SA_RESTART, 0x36aae35cc20}, {0x798dd3a710, [], SA_RESTORER|SA_RESTART, 0x36aae35cc20}, 8) = 0 close(4) = 0 read(3, Process 21099 attached <unfinished ...> [pid 21099] close(255) = 0 [pid 21099] rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 [pid 21099] rt_sigaction(SIGTSTP, {SIG_DFL, [], SA_RESTORER, 0x36aae35cc20}, {SIG_DFL, [], 0}, 8) = 0 [pid 21099] rt_sigaction(SIGTTIN, {SIG_DFL, [], SA_RESTORER, 0x36aae35cc20}, {SIG_DFL, [], 0}, 8) = 0 [pid 21099] rt_sigaction(SIGTTOU, {SIG_DFL, [], SA_RESTORER, 0x36aae35cc20}, {SIG_DFL, [], 0}, 8) = 0 [pid 21099] rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x36aae35cc20}, {SIG_DFL, [], SA_RESTORER, 0x36aae35cc20}, 8) = 0 [pid 21099] rt_sigaction(SIGQUIT, {SIG_DFL, [], SA_RESTORER, 0x36aae35cc20}, {SIG_IGN, [], SA_RESTORER, 0x36aae35cc20}, 8) = 0 [pid 21099] rt_sigaction(SIGCHLD, {SIG_DFL, [], SA_RESTORER|SA_RESTART, 0x36aae35cc20}, {0x798dd3a710, [], SA_RESTORER|SA_RESTART, 0x36aae35cc20}, 8) = 0 [pid 21099] rt_sigaction(SIGCHLD, {0x798dd3a710, [], SA_RESTORER|SA_RESTART, 0x36aae35cc20}, {SIG_DFL, [], SA_RESTORER|SA_RESTART, 0x36aae35cc20}, 8) = 0 [pid 21099] rt_sigaction(SIGINT, {0x798dd551a0, [], SA_RESTORER, 0x36aae35cc20}, {SIG_DFL, [], SA_RESTORER, 0x36aae35cc20}, 8) = 0 [pid 21099] dup2(4, 1) = 1 [pid 21099] close(4) = 0 [pid 21099] close(3) = 0 [pid 21099] rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0 [pid 21099] rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x36aae35cc20}, {0x798dd551a0, [], SA_RESTORER, 0x36aae35cc20}, 8) = 0 [pid 21099] rt_sigaction(SIGQUIT, {SIG_DFL, [], SA_RESTORER, 0x36aae35cc20}, {SIG_DFL, [], SA_RESTORER, 0x36aae35cc20}, 8) = 0 [pid 21099] rt_sigaction(SIGCHLD, {SIG_DFL, [], SA_RESTORER|SA_RESTART, 0x36aae35cc20}, {0x798dd3a710, [], SA_RESTORER|SA_RESTART, 0x36aae35cc20}, 8) = 0 [pid 21099] execve("/lib64/ld-linux-x86-64.so.2", ["/lib64/ld-linux-x86-64.so.2", "--verify", "./pin_sim.so"], [/* 51 vars */]) = 0 [pid 21099] brk(0) = 0x2b0b251b090 [pid 21099] open("./pin_sim.so", O_RDONLY|O_CLOEXEC) = 3 [pid 21099] read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\240@\24\0\0\0\0\0"..., 832) = 832 [pid 21099] fstat(3, {st_mode=S_IFREG|0775, st_size=55707995, ...}) = 0 [pid 21099] getcwd("/path/to/sniper/lib", 128) = 52 [pid 21099] mmap(NULL, 12474024, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x2b0af187000 [pid 21099] mprotect(0x2b0afa9b000, 2093056, PROT_NONE) = 0 [pid 21099] mmap(0x2b0afc9a000, 716800, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x913000) = 0x2b0afc9a000 [pid 21099] mmap(0x2b0afd49000, 145064, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x2b0afd49000 [pid 21099] mprotect(0x3a0fbff6000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC|PROT_GROWSDOWN) = -1 EACCES (Permission denied) [pid 21099] close(3) = 0 [pid 21099] exit_group(1) = ? [pid 21099] +++ exited with 1 +++ <... read resumed> "", 128) = 0 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=21099, si_uid=169971, si_status=1, si_utime=0, si_stime=1} --- wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 1}], WNOHANG, NULL) = 21099 wait4(-1, 0x3de445c7ac0, WNOHANG, NULL) = -1 ECHILD (No child processes) rt_sigreturn() = 0 close(3) = 0 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0 rt_sigaction(SIGINT, {0x798dd36e90, [], SA_RESTORER, 0x36aae35cc20}, {SIG_DFL, [], SA_RESTORER, 0x36aae35cc20}, 8) = 0 rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x36aae35cc20}, {0x798dd36e90, [], SA_RESTORER, 0x36aae35cc20}, 8) = 0 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 faccessat(AT_FDCWD, "/libx32/ld-linux-x32.so.2", X_OK) = -1 ENOENT (No such file or directory) fstat(1, {st_mode=S_IFCHR|0622, st_rdev=makedev(136, 0), ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x36aaed99000 write(1, "\tnot a dynamic executable\n", 26 not a dynamic executable ) = 26 read(255, "\nexit $result\n# Local Variables:"..., 5758) = 52 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 exit_group(1) = ? +++ exited with 1 +++
編輯 3
readelf -Wl pin_sim.so
:Elf file type is DYN (Shared object file) Entry point 0x1440a0 There are 7 program headers, starting at offset 64 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x913415 0x913415 R E 0x200000 LOAD 0x913990 0x0000000000b13990 0x0000000000b13990 0x0ae648 0x0d1d18 RW 0x200000 DYNAMIC 0x9bf0f8 0x0000000000bbf0f8 0x0000000000bbf0f8 0x0002a0 0x0002a0 RW 0x8 GNU_EH_FRAME 0x7fbee0 0x00000000007fbee0 0x00000000007fbee0 0x036cfc 0x036cfc R 0x4 GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RWE 0x10 GNU_RELRO 0x913990 0x0000000000b13990 0x0000000000b13990 0x0ac670 0x0ac670 R 0x1 PAX_FLAGS 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 0x8 Section to Segment mapping: Segment Sections... 00 .hash .dynsym .dynstr .gnu.version .gnu.version_d .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .charmversion .eh_frame_hdr .eh_frame .gcc_except_table 01 .init_array .fini_array .jcr .data.rel.ro .dynamic .got .data .pinclientint .bss 02 .dynamic 03 .eh_frame_hdr 04 05 .init_array .fini_array .jcr .data.rel.ro .dynamic .got 06
在第二個 strace 部分,講述 x32 二進製文件很奇怪,但不太可能:
faccessat(AT_FDCWD, "/libx32/ld-linux-x32.so.2", X_OK) = -1 ENOENT (No such file or directory)
也許集群的 /lib64/ld-linux-x86-64.so.2 不喜歡你的 pin_sim.so 不知何故。
要進一步解決問題,請嘗試
/lib64/ld-linux-x86-64.so.2 --list /path/to/your/pin_sim.so
在您的集群上執行。下次,不要忘記添加
-f
到您的 strace 參數中,它會打開完整的程序樹跟踪。
我在 WSL(Ubuntu 16.04)中遇到了同樣的問題,正如評論中所述,原因是我的庫有 GNU_STACK RWE 標誌,但 Ubuntu WSL 不支持它。因此,如果您的庫實際上不需要它,解決方案是使用以下命令從庫中刪除 E 標誌:
sudo apt install execstack execstack -c yourlib.so