Linux

如何獲取有關不會執行的二進製文件的資訊?

  • September 11, 2020

當我執行名為“myfile”的使用者應用程序之一時。

$ ./myfile

我收到以下輸出

bash: ./myfile: cannot execute binary file

我的使用者希望二進製文件能夠執行。我認為這是一個編譯錯誤,但無法確認。我執行了文件命令

$ file myfile
myfile: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

我的 RHEL6 作業系統是 64 位的

$ uname -p -o
x86_64 GNU/Linux

所以在我看來,它是為正確的架構而設計的。我不明白文件命令輸出中的“可重定位”是什麼意思,也無法從手冊頁中得到解釋。

為了更好地衡量,我檢查了共享庫依賴項

$ ldd myfile 
not a dynamic executable

有什麼方法可以讓這個文件執行,或者給我的使用者一些關於它為什麼不能執行的建設性資訊(比如他需要使用 x 重新編譯)?

追踪

$ strace ./myfile
execve("./myfile", ["./myfile"], [/* 22 vars */]) = -1 ENOEXEC (Exec format error)
dup(2)                                  = 3
fcntl(3, F_GETFL)                       = 0x8002 (flags O_RDWR|O_LARGEFILE)
fstat(3, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7a9fc93000
lseek(3, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
write(3, "strace: exec: Exec format error\n", 32strace: exec: Exec format error
) = 32
close(3)                                = 0
munmap(0x7f7a9fc93000, 4096)            = 0
exit_group(1)                           = ?

自述輸出

readelf -S ./myfile    There are 13 section headers, starting at offset 0x1e8:

Section Headers:
 [Nr] Name              Type             Address           Offset
      Size              EntSize          Flags  Link  Info  Align
 [ 0]                   NULL             0000000000000000  00000000
      0000000000000000  0000000000000000           0     0     0
 [ 1] .text             PROGBITS         0000000000000000  00000040
      0000000000000098  0000000000000000  AX       0     0     4
 [ 2] .rela.text        RELA             0000000000000000  000006e0
      0000000000000120  0000000000000018          11     1     8
 [ 3] .data             PROGBITS         0000000000000000  000000d8
      0000000000000010  0000000000000000  WA       0     0     4
 [ 4] .bss              NOBITS           0000000000000000  000000e8
      0000000000000000  0000000000000000  WA       0     0     4
 [ 5] .rodata           PROGBITS         0000000000000000  000000e8
      0000000000000033  0000000000000000   A       0     0     1
 [ 6] .comment          PROGBITS         0000000000000000  0000011b
      000000000000002d  0000000000000001  MS       0     0     1
 [ 7] .note.GNU-stack   PROGBITS         0000000000000000  00000148
      0000000000000000  0000000000000000           0     0     1
 [ 8] .eh_frame         PROGBITS         0000000000000000  00000148
      0000000000000038  0000000000000000   A       0     0     8
 [ 9] .rela.eh_frame    RELA             0000000000000000  00000800
      0000000000000018  0000000000000018          11     8     8
 [10] .shstrtab         STRTAB           0000000000000000  00000180
      0000000000000061  0000000000000000           0     0     1
 [11] .symtab           SYMTAB           0000000000000000  00000528
      0000000000000180  0000000000000018          12     9     8
 [12] .strtab           STRTAB           0000000000000000  000006a8
      0000000000000037  0000000000000000           0     0     1
Key to Flags:
 W (write), A (alloc), X (execute), M (merge), S (strings)
 I (info), L (link order), G (group), x (unknown)
 O (extra OS processing required) o (OS specific), p (processor specific)

聽起來可重定位與不是執行檔的目標文件有關。

執行檔應如下所示

ELF 64 位 LSB 執行檔,x86-64,版本 1 (SYSV),動態連結,解釋器 /lib64/ld-linux-x86-64.so.2,適用於 GNU/Linux 2.6.32,BuildID[sha1]=a8ff57737fe60fba639d91d603253f4cdc6eb9f7 , 剝離

目標文件看起來像這樣

# 文件 /usr/lib/x86_64-linux-gnu/crtn.o
/usr/lib/x86_64-linux-gnu/crtn.o:ELF 64 位 LSB 可重定位,x86-64,版本 1 (SYSV),未剝離

如果需要,您還可以通過這種方式獲取更多資訊

# objdump -x myfile

或者拆機

# objdump -d myfile

列出目標文件中的符號(未剝離)

#nm /usr/lib/x86_64-linux-gnu/gcrt1.o
退出
0000000000000000 b 呼叫.4237
0000000000000000 D __data_start
0000000000000000 W data_start
文本
0000000000000030 T __gmon_start__
0000000000000000 R _IO_stdin_used
U __libc_csu_fini
U __libc_csu_init
U __libc_start_main
主
在 _mcleanup
在 __monstartup
0000000000000000 T _start

試圖從執行檔(剝離)中列出符號

#nm /bin/bash
nm: /bin/bash: 沒有符號

引用自:https://serverfault.com/questions/730922