Как заставить GDB распознать мой выполняемый вручную файл ELF как исполняемый?

#linux #gdb #elf

#linux #gdb #elf

Вопрос:

У меня есть следующий файл ELF AMD64 в 64-разрядном (Arch) linux (не отформатирован, чтобы упростить копирование и вставку)

 7F 45 4C 46 02 01 01 00 00 00 00 00 00 00 00 00 02 00 3E 00 01 00 00 00 78 00 40 00 00 00 00 00 40 00 00 00 00 00 00 00 84 00 00 00 00 00 00 00 00 00 00 00 40 00 38 00 01 00 40 00 03 00 02 00 01 00 00 00 05 00 00 00 78 00 00 00 00 00 00 00 78 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 00 00 00 00 00 00 0C 00 00 00 00 00 00 00 00 00 20 00 00 00 00 00 48 B8 3C 00 00 00 00 00 00 00 0F 05 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 06 00 00 00 00 00 00 00 78 00 40 00 00 00 00 00 78 00 00 00 00 00 00 00 0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 0C 00 00 00 00 00 00 00 07 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 44 01 00 00 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 00 2E 74 65 78 74 00 2E 73 68 73 74 72 74 61 62 00
 

который ничего не делает, кроме немедленного выхода.

Вывод readelf -a

 ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x400078
  Start of program headers:          64 (bytes into file)
  Start of section headers:          132 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         1
  Size of section headers:           64 (bytes)
  Number of section headers:         3
  Section header string table index: 2

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         0000000000400078  00000078
       000000000000000c  000000000000000c  AX       0     0     8
  [ 2] .shstrtab         STRTAB           0000000000000000  00000144
       0000000000000010  0000000000000010           0     0     0
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  l (large), p (processor specific)

There are no section groups in this file.

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000000078 0x0000000000400078 0x0000000000000000
                 0x000000000000000c 0x000000000000000c  R E    0x200000

 Section to Segment mapping:
  Segment Sections...
   00     .text 

There is no dynamic section in this file.

There are no relocations in this file.

The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.

No version information found in this file.
 

Хотя исполняемый файл работает отлично, при выполнении я gdb <file> получаю сообщение "0x7ffd7e078db0s": not in executable format: file format not recognized

Странно то, что когда я удаляю все разделы (так что ELF остается только с заголовком файла, заголовком программы и кодом), GDB распознает его как исполняемый файл.

Таким образом, мой вопрос в том, как я могу позволить GDB распознать мой файл как исполняемый? В качестве альтернативы, какую информацию использует GDB, чтобы определить, что файл является исполняемым?

Спасибо за ваше время и усилия.

Ответ №1:

Ваш .shstrtab раздел имеет длину 0x10 , но должен иметь длину 0x11 :

  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F      <-- byte offset
  .  t  e  x  t   .  s  h  s  t  r  t  a  b    <-- value
 

Изменение 293 байта rd с 0x10 на 0x11 приводит к запуску программы под GDB.

PS eu-readelf более надежен, чем readelf , и делает ошибку более понятной. Использование оригинального (сломанного) двоичного файла:

 $ readelf -WS junk.elf
There are 3 section headers, starting at offset 0x84:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        0000000000400078 000078 00000c 0c  AX  0   0  8
  [ 2] .shstrtab         STRTAB          0000000000000000 000144 000010 10      0   0  0
 

Сравните с eu-readelf :

 $ eu-readelf -WS junk.elf
There are 3 section headers, starting at offset 0x84:

Section Headers:
[Nr] Name                 Type         Addr             Off      Size     ES Flags Lk Inf Al
[ 0]                      NULL         0000000000000000 00000000 00000000  0        0   0  0
[ 1] .text                PROGBITS     0000000000400078 00000078 0000000c 12 AX     0   0  8
[ 2] <corrupt>            STRTAB       0000000000000000 00000144 00000010 16        0   0  0