对于函数何时出现在.plt部分中,我感到困惑。
我试图从代码内部打印printf
的地址(而不是objdump
),但我偶然发现了这个问题。我想在C和gdb中通过.plt和.got“跟随” printf
。
此实验的来源如下(虽然不是“不错”,但足以显示我要执行的操作):
int main(int argc, char *argv[]) {
printf("Warm up\n");
// int (*plt)(const char *format, ...) = printf;
int *plt = argv;
long got = *((int*)plt);
printf("plt 0x%016lx\n", plt);
printf("got 0x%016lx\n", got);
return 0;
}
objdump
在.plt中给出了预期的printf
:
$ objdump -d -j .plt ./a.out
./a.out: file format elf64-x86-64
Disassembly of section .plt:
0000000000000540 <.plt>:
540: ff 35 72 0a 20 00 pushq 0x200a72(%rip) # 200fb8 <_GLOBAL_OFFSET_TABLE_+0x8>
546: ff 25 74 0a 20 00 jmpq *0x200a74(%rip) # 200fc0 <_GLOBAL_OFFSET_TABLE_+0x10>
54c: 0f 1f 40 00 nopl 0x0(%rax)
0000000000000550 <puts@plt>:
550: ff 25 72 0a 20 00 jmpq *0x200a72(%rip) # 200fc8 <puts@GLIBC_2.2.5>
556: 68 00 00 00 00 pushq $0x0
55b: e9 e0 ff ff ff jmpq 540 <.plt>
0000000000000560 <printf@plt>:
560: ff 25 6a 0a 20 00 jmpq *0x200a6a(%rip) # 200fd0 <printf@GLIBC_2.2.5>
566: 68 01 00 00 00 pushq $0x1
56b: e9 d0 ff ff ff jmpq 540 <.plt>
现在,我使用的不是上面的注释行而不是int *plt = argv;
:
int (*plt)(const char *format, ...) = printf;
现在objdump
给出:
$ objdump -d -j .plt ./a.out
./a.out: file format elf64-x86-64
Disassembly of section .plt:
0000000000000540 <.plt>:
540: ff 35 72 0a 20 00 pushq 0x200a72(%rip) # 200fb8 <_GLOBAL_OFFSET_TABLE_+0x8>
546: ff 25 74 0a 20 00 jmpq *0x200a74(%rip) # 200fc0 <_GLOBAL_OFFSET_TABLE_+0x10>
54c: 0f 1f 40 00 nopl 0x0(%rax)
0000000000000550 <puts@plt>:
550: ff 25 72 0a 20 00 jmpq *0x200a72(%rip) # 200fc8 <puts@GLIBC_2.2.5>
556: 68 00 00 00 00 pushq $0x0
55b: e9 e0 ff ff ff jmpq 540 <.plt>
printf
在哪里?为什么它不在.plt中?