linux动态链接中的PLT和GOT,Linux中的GOT和PLT到底是个啥?

*本文原创作者:PhyzX,本文属FreeBuf原创奖励计划,未经许可禁止转载

0x00 Intro

本文以Ian Wienand的博客 为蓝本,我在必要的地方予以增补、解释以及再实验,希望读者对PLT和GOT有一个初步的、相对完整的认识。

0x01The Simplest Example

原文的标题是“PLT and GOT - the key to code sharing and dynamic libraries”,可见PLT和GOT对代码复用以及动态库的关键作用。

共享库(shared library)是现代操作系统的组成部分,但其内部机制却很少有人去了解。当然,有很多解释共享库机制的文章,希望本篇博客能为这方面的知识体系加一把火。

OK,我们从最起始部分讲起----在二进制文件(比如object file)中会有一段叫relocations的部分,这部分的内容在链接时候(link time)再进行敲定确切的值,注意链接可以发生在运行前(称为静态链接,toolchain linker),也可发生在运行时(称为动态链接,dynamic linker)。具体relocations部分中的内容就是在讲:“确定X这个符号(symbol)的值,然后把这个值写到二进制文件的Y偏移处”。每一条relocation都有确定的类型(定义与ABI文档中),从而确切地说明每个类型的值到底该如何敲定。

如下为最简单的例子:

3e74d97f2c9082207f07f32725019b28.png

我们可以看到”foo”这个符号的Sym.Value是0,说明在把a.c编译成a.o的时候,“foo”这个符号的值还不知道,所以编译就在Sym.Value处先写0,然后在Type这个位置写上R_X86_64_PC32,从而告诉之后要进行link的链接器:”在最终生成的可执行文件的.text部分的0x6这个偏移位置,patch上foo这个符号的地址值”。如果我们看一下a.o这个对象文件的.text部分0x6这个位置,我们会看到如图绿线部分:

a69aeb637c030141cf5d84e1503a7b67.png

觉得刚刚看到这张图片,可能就会有些刚刚接触这些概念的同学就有些懵了。别急,我一点点地讲这张图。首先一个二进制可执行文件可被划分为多个部分:

f584a6f2ecb72d3879b7e2f9de8bd5d4.png

这张图片截取自《程序员的自我修养》这本书,真心希望像搞懂“程序是如何跑起来的?”这种问题的同学,去读一下这本书,你会觉得很值的,这是一个很本质的问题,而书中解释得那样的清晰,总之,强烈推荐!

.text部分会放着这个二进制文件的执行代码,所以当我们用objdump进行反汇编的时候,就会看到a.o这个二进制文件的.text部分的机器码,前两条指令用于布置好栈空间(这部分可参考William Stallings的Computer Security那本书的第十章)不是本文的重点,后两条指令用于清理栈空间,并返回调用函数,也不是本文重点。重点在第三条语句,它在.text的Offset 0x4处。我们可以看到,a.o仅仅是一个经过编译后的object file,所以其中的真实值并没有敲定,从而看到绿线处暂时填4个00。

好,下面我问一个问题:当CPU执行到0x4出这句指令时,%rip(即PC)的值为多少?两个选项,A. 0x4 ;B. 0xa。答案:B。参考CSAPP第四章,截图如下:

1001c9e093dbcae7bc87964a0092389e.png

其实,计算机在执行一条指令需要一个指令周期,不同的CPU架构的指令周期可以分为不同阶段,上图中我们可看到Intel x86架构CPU的指令周期分为:取指,译码,执行,访存,写回,PC update,这六个阶段。这里,我说一下我对PC的理解,图中绿线部分,vaIP对应%rip寄存器,%rip趋向于一种实际意义层面上的理解,而PC更趋向于一种意向意义层面上的理解。具体来说,在PC update阶段,CPU才去关注”我要去执行的下一条指令

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值