.got 和 .got.plt 部分有啥区别?

Posted

技术标签:

【中文标题】.got 和 .got.plt 部分有啥区别?【英文标题】:What is the difference between .got and .got.plt section?.got 和 .got.plt 部分有什么区别? 【发布时间】:2012-07-25 11:06:55 【问题描述】:

ELF 格式的 .got 和 .got.plt 部分有什么区别?

【问题讨论】:

根据:acsu.buffalo.edu/~charngda/elf.html.got 条目永远不会被延迟解析,但.got.plt 条目可以被延迟解析。 我认为 .got 用于关于全局“变量”的重定位,而 .got.plt 是在解析过程绝对地址时与 .plt 一起作用的辅助部分。 【参考方案1】:

我之前的评论是正确的:

我认为.got 用于关于全局“变量”的重定位,而.got.plt 是在解析过程绝对地址时与.plt 一起行动的辅助部分。

下面的例子让事情变得更清楚了。

这些是我的 32 位 i686-linux /lib/libm.so 的重定位

Relocation section '.rel.dyn' at offset 0x32b8 contains 8 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
00025030  00000008 R_386_RELATIVE   
00024fd8  00005706 R_386_GLOB_DAT    00025034   _LIB_VERSION
00024fdc  00000406 R_386_GLOB_DAT    00000000   __gmon_start__
00024fe0  00000506 R_386_GLOB_DAT    00000000   _Jv_RegisterClasses
00024fe4  00000806 R_386_GLOB_DAT    00000000   _rtld_global_ro
00024fe8  00000906 R_386_GLOB_DAT    00000000   stderr
00024fec  00013006 R_386_GLOB_DAT    0002507c   signgam
00024ff0  00000e06 R_386_GLOB_DAT    00000000   __cxa_finalize

Relocation section '.rel.plt' at offset 0x32f8 contains 12 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
00025000  00000107 R_386_JUMP_SLOT   00000000   fputs
00025004  00000207 R_386_JUMP_SLOT   00000000   __errno_location
00025008  00000307 R_386_JUMP_SLOT   00000000   sprintf
0002500c  00000407 R_386_JUMP_SLOT   00000000   __gmon_start__
00025010  00000607 R_386_JUMP_SLOT   00000000   strtod
00025014  00000707 R_386_JUMP_SLOT   00000000   __assert_fail
00025018  00000a07 R_386_JUMP_SLOT   00000000   strlen
0002501c  00000b07 R_386_JUMP_SLOT   00000000   strtof
00025020  00000c07 R_386_JUMP_SLOT   00000000   fwrite
00025024  00000d07 R_386_JUMP_SLOT   00000000   strtold
00025028  00005e07 R_386_JUMP_SLOT   00005970   matherr
0002502c  00000e07 R_386_JUMP_SLOT   00000000   __cxa_finalize

您注意到有两个重定位部分,即 .rel.dyn 和 .rel.plt。您可以看到 .rel.plt 的所有重定位都是 R_386_JUMP_SLOT 类型,这意味着它们是分支重定位,另一方面,几乎所有 .rel.dyn 中的重定位都是 R_386_GLOB_DAT,这意味着全局变量的重定位。

.symtab 和 .dynsym 之间存在另一个细微差别。虽然第一个包含静态链接编辑期间使用的所有符号的引用,但后者仅包含动态链接所需的那些符号。因此,上面提到的重定位仅指 .dynsym 部分。

【讨论】:

IIRC,地址被占用的函数也需要.got 条目;编译器通常选择要求对它们进行早期绑定,以便它们可以从 GOT 加载最终地址,而不是仅仅将 PLT 存根的地址作为函数指针。

以上是关于.got 和 .got.plt 部分有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

C温故补缺(十七):动态链接(ELF,PIC,GOT,PLT)

elf文件中的.plt .rel.dyn .rel.plt .got .got.plt的关系

Pwn_11 Got 劫持

ciscn_2019_sw_1 Writeup

ApplicationSettings 部分和 AppSettings 部分有啥区别? [复制]

部分视图和渲染部分视图有啥区别?