add support for .plt.sec in ELF binaries
Is your feature request related to a problem? Please describe.
When analyzing binaries generated on Fedora 29, compiled with
-fcf-protection (Intel CET + MPX), it becomes much more confusing
looking at calls to imported functions.
Describe the solution you'd like
Calls to .plt.sec entries should be identified as the ones to the usual .plt.
0x00004e98 31c0 xor eax, eax
0x00004e9a e8a1e60000 call 0x13540
0x00004e9f 488d351e4a01. lea rsi, [0x000198c4]
0x00004ea6 bf06000000 mov edi, 6
0x00004eab e8b0fdffff call sym.imp.setlocale
0x00004eb0 488d35584b01. lea rsi, str.usr_share_locale ; 0x19a0f ; "/usr/share/locale"
0x00004eb7 488d3d374b01. lea rdi, [0x000199f5] ; "coreutils"
0x00004ebe e81dfaffff call sym.imp.bindtextdomain
Describe alternatives you've considered
None
Additional context
0x00004e98 31c0 xor eax, eax
0x00004e9a e8a1e60000 call 0x13540
0x00004e9f 488d351e4a01. lea rsi, [0x000198c4]
0x00004ea6 bf06000000 mov edi, 6
0x00004eab e8b0fdffff call 0x4c60
0x00004eb0 488d35584b01. lea rsi, str.usr_share_locale ; 0x19a0f ; "/usr/share/locale"
0x00004eb7 488d3d374b01. lea rdi, [0x000199f5] ; "coreutils"
0x00004ebe e81dfaffff call 0x48e0
This is a snippet of the main
function of /bin/ls on Fedora 29. The calls at 0x00004eab
and 0x00004ebe
are, respectively, calls to setlocale
and bindtextdomain
.
Binaries compiled with Intel CET/MPX support generates two .plt sections (.plt and .plt.sec).
.plt.sec entries are like:
0x00004c60 f30f1efa endbr64
0x00004c64 f2ff252de201. bnd jmp qword reloc.setlocale ; [0x22e98:8]=0x4560 ; "`E"
0x00004c6b 0f1f440000 nop dword [rax + rax]
.plt entries are like:
0x00004040 f30f1efa endbr64
0x00004044 6801000000 push 1
0x00004049 f2e9d1ffffff bnd jmp 0x4020 ;[1]
The binary calls the entry in .plt.sec. When the binary starts (unless it uses BIND_NOW) reloc.XXXXX points to the related entry in .plt, which calls the dynamic linker that resolve the symbol and put the resolved address in reloc.XXXXX. Next times the .plt.sec entry is called, it goes directly to the imported function.
Note that it's enough to compile with MPX support to get .plt and .plt.sec
Reproducer
#include <stdio.h>
int main(int argc, char **argv) {
printf("Good morning %s!\n", argv[0]);
printf("Good night %s!\n", argv[0]);
return 0;
}
Compile with: gcc -O2 -ggdb -z bndplt test.c -o test-nocet-bndplt
其他:
- MIPS: Drop .dynsym symbol ordering requirement and nullify DT_MIPS_XHASH
- Hexagon: 希望实现TLSDESC
- x86: Intel Control-flow Enhancement Technology (D59780)。对Intel坚持弄.plt.sec有点失望。 他们的说辞仅仅是早年弄MPX(已经被Linux移除,正在被Linux移除)也设计了这样的方案,并且在没有基准测试的情况下说这样或许对cache locality更友好。 对ppc了解更深后发现.plt.sec倒是和ppc32/ppc64 .glink有相似之处。ppc引入.glink是缺乏ADDPCIS时的无奈之举。x86这样设计则算明显缺陷,亦不利于未来增加新的PLT格式, 爲了避免未来再发生这种binutils行爲挟持LLVM/Clang/lld实现的例子,只能多关注binutils的变化了。另外值得一提,AArch64 8.3a 8.5a也有相似的特性Pointer Authentication、Branch Target Identification。 Linker选项的语义AArch64比x86有优雅。我试图在D59780挽救。