当前位置: 首页 > article >正文

从elf文件动态加载的过程解释got,plt及got.plt,plt.sec


author: hjjdebug
date: 2025年 05月 23日 星期五 17:29:34 CST
desprib: 从elf文件动态加载的过程解释got,plt及got.plt,plt.sec


文章目录

  • 1. 概念定义
  • 2. 测试源码
  • 3. 外部函数调用对应着 .plt.sec 中的一小段代码,
  • 4. .got.plt 将来存储实际的外部函数地址, 开始存储.plt中对应地址
  • 5. plt 节对应一小段代码,即以槽号为参数,调用地址解析函数.把真实外部地址存入.got.plt表

1. 概念定义

1 GOT : 全局偏移表(GOT, Global Offset Table)
由于调试时没有碰到使用它,就不多介绍了

  1. got.plt , 归属于got,数据表,保存有外部函数地址.
    但第一次函数调用时,保存的是plt中的对应地址

  2. plt.sec ,其中的sec可能是section的简写, 表示归属plt
    程序段, 对于每一个外部调用项,例add@plt, printf@plt
    提供一条跳转指令 jmp (*addr)
    其中 addr 是 got.plt地址表中一项

  3. plt : 程序链接表(PLT,Procedure Link Table)
    程序段, 代码形式
    push number
    jmp _dl_runtime_resolve
    以槽位号为参数,调用地址解析函数,修改对应got.plt项

2. 测试源码

下面给出一个简单的测试代码来分析

$cat lib.cpp
int add(int i,int j){return i+j;}$cat main.cpp
#include <stdio.h>
int add(int i,int j);
int main() {int i=add(3,5);printf("i:%d\n",i);return 0;
}

编译:
把add 编译称库函数 g++ -shared -o lib.so lib.cpp
$ g++ -no-pie -o tt main.cpp -L. lib.so
执行:
hjj@hjj-7090:~/test/tt$ export LD_LIBRARY_PATH=.
hjj@hjj-7090:~/test/tt$ ./tt
i:8

代码分析:
汇编码:

int main() {401156:	f3 0f 1e fa          	endbr64 40115a:	55                   	push   %rbp40115b:	48 89 e5             	mov    %rsp,%rbp40115e:	48 83 ec 10          	sub    $0x10,%rspint i=add(3,5);401162:	be 05 00 00 00       	mov    $0x5,%esi401167:	bf 03 00 00 00       	mov    $0x3,%edi40116c:	e8 df fe ff ff       	callq  401050 <_Z3addii@plt> //调用外部add函数401171:	89 45 fc             	mov    %eax,-0x4(%rbp) //保存到iprintf("i:%d\n",i);401174:	8b 45 fc             	mov    -0x4(%rbp),%eax401177:	89 c6                	mov    %eax,%esi      //i给第2参数401179:	48 8d 3d 84 0e 00 00 	lea    0xe84(%rip),%rdi //字符串给第1参数      401180:	b8 00 00 00 00       	mov    $0x0,%eax401185:	e8 d6 fe ff ff       	callq  401060 <printf@plt> //调用外部printfreturn 0;40118a:	b8 00 00 00 00       	mov    $0x0,%eax
}

从上边汇编码分析知:

3. 外部函数调用对应着 .plt.sec 中的一小段代码,

每段代码即而跳转进.got.plt中定义的地址. 相当于 jmp (*addr), 从固定表项取地址去执行
Disassembly of section .plt.sec:
0000000000401050 _Z3addii@plt:
401050: f3 0f 1e fa endbr64
401054: f2 ff 25 bd 2f 00 00 bnd jmpq *0x2fbd(%rip) # 404018 <_Z3addii>
40105b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)

0000000000401060 printf@plt:
401060: f3 0f 1e fa endbr64
401064: f2 ff 25 b5 2f 00 00 bnd jmpq *0x2fb5(%rip) # 404020 <printf@GLIBC_2.2.5>
40106b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)

0x404018 处存储着 int add(int i, int j);函数的实际入口地址.
0x404020 处存储着 printf 的实际入口地址,
但是, 第一次调用时, 0x404018 存储的还不是add 的地址, 而是0x401030 .plt中的地址

4. .got.plt 将来存储实际的外部函数地址, 开始存储.plt中对应地址

Contents of section .got.plt:
404000 103e4000 00000000 00000000 00000000 .>@…
404010 00000000 00000000 30104000 00000000 …0.@…
404020 40104000 00000000 @.@…
加载如内存后, 404008,404010地址就变成有效值了. 它们是动态解析函数地址._dl_runtime_resolve

这个表从0x404018开始,地址是会被修改的,函数实际地址会由地址解析函数放到这里.
加载时的初始化地址对应着.plt中的一小段代码地址,

5. plt 节对应一小段代码,即以槽号为参数,调用地址解析函数.把真实外部地址存入.got.plt表

0x401030 在 .plt 节中, 对应一小段代码. 形式为 push number; jump address_resolve;
Disassembly of section .plt:
0000000000401020 <.plt>:
401020: ff 35 e2 2f 00 00 pushq 0x2fe2(%rip) # 404008 <GLOBAL_OFFSET_TABLE+0x8>
401026: f2 ff 25 e3 2f 00 00 bnd jmpq *0x2fe3(%rip) # 404010 <GLOBAL_OFFSET_TABLE+0x10>
40102d: 0f 1f 00 nopl (%rax)
401030: f3 0f 1e fa endbr64 #后面的代码只会走一次,当第一次函数调用时.
401034: 68 00 00 00 00 pushq $0x0
401039: f2 e9 e1 ff ff ff bnd jmpq 401020 <.plt>
40103f: 90 nop
401040: f3 0f 1e fa endbr64
401044: 68 01 00 00 00 pushq $0x1
401049: f2 e9 d1 ff ff ff bnd jmpq 401020 <.plt>
40104f: 90 nop

add会push 进0, 即槽位0 ,对应着修改.got.plt的404018. 调用地址解析函数(404010处地址)
同样,
printf会push进1, 即槽位1 ,对应着修改.got.plt的404020. 调用地址解析函数(404010处地址)
地址解析函数会根据槽位找到符号,再根据符号名找到符号地址,这就是地址解析的过程,
找到地址后根据槽位存入地址表, 这就是后绑定.
好处你就随便说了, 只绑定一次, 用的时候才绑定, 不用一下子把所用外部函数都绑定等.

我的gcc version
$ gcc --version
gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0
反汇编及地址解析,绑定实现的细节也许会与编译器有关系,不过其原理应该是一致的.
通过具体解剖这个小麻雀,我们知道了got.plt, plt,plt.sec的工作的细节,知道了动态连接的过程.

相关文章:

从elf文件动态加载的过程解释got,plt及got.plt,plt.sec

author: hjjdebug date: 2025年 05月 23日 星期五 17:29:34 CST desprib: 从elf文件动态加载的过程解释got,plt及got.plt,plt.sec 文章目录 1. 概念定义2. 测试源码3. 外部函数调用对应着 .plt.sec 中的一小段代码,4. .got.plt 将来存储实际的外部函数地址, 开始存储.plt中对应…...

鸿蒙HarmonyOS多设备流转:分布式的智能协同技术介绍

随着物联网和智能设备的普及&#xff0c;多设备间的无缝协作变得越来越重要。鸿蒙&#xff08;HarmonyOS&#xff09;作为华为推出的新一代操作系统&#xff0c;其分布式技术为实现多设备流转提供了强大的支持。本文将详细介绍鸿蒙多设备流转的技术原理、实现方式和应用场景。 …...

XXE(外部实体注入)

目录 学习xxe前提&#xff1a;了解xml格式 1. XML基础 2. XXE基础知识 2.1. 结构 2.2. 定义与原理 2.3. XML实体类型 2.4. 攻击类型 2.5. 防御措施 3. pikachu靶场xxe练习 学习xxe前提&#xff1a;了解xml格式 1. XML基础 文档结构包括XML声明、DTD文档类型定义&…...

jenkins凭据管理

用途: 存储构建需要与其他系统认证所使用的账户或者密码信息. Username with password类型存储Harbor或者其他系统的用户名和密码。GitLab API token类型存储Gitlab的用户API token。Secret text类型可以用来存储OpenShift等系统中的token。Certificate类型可以用户存储证书&am…...

驱动开发硬核特训 · Day 31:理解 I2C 子系统的驱动模型与实例剖析

&#x1f4da; 训练目标&#xff1a; 从驱动模型出发&#xff0c;掌握 I2C 子系统的核心结构&#xff1b;分析控制器与从设备的注册流程&#xff1b;结合 AT24 EEPROM 驱动源码与设备树实例&#xff0c;理解 i2c_client 与 i2c_driver 的交互&#xff1b;配套高质量练习题巩固理…...

9大开源AI智能体概况

项目GitHub 链接开发组织核心功能应用领域典型应用案例活跃度AutoGPT (176k⭐)链接Significant Gravitas 团队基于 GPT-4 的自主代理&#xff0c;能够自动分解任务并生成多步提示循环执行&#xff0c;支持调用工具&#xff08;如网络搜索、文件操作等&#xff09;。自动化办公、…...

【python】局域网内通过python远程重启另一台windows电脑

&#x1f449;技__能&#x1f448;&#xff1a;C/C/C#/Python/Java/PHP/Vue/Node.js/HTML语言 &#x1f449;专__注&#x1f448;&#xff1a;专注主流机器人、人工智能等相关领域的开发、测试技术。 局域网内通过python远程重启另一台windows电脑 目录 局域网内通过python远程…...

超越感官的实相:声、光、气味的科学与哲学探微

在人类的感官世界中&#xff0c;声、光、气味是日常生活中最直接的现象&#xff1a;我们聆听音乐、观赏光影、呼吸花香。然而&#xff0c;若深入探究它们的本质&#xff0c;科学与哲学竟以截然不同的视角&#xff0c;揭示了一个超越感官的实相世界。本文将从经典物理学、佛教哲…...

Python邮件处理:POP与SMTP

poplib简介 poplib 是Python 3中的官方邮件库&#xff0c;实现了POP的标准&#xff1a;RFC1939&#xff0c;用于邮件的收取。与之类似的还有imaplib 。 &#xff08;注&#xff1a;本文仅拿pop举例&#xff09; poplib的使用方法&#xff0c;就是几步&#xff1a; 先创建一…...

什么是VR场景?VR与3D漫游到底有什么区别

在数字化时代&#xff0c;虚拟现实&#xff08;Virtual Reality, 简称VR&#xff09;场景与3D漫游作为两种前沿技术&#xff0c;改变着人们的生活方式和体验模式。通过计算机模拟真实或假想的场景&#xff0c;让用户仿佛身临其境&#xff0c;并能与虚拟环境进行互动。尽管VR场景…...

python学习day2:进制+码制+逻辑运算符

进制 Python 中的进制表示与转换 进制的基本概念 二进制、八进制、十进制、十六进制的定义与特点不同进制在计算机科学中的应用场景 Python 中的进制表示 二进制表示&#xff1a;使用 0b 前缀八进制表示&#xff1a;使用 0o 前缀十六进制表示&#xff1a;使用 0x 前缀示例…...

【分布式文件系统】FastDFS

1.简介 讲这个之前&#xff0c;相信很多人特别是学java的&#xff0c;肯定在做苍穹外卖的时候肯定接触过一个东西&#xff0c;叫做阿里云OSS&#xff0c;他们的功能都差不多&#xff0c;但是阿里云的这个是要付费的&#xff0c;而FastDFS是免费开源的&#xff0c;是由淘宝资深…...

14、自动配置【源码分析】-初始加载自动配置类

14、自动配置【源码分析】-初始加载自动配置类 Spring Boot的自动配置功能通过智能地加载和配置组件&#xff0c;极大地简化了应用的初始化过程。以下是初始加载自动配置类的详细原理&#xff1a; ### 1. 启动应用 当执行 SpringApplication.run() 方法启动Spring Boot应用时&a…...

word为章节标题添加自动编号

问题&#xff1a; 如何为word文档中的多级标题添加自动编号&#xff1f; 方法&#xff1a; 1、首先为文档各级标题设置格式样式&#xff0c;一级标题使用样式中的“标题 1”&#xff0c;二级标题使用“标题 2”&#xff0c;三级使用“标题 3”&#xff0c;也就是直接在开始—…...

无人机飞行间隔安全智能评估、安全风险评估

无人机空中安全飞行评估需结合改进碰撞模型、蒙特卡洛仿真、安全间隔反推及动态避障策略&#xff0c;通过多机型分类与实时数据融合&#xff0c;实现从理论建模到实际部署的全流程管控&#xff0c;为城市低空密集飞行提供安全保障。 需求 无人机飞行间隔安全智能评估 无人机…...

C++成员对象和封闭类

C++成员对象和封闭类详解 在C++中,成员对象是指一个类的成员变量,它本身是另一个类的对象。封闭类是包含这些成员对象的类。理解两者的关系和行为,对于构造函数、析构函数、初始化顺序以及内存布局等方面的理解非常重要。 1. 成员对象和封闭类的基本概念 成员对象 是一个类…...

【VLNs篇】03:VLMnav-端到端导航与视觉语言模型:将空间推理转化为问答

栏目内容论文标题End-to-End Navigation with Vision-Language Models: Transforming Spatial Reasoning into Question-Answering (端到端导航与视觉语言模型&#xff1a;将空间推理转化为问答)核心问题如何利用大型视觉语言模型&#xff08;VLM&#xff09;实现端到端的机器人…...

PCB设计实践(二十五)贴片电阻与插件电阻的全面解析:差异、演进与应用场景

一、基础结构与技术原理差异 物理结构差异 贴片电阻&#xff08;SMD Resistor&#xff09;采用表面贴装技术&#xff08;SMT&#xff09;&#xff0c;其主体为扁平长方体或圆柱形结构&#xff0c;两端金属化电极直接与PCB焊盘接触。典型封装尺寸包括0402&#xff08;1.00.5mm&a…...

知道不知道

以其昏昏使人昭昭&#xff0c;真正的傻子是自己。 昏昏沉沉&#xff0c;迷迷茫茫&#xff0c;无所适从&#xff0c;无所事事。 清醒与糊涂间交替&#xff0c;知道与不知道间轮循。 在哪里&#xff1f;到哪里&#xff1f; 世界上事物对于我们&#xff1a;知道知道的&…...

文章记单词 | 第106篇(六级)

一&#xff0c;单词释义 branch /brntʃ/ n. 树枝&#xff1b;分支&#xff1b;分部 v. 分支&#xff1b;分岔proceeding /prəˈsiːdɪŋ/ n. 程序&#xff1b;进程&#xff1b;&#xff08;复数&#xff09;会议记录academy /əˈkdəmi/ n. 学院&#xff1b;研究院&#x…...

SpringBoot项目中Redis的使用

在Spring Boot项目中使用Redis作为缓存或数据存储是非常常见的场景。以下是详细的实现步骤和示例代码&#xff1a; 一、添加依赖 在pom.xml中添加Spring Data Redis依赖&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifac…...

Canvas设计图片编辑器全讲解(一)Canvas基础(万字图文讲解)

一、前序 近两年AI发展太过迅速&#xff0c;各类AI产品层出不穷&#xff0c;AI绘图/AI工作流/AI视频等平台的蓬勃发展&#xff0c;促使图片/视频等复杂内容的创作更加简单&#xff0c;让更多普通人有了图片和视频创作的机会。另一方面用户内容消费也逐渐向图片和视频倾斜。在“…...

利用Qt绘图随机生成带多种干扰信息的数字图片

背景 在学习AutoML或ML的过程中&#xff0c;需要一些图片类型的数据做分类预测训练&#xff0c;于是想到尝试最简单的数字识别&#xff0c;且单个数字的识别&#xff0c;也就是y的取值只有10种可能&#xff0c;即0到9。 以下参考代码分别考虑了数字字体的大小、数字颜色的深浅…...

STM32——从点灯到传感器控制

STM32基础外设开发&#xff1a;从点灯到传感器控制 一、前言 本篇文章总结STM32F10x系列基础外设开发实例&#xff0c;涵盖GPIO控制、按键检测、传感器应用等。所有代码基于标准库开发&#xff0c;适合STM32初学者参考。 二、硬件准备 STM32F10x系列开发板LED模块有源蜂鸣器…...

java day14

接昨天&#xff0c;响应 响应 就是我们在处理请求的时候&#xff0c;里面的return 其实方法里面写的return的返回平常的什么字符串啊什么等等&#xff1b;这些东西都是直接返回&#xff1b;如果是一个对象的话&#xff0c;我们会按json的格式返回&#xff1b; 这些都依赖于一…...

Tailwind css实战,基于Kooboo构建AI对话框页面(一)

在当今数字化时代&#xff0c;AI 助手已成为网站和应用不可或缺的一部分。本文将带你一步步使用 Tailwind CSS 和 Kooboo 构建一个现代化的 AI 对话界面框。 一、选择 Kooboo平台 的核心优势 智能提示&#xff1a;在输入 class 属性时&#xff0c;会自动触发 Tailwind CSS 规则…...

重塑数学边界:人工智能如何引领数学研究的新纪元

目录 一、人工智能如何重新定义数学研究的边界 &#xff08;一&#xff09;数学与AI的关系&#xff1a;从基础理论到创新思维的回馈 &#xff08;二&#xff09;AI的创造力&#xff1a;突破传统推理的局限 &#xff08;三&#xff09;AI对数学研究的潜在贡献&#xff1a;创…...

docker部署并测试翻译模型-CSANMT连续语义增强机器翻译

1.模型选择CSANMT-Translation模型&#xff1a; 2.修改docker-compose.yml文件&#xff0c;重新定义模型缓存路径和存储路径 其中MODELSCOPE_CACHE指定了模型的下载路径。 3.运行docker compose up -d --build&#xff0c;提示出现报错&#xff1a;Error response from daemon…...

蓝桥杯2025.5.23每日一题-儿童数

儿童数 若一个正整数 n n n 满足 n 61 n^{61} n61 整除 2024 ! 2024! 2024!&#xff0c;即 2024 ! 2024! 2024! 除以 n 61 n^{61} n61 的余数为 0 0 0&#xff0c;则称 n n n 为儿童数。 现在&#xff0c;请你计算在区间 [ 1 , ∞ ) [1, \infty) [1,∞) 内一共有多少…...

Spring Boot项目配置核心 - pom.xml的依赖管理与构建优化

基础架构 <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVe…...