TransWikia.com

Is an ELF SHT_RELA section with a 0 `sh_link` valid?

Reverse Engineering Asked by John Källén on May 1, 2021

I have an 64-bit s390x ELF binary with a RELA section named ".rela.plt" whose sh_link field is 0. I was under the impression that the sh_link is a required value, providing the id of the section where the symbols used by the relocations are stored.

If I run objdump on the binary no information about any relocations is emitted, hinting that perhaps there are no relocations to be done. The following is repored by readelf:

There are 36 section headers, starting at offset 0xa91c8:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .note.ABI-tag     NOTE             0000000080000190  00000190
       0000000000000020  0000000000000000   A       0     0     4
  [ 2] .note.gnu.build-i NOTE             00000000800001b0  000001b0
       0000000000000024  0000000000000000   A       0     0     4
  [ 3] .rela.plt         RELA             00000000800001d8  000001d8
       0000000000000018  0000000000000018  AI       0    23     8
  [ 4] .init             PROGBITS         00000000800001f0  000001f0
       000000000000004c  0000000000000000  AX       0     0     4
  [ 5] .plt              PROGBITS         000000008000023c  0000023c
       0000000000000020  0000000000000000  AX       0     0     4
  [ 6] .text             PROGBITS         0000000080000260  00000260
       000000000006c328  0000000000000000  AX       0     0     16
  [ 7] __libc_freeres_fn PROGBITS         000000008006c588  0006c588
       0000000000000f18  0000000000000000  AX       0     0     8
  [ 8] __libc_thread_fre PROGBITS         000000008006d4a0  0006d4a0
       00000000000000f0  0000000000000000  AX       0     0     8
  [ 9] .fini             PROGBITS         000000008006d590  0006d590
       0000000000000034  0000000000000000  AX       0     0     4
  [10] .rodata           PROGBITS         000000008006d5c8  0006d5c8
       000000000001d810  0000000000000000   A       0     0     8
  [11] __libc_subfreeres PROGBITS         000000008008add8  0008add8
       0000000000000058  0000000000000000   A       0     0     8
  [12] __libc_atexit     PROGBITS         000000008008ae30  0008ae30
       0000000000000008  0000000000000000   A       0     0     8
  [13] __libc_thread_sub PROGBITS         000000008008ae38  0008ae38
       0000000000000008  0000000000000000   A       0     0     8
  [14] .eh_frame         PROGBITS         000000008008ae40  0008ae40
       000000000000aa2c  0000000000000000   A       0     0     8
  [15] .gcc_except_table PROGBITS         000000008009586c  0009586c
       00000000000000c5  0000000000000000   A       0     0     1
  [16] .tdata            PROGBITS         0000000080096ed0  00095ed0
       0000000000000020  0000000000000000 WAT       0     0     8
  [17] .tbss             NOBITS           0000000080096ef0  00095ef0
       0000000000000034  0000000000000000 WAT       0     0     8
  [18] .fini_array       FINI_ARRAY       0000000080096ef0  00095ef0
       0000000000000008  0000000000000000  WA       0     0     8
  [19] .ctors            PROGBITS         0000000080096ef8  00095ef8
       0000000000000010  0000000000000000  WA       0     0     8
  [20] .dtors            PROGBITS         0000000080096f08  00095f08
       0000000000000010  0000000000000000  WA       0     0     8
  [21] .jcr              PROGBITS         0000000080096f18  00095f18
       0000000000000008  0000000000000000  WA       0     0     8
  [22] .data.rel.ro      PROGBITS         0000000080096f20  00095f20
       00000000000000e0  0000000000000000  WA       0     0     8
  [23] .got              PROGBITS         0000000080097000  00096000
       00000000000000c8  0000000000000008  WA       0     0     8
  [24] .data             PROGBITS         00000000800970c8  000960c8
       00000000000019c8  0000000000000000  WA       0     0     8
  [25] .bss              NOBITS           0000000080098a90  00097a90
       0000000000002070  0000000000000000  WA       0     0     8
  [26] __libc_freeres_pt NOBITS           000000008009ab00  00097a90
       0000000000000030  0000000000000000  WA       0     0     8
  [27] .comment          PROGBITS         0000000000000000  00097a90
       0000000000000034  0000000000000001  MS       0     0     1
  [28] .debug_aranges    PROGBITS         0000000000000000  00097ac4
       0000000000000030  0000000000000000           0     0     1
  [29] .debug_info       PROGBITS         0000000000000000  00097af4
       00000000000000ed  0000000000000000           0     0     1
  [30] .debug_abbrev     PROGBITS         0000000000000000  00097be1
       000000000000007f  0000000000000000           0     0     1
  [31] .debug_line       PROGBITS         0000000000000000  00097c60
       000000000000004c  0000000000000000           0     0     1
  [32] .debug_str        PROGBITS         0000000000000000  00097cac
       00000000000000d3  0000000000000001  MS       0     0     1
  [33] .shstrtab         STRTAB           0000000000000000  000a903e
       0000000000000186  0000000000000000           0     0     1
  [34] .symtab           SYMTAB           0000000000000000  00097d80
       000000000000ae00  0000000000000018          35   759     8
  [35] .strtab           STRTAB           0000000000000000  000a2b80
       00000000000064be  0000000000000000           0     0     1
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),
  p (processor specific)

In addition, on stderr I see:

readelf: Warning: [ 3]: Link field (0) should index a symtab section.

Should I be interpreting the zero sh_link for the ".rela.plt" section as a hint that there is no work to be done?

One Answer

On the surface it seems indeed that this file does not conform to the ELF specification.

I will need to look at the file but I expect it does have relocations and you should not skip them. It seems the flags have SHF_INFO_LINK set which means the index should be looked up in the sh_info field and 23 points to the .got section which means relocations apply to it.

One possibility is that relocations do not use symbols (e.g. only IRELATIVE type relocations) and another is that it uses the only SYMTAB present in the file (index 34).

EDIT: it seems my theory was correct. Output of readelf -r:

Relocation section '.rela.plt' at offset 0x1d8 contains 1 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000080097018  00000000003d R_390_IRELATIVE                      800174b0

The *_IRELATIVE relocations do not refer to a symbol and thus do not need a symbol table.

Answered by Igor Skochinsky on May 1, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP