linux got分析,聊聊Linux动态链接中的PLT和GOT(3)——公共GOT表项
前文(聊聊Linux动态链接中的PLT和GOT(2)——延迟重定位)提到所有动态库函数的plt指令最终都跳进公共plt执行,那么公共plt指令里面的地址是什么鬼?
把test可执行文的共公plt贴出来:
080482a0 :
80482a0: pushl 0x80496f0
80482a6: jmp *0x80496f4
...
第一句,pushl 0x80496f0,是将地址压到栈上,也即向最终调用的函数传递参数。
第二句,jmp *0x80496f4,这是跳到最终的函数去执行,不过猜猜就能想到,这是跳到能解析动态库函数地址的代码里面执行。
0x80496f4里面住着是何方圣呢?下面使用gdb调试器将它请出来:
$ gdb -q ./test
...
(gdb)x/xw 0x80496f4
0x80496f4 8>: 0x00000000
(gdb) b main
Breakpoint 1 at 0x80483f3
(gdb) r
Starting program: /home/ivan/test/test/test
Breakpoint 1, 0x80483f3 in main ()
(gdb) x/xw 0x80496f4
0x80496f4 8>: 0xf7ff06a0
从调试过程可以发现,0x80496f4属于GOT表中的一项,进程还没有运行时它的值是0x00000000,当进程运行起来后,它的值变成了0xf7ff06a0。如果做更进一步的调试会发现这个地址位于动态链接器内,对应的函数是_dl_runtime_resolve。
嗯,是不是想到了什么呢。所有动态库函数在第一次调用时,都是通过XXX@plt -> 公共@plt -> _dl_runtime_resolve调用关系做地址解析和重定位的。
谈到这里,其实还有谜底是没有解开的,以printf函数为例:
_dl_runtime_resolve是怎么知要查找printf函数的
_dl_runtime_resolve找到printf函数地址之后,它怎么知道回填到哪个GOT表项
到底_dl_runtime_resolve是什么时候被写到GOT表的
前2个问题,只需要一个信息就可以了知道,这个信息就在藏在在函数对应的xxx@plt表中,以printf@plt为例:
printf@plt>:
jmp *0x80496f8
push $0x00
jmp common@plt
第二条指令就是秘密所在,每个xxx@plt的第二条指令push的操作数都是不一样的,它就相当于函数的id,动态链接器通过它就可以知道是要解析哪个函数了。
真有这么神吗?这不是神,是编译链接器和动态链接器故意安排的巧合罢了。
使用readelf -r test命令可以查看test可执行文件中的重定位信息,其中.rel.plt这一段就大有秘密:
$ readelf -r test
....
Relocation section '.rel.plt' at offset 0x25c contains 3 entries:
Offset Info Type Sym.Value Sym. Name
080496f8 00000107 R_386_JUMP_SLOT 00000000 puts
080496fc 00000207 R_386_JUMP_SLOT 00000000 __gmon_start__
08049700 00000407 R_386_JUMP_SLOT 000000000 __libc_start_main
再看看各函数plt指令中的push操作数:
printf对应push 0x0
gmon_start对应push 0x8
__libc_start_main对应push 0x10
这3个push操作数刚好对应3个函数在.rel.plt段的偏移量。在_dl_runtime_resolve函数内,根据这个offset和.rel.plt段的信息,就知道要解析的函数。再看看.rel.plt最左边的offset字段,它就是GOT表项的地址,也即_dl_runtime_resolve做完符号解析之后,重定位回写的空间。
第三个问题:到底_dl_runtime_resolve是什么时候被写到GOT表的。
答案很简单,可执行文件在Linux内核通过exeve装载完成之后,不直接执行,而是先跳到动态链接器(ld-linux-XXX)执行。在ld-linux-XXX里将_dl_runtime_resolve地址写到GOT表项内。
事实上,不单单是预先写_dl_runtime_resolve地址到GOT表项中,在i386架构下,除了每个函数占用一个GOT表项外,GOT表项还保留了3个公共表项,也即got的前3项,分别保存:
got[0]: 本ELF动态段(.dynamic段)的装载地址
got[1]:本ELF的link_map数据结构描述符地址
got[2]:_dl_runtime_resolve函数的地址
动态链接器在加载完ELF之后,都会将这3地址写到GOT表的前3项。
其实上述公共的plt指令里面,还有一个操作数是没有分析的,其实它就是got[1](本ELF的link_map)地址,因为只有link_map结构,结合.rel.plt段的偏移量,才能真正找到该elf的.rel.plt表项。
有兴趣的读者可以使用gdb,在执行到main函数时,将GOT表的这3项数据看一下,验证一下。
好了,谈到这里是否对PLT和GOT机制有个更清晰认识了呢?最后一篇会使用图文结构将整个PLT/GOT机制串起来。
linux got分析,聊聊Linux动态链接中的PLT和GOT(3)——公共GOT表项相关推荐
- 聊聊Linux动态链接中的PLT和GOT(3)——公共GOT表项
前文(聊聊Linux动态链接中的PLT和GOT(2)--延迟重定位)提到所有动态库函数的plt指令最终都跳进公共plt执行,那么公共plt指令里面的地址是什么鬼? 把test可执行文的共公plt贴出来 ...
- 聊聊Linux动态链接中的PLT和GOT(1)——何谓PLT与GOT
在介绍PLT和GOT出场之前,先以一个简单的例子引入两个主角,各位请看以下代码: #include <stdio.h>void print_banner() {printf("W ...
- linux 统计_聊聊 Linux 的内存统计
写在前面 本文主要分析 Linux 系统内存统计的一些指标以及进程角度内存使用监控的一些方法. 开始阅读这篇文章前,请先简单阅读下面的几篇文章. <进程眼中的线性地址空间> <线程眼 ...
- linux内核分析期末,Linux内核分析作业
Linux内核分析课程期末大作业 一.程序的主要设计思路及实现方式 在Linux内核中,存在一个全局变量:init_task.该变量即是Linux第一个启动的用户空间进程init对应的task_str ...
- linux修改http版本信息,动态库中的soname中版本号的修改
soname(简单共享名,Short for shared object name),在linux下使用动态库时,经常会发现明明编译时指定的是libA.so,可是程序运行时或通过ldd查看依赖却是li ...
- linux make指定目标平台,CMake on Linux:目标平台不支持动态链接
我很简单 CMakeLists.txt CMAKE_MINIMUM_REQUIRED(VERSION 2.8) FIND_PACKAGE(VTK REQUIRED) PROJECT(test CXX) ...
- linux kdump 分析工具,Ubuntu 15.10中的Kdump工具实战
Step 1: 安装kdump and crash工具 sudo apt-get install linux-crashdump Step 2: 安装kernel的符号文件 可以先用apt-cache ...
- Linux命令行下载OneDrive分享链接中的文件
我所知的某个游戏分享站喜欢用OneDrive来分享游戏,用OneDrive很好,抵制百度网盘我强烈支持,但是OneDrive国内有时候抽风比较厉害,而在国外OneDrive下载几乎能跑满带宽,我G口的 ...
- linux内核分析 轮换,Linux 内核源代码情状分析 chap2 存储管理 (6) - 页面的定期换出...
1. 目的 Linux 内核通过定期检查并且预先将若干页面换出, 实现减轻系统在缺页异常时候所产生的负担. 虽然, 无法避免需要临时寻找可以换出的页面, 但是, 可以减少这种事件发生的概率.Linux ...
最新文章
- Vue开发跨端应用(二)修改electron demo
- css div 边缘渐变,围绕div的CSS3渐变边框
- 精准营销的核心思维何在?
- 激光SLAM学习--多种类激光雷达介绍(单线、多线)
- 一周学习总结PPT-学会VLOOKUP函数,1分钟搞定数据汇总
- 使用 node.js 进行服务器端 JavaScript 编程
- 深入JVM系列(二)之GC机制、收集器与GC调优
- 【Machine Learning】监督学习、非监督学习及强化学习对比
- Mac远程服务器文件上传rz和sz的安装使用
- 成都市交委与摩拜科技联手 助推智慧城市建设
- MSDN 精简版 1.6
- mouseenter和mouseleave跟mouseover和mouseout
- 色谱计算机常用英文,色谱术语的常用中英文对照
- AspUpload组件的方法中文说明
- DOORS vs DNG
- object mapping for [details] tried to parse field [details] as object, but found concrete value
- java datetime转int_java日期int和String互转
- 密码的显示与隐藏php,el-input 标签中密码的显示和隐藏功能的实例代码
- 上汽招聘项目管理PMO(地点:上海,薪酬面议)
- 7-5 宿舍谁最高? (20 分)