【问题标题】:Parse PLT stub addresses and names解析 PLT 存根地址和名称
【发布时间】:2020-06-27 14:20:08
【问题描述】:
我想从 C/C++ 解析 ELF 文件,其中包含 .plt 部分并获取 PLT 函数存根地址和名称,输出类似于“objdump -D -j .plt a.out”
我可以从文件中获取 .PLT 部分地址,但是如何解析呢?有什么样的结构?如何找到名字?等等
【问题讨论】:
标签:
c++
c
linux
parsing
elf
【解决方案1】:
.plt 的每个条目对应于 .rela.plt 中的一个条目。当您在上面的屏幕截图中看到 pushq $0x0 时,即指的是 .rela.plt 条目 0。
下面是我坐过的二进制文件示例:
$ objdump --section=.plt -C -d -r -M intel /tmp/upb_binary_stripped | head -20
/tmp/upb_binary_stripped: file format elf64-x86-64
Disassembly of section .plt:
0000000000001010 <.plt>:
1010: ff 35 f2 6f 00 00 push QWORD PTR [rip+0x6ff2] # 8008 <_GLOBAL_OFFSET_TABLE_+0x8>
1016: ff 25 f4 6f 00 00 jmp QWORD PTR [rip+0x6ff4] # 8010 <_GLOBAL_OFFSET_TABLE_+0x10>
101c: 0f 1f 40 00 nop DWORD PTR [rax+0x0]
0000000000001020 <longjmp@plt>:
1020: ff 25 f2 6f 00 00 jmp QWORD PTR [rip+0x6ff2] # 8018 <longjmp>
1026: 68 00 00 00 00 push 0x0
102b: e9 e0 ff ff ff jmp 1010 <.plt>
0000000000001030 <setjmp@plt>:
1030: ff 25 ea 6f 00 00 jmp QWORD PTR [rip+0x6fea] # 8020 <setjmp>
1036: 68 01 00 00 00 push 0x1
103b: e9 d0 ff ff ff jmp 1010 <.plt>
现在,如果我在 .rela.plt 中转储重定位,您可以看到 longjmp 和 setjmp 的条目,对应于 PLT 中的数字:
$ readelf -r /tmp/upb_binary_stripped
[...]
Relocation section '.rela.plt' at offset 0x618 contains 10 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000008018 000100000007 R_X86_64_JUMP_SLO 0000000000000000 longjmp + 0
000000008020 000200000007 R_X86_64_JUMP_SLO 0000000000000000 setjmp + 0
[...]
以正常方式读取 Rela 条目,使用 Elf64_Rela 和 ELF64_R_SYM(rela.r_info) 从链接部分获取符号名称(应为 .dynsym)。