这与-fcf-protection
有关.Ubuntu的GCC配置为--enable-cet
,默认情况下启用-fcf-protection
检测.如果你用-fcf-protection=none
编译,你会看到做JMP [<got-entry>]; PUSH <idx>; JMP <pltstub>
的"正常"PLT条目.
对于-fcf-protection
(也包括=branch
或=full
),添加了一个额外的部分,称为.plt.sec
,实际的函数调用存根位于那里.每个存根以ENDBR64
(见What does the endbr64 instruction actually do?)开始,将其标记为有效的分支目标,所有JMP
条指令都变成BND JMP
(见Meaning of BND RET in x86).推送重定位索引的PUSH <idx>
个指令都在.plt
中,现在它保存了一个序列ENDBR64; PUSH <idx>; BND JUMP <pltstub>
(如下面所示).
在"正常"情况下,每个GOT条目最初填充有相应PLT条目的下一个指令的地址.
在.plt.sec
的情况下,GOT条目初始填充为.plt + <offset>
,其中<offset>
指向.plt
中的相应序列ENDBR64; PUSH <idx>; BND JMP <pltstub>
.
至于为什么会这样设计,我不清楚.我找到了this perf
patch,这似乎给了一些关于.plt.sec
的见解.
以下是PLT -fcf-protection=none
的外观,这是您所期望的:
Disassembly of section .plt:
0000000000001020 <puts@plt-0x10>:
1020: ff 35 e2 2f 00 00 push 0x2fe2(%rip) # 4008 <_GLOBAL_OFFSET_TABLE_+0x8>
1026: ff 25 e4 2f 00 00 jmp *0x2fe4(%rip) # 4010 <_GLOBAL_OFFSET_TABLE_+0x10>
102c: 0f 1f 40 00 nopl 0x0(%rax)
0000000000001030 <puts@plt>:
1030: ff 25 e2 2f 00 00 jmp *0x2fe2(%rip) # 4018 <puts@GLIBC_2.2.5>
1036: 68 00 00 00 00 push $0x0
103b: e9 e0 ff ff ff jmp 1020 <_init+0x20>
下面是-fcf-protection
的样子:
Disassembly of section .plt:
0000000000001020 <.plt>:
1020: ff 35 e2 2f 00 00 push 0x2fe2(%rip) # 4008 <_GLOBAL_OFFSET_TABLE_+0x8>
1026: f2 ff 25 e3 2f 00 00 bnd jmp *0x2fe3(%rip) # 4010 <_GLOBAL_OFFSET_TABLE_+0x10>
102d: 0f 1f 00 nopl (%rax)
1030: f3 0f 1e fa endbr64
1034: 68 00 00 00 00 push $0x0
1039: f2 e9 e1 ff ff ff bnd jmp 1020 <_init+0x20>
103f: 90 nop
1040: f3 0f 1e fa endbr64
1044: 68 01 00 00 00 push $0x1
1049: f2 e9 d1 ff ff ff bnd jmp 1020 <_init+0x20>
104f: 90 nop
1050: f3 0f 1e fa endbr64
1054: 68 02 00 00 00 push $0x2
1059: f2 e9 c1 ff ff ff bnd jmp 1020 <_init+0x20>
105f: 90 nop
Disassembly of section .plt.got:
0000000000001060 <__cxa_finalize@plt>:
1060: f3 0f 1e fa endbr64
1064: f2 ff 25 8d 2f 00 00 bnd jmp *0x2f8d(%rip) # 3ff8 <__cxa_finalize@GLIBC_2.2.5>
106b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
Disassembly of section .plt.sec:
0000000000001070 <puts@plt>:
1070: f3 0f 1e fa endbr64
1074: f2 ff 25 9d 2f 00 00 bnd jmp *0x2f9d(%rip) # 4018 <puts@GLIBC_2.2.5>
107b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)