Linux动态链接懒加载

news2025/4/17 8:57:43

Linux动态链接懒加载

懒加载

最近一个名词——懒加载,是一种与动态链接相关的技术,我对它有点感兴趣,于是决定深入了解一番。

懒加载是一种延迟加载资源的策略,它将资源的加载推迟到在首次访问或需要时才执行。这意味着在应用程序启动时,并不会立即加载和链接所有可能需要的库或模块,而是等到应用程序执行到实际需要使用它们的代码路径时才加载和链接。这可以减少启动时间和内存占用,因为应用程序只加载了实际需要的部分。

比如,以下面的程序为例。当程序刚运行到main函数时,got中还没有printf函数的地址。当程序要调用printf函数的时候,才会将printf的地址写入got中

#include <stdio.h>

int main() {
    printf("Hello World!\n");
    return 0;
}

我听说Linux中默认采用懒加载,就将上面的程序编译后进行调试。

gcc main.c -o main -g
gdb main

main函数反汇编

printf函数参数只有字符串,此时编译器会将printf函数替换为puts函数。因为采用的是动态链接,要使用puts函数,会先跳转到plt,再从plt跳转到got中的地址。

先不急着运行,我们来看看got中的数据。

got数据

好奇怪,got中已经有了puts的地址。说好的懒加载呢?

那么got中什么时候被写入了puts的地址呢?

got数据被修改

我重新调试一次。starti命令会开始执行程序,并在第一条指令处停下来。0x555555557fd0是got中puts的地址,一开始的值是0x1030。watch指令在检测到地址中的值改变后会停止运行。

这里可以看到,程序在…/sysdeps/x86_64/dl-machine.h中停了下来。程序现在还处于/lib64/ld-linux-x86-64.so.2中,这是linux的动态链接器,负责动态库加载,符号解析和重定位等。

从上面的调试过程可以看出,linux的动态链接并不是默认采用懒加载

那怎么才能让linux动态链接的时候采用懒加载呢?需要在编译的时候加上特别的参数。

gcc main.c -o main -g -Wl,-z,lazy

这样就可以让linux以懒加载的方式解析符号地址。-z,lazy是把lazy参数传递给链接器。从这里我们可以看出,是否采用懒加载是由链接器决定的

重新调试,得到下面的结果。

懒加载got

可以看到got中puts的地址还未被修改成正确的地址。那么这个0x0000555555555030又是什么呢。

plt

objdump plt

上面的图是通过objdump得到的数据,0x0000555555555030对应的是0x1030,0x555555555020对应的是0x1020。

我们的跳转顺序为 main -> puts@plt -> .plt。0x555555555026会跳转到动态链接器,由动态链接器完成动态库加载和符号解析,并把解析后的地址填入got中。

这就是整个懒加载的过程了。

RELRO

RELRO(Read-Only Relocations)是一种用于加强可执行文件的安全性的机制,特别是针对共享库(动态链接库)的。它的主要目的是防止一些常见的攻击技巧,例如覆盖全局偏移表(GOT)和过程链接表(PLT)的攻击。

RELRO 的作用和原理:

  1. Partial RELRO(PRelRO):这是 RELRO 的一种模式,它将 GOT 表中的一部分条目标记为只读。在程序启动后,这些条目将被标记为只读,从而保护它们免受任何修改。这提供了一定程度的保护,但仍然允许一些符号的重定位,这些符号可能需要在运行时解析。
  2. Full RELRO(FRelRO):这是 RELRO 的更强版本,它将 GOT 表中的所有条目都标记为只读。这意味着在程序启动后,所有 GOT 表中的符号都无法被修改。这提供了更高级别的保护,但可能导致一些特定情况下的性能损失,因为某些符号可能需要在运行时解析,但它们现在无法被修改。

我们怎么知道一个可行性文件是Partial RELRO还是Full RELRO?可以通过checksec来查看。

sudo apt install checksec

checksec

可以看到懒加载是Partial RELRO,非懒加载是Full RELRO。

如果不采用懒加载,在程序正式运行前,会由动态链接器ld.so进行动态库加载和符号解析,并把dynamic和got等段设置为只读。

如果采用懒加载,只会将dynamic和部分got设置为只读,另一部分got设置为可写。

那么这种机制是如何实现的呢?我们需要通过objdump查看可执行文件的段偏移来理解。

非懒加载got

懒加载got

可以看到,在懒加载中,有两个got段:.got和.got.plt。.got的内容会在程序运行前被修改,然后会把从rodata到got的读写权限设置为只读。另外,.got.plt的起始地址是4K对齐的,.got.plt和.data在一个页面中,它们的读写权限也一样,都是可读可写。在运行过程中,动态链接器会动态解析符号地址并填入.got.plt中。

而非懒加载中,.got的内容会在程序运行前被修改,然后会把从rodata到got的权限设置为只读。

本篇博客主要讲了如何让可执行文件以懒加载的方式执行,懒加载的大致流程,RELRO的原理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/997947.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Paper: 利用RNN来提取恶意软件家族的API调用模式

论文 摘要 恶意软件家族分类是预测恶意软件特征的好方法&#xff0c;因为属于同一家族的恶意软件往往有相似的行为特征恶意软件检测或分类方法分静态分析和动态分析两种&#xff1a; 静态分析基于恶意软件中包含的特定签名进行分析&#xff0c;优点是分析的范围覆盖了整个代码…

【Unity3D】UI Toolkit自定义元素

1 前言 UI Toolkit 支持通过继承 VisualElement 实现自定义元素&#xff0c;便于通过脚本控制元素。另外&#xff0c;UI Toolkit 也支持将一个容器及其所有子元素作为一个模板&#xff0c;便于通过脚本复制模板。 如果读者对 UI Toolkit 不是太了解&#xff0c;可以参考以下内容…

《AI辞职信一键生成》告别凡俗套路,展现独特个性!

在这个科技日新月异的时代&#xff0c;我们的生活被各种应用软件深深地渗透。其中&#xff0c;讯飞星火AI大模型的应用无疑是一种创新和突破。最近&#xff0c;我有幸体验了一款名为《AI辞职信一键生成》的web应用&#xff0c;它以其独特的功能和出色的用户体验&#xff0c;让我…

微信小程序Day2笔记

1、WXML模板语法 1. 数据绑定 数据绑定的基本原则 在data中定义数据在WXML中使用数据 2. 在data中定义页面的数据 在页面对应的.js文件中&#xff0c;把数据定义到data对象中。 3. Mustache语法的格式 把data中的数据绑定到页面中渲染&#xff0c;使用Mustache语法&…

不推介使用裸指针的几种情况

情况一&#xff1a; //原生指针没有所有权 void f() {// 不好: 原生指针拥有了所有权int* p1 new int{7}; // ... }template<typename T> class X {public:T* p; // 不好: 不清楚 p 所有权T* q; // 不好: 不清楚 q 所有权// ... };// 不好: 不清楚返回值所有权 Gadget*…

机器学习:自然语言处理上的对抗式攻击

Attacks in NLP 相关话题 Introduction 以前的攻击专注于图像和语音上&#xff0c;而NLP上的内容比较少。而NLP的复杂度跟词典有关系&#xff1a; NLP只能在embedding后的特征上加噪声 Evasion Attacks 电影的评论情感分类&#xff0c;将film换成films后&#xff0c;评论从…

637. 二叉树的层平均值

637. 二叉树的层平均值 题目-简单难度示例1. bfs 题目-简单难度 给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。 示例 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&…

DQN模型

1. DQN模型 References [1] 强化学习第五节&#xff08;DQN&#xff09;【个人知识分享】_哔哩哔哩_bilibili

在MDK-Keil中开发S32K144

对于NXP的S32K1xx系列MCU&#xff0c;前面已经介绍过&#xff0c;官方有专门支持该系列MCU开发的IDE工具——S32DS&#xff0c;这个工具还有对应的代码生成配置工具&#xff0c;而且也是官方推荐使用的工具。 S32DS开发环境是基于Eclipse改写的&#xff0c;熟悉Eclipse的话可以…

python使用百度AipOCR来实现图像文字识别

上篇文字讲到了可以截屏手机模拟器上的界面并传回电脑上&#xff0c;文章链接 python将手机模拟器截屏并发送至电脑上_小小爬虾的博客-CSDN博客 传回来以后&#xff0c;就可以识别出图片中的文字内容了。 我使用的是Python3.10.4&#xff0b;百度的AipOCR库实现图像文字识别…

利用Scrum敏捷工具管理敏捷产品迭代Sprint Backlog

​什么是Sprint Backlog&#xff1f; Sprint Backlog是Scrum的主要工件之一。在Scrum中&#xff0c;团队按照迭代的方式工作&#xff0c;每个迭代称为一个Sprint。在Sprint开始之前&#xff0c;PO会准备好产品Backlog&#xff0c;准备好的产品Backlog应该是经过梳理、估算和优…

systemserver的inputdispatcher直接产生CANCEL事件原理分析-讨厌的android触摸面试题

背景回顾&#xff1a; 上一个blog已经重点讲解了app层面自己产生的Cancel触摸事件&#xff0c;大概产生的原理如下&#xff1a; 上一个blog地址&#xff1a;https://blog.csdn.net/learnframework/article/details/124086882 即可以看出来&#xff0c;在服务端systemserver其实…

国家信息中心举办“数字政府建设暨数字安全技术”研讨会:海云安提出数字政府软件供应链安全解决方案

近日&#xff0c;由国家信息中心主办&#xff0c;复旦大学研究院承办的“数字政府建设暨数字安全技术研讨会”在义乌顺利召开。国家信息中心信息与网络安全部副主任禄凯&#xff0c;复旦大学党委常委、宣传部部长陈玉刚&#xff0c;义乌市委常委、常务副市长喻新贵为会议致辞。…

三、C#—变量,表达式,运算符(3)

&#x1f33b;&#x1f33b; 目录 一、变量1.1 变量1.2 使用变量的步骤1.3 变量的声明1.4 变量的命名规则1.5 变量的初始化1.6 变量初始化的三种方法1.7 变量的作用域1.8 变量使用实例1.9 变量常见错误 二、C#数据类型2.1 数据类型2.2 值类型2.2.1 值类型直接存储值2.2.2 简单类…

【rust/egui】(十)使用painter绘制一些图形—connections

说在前面 rust新手&#xff0c;egui没啥找到啥教程&#xff0c;这里自己记录下学习过程环境&#xff1a;windows11 22H2rust版本&#xff1a;rustc 1.71.1egui版本&#xff1a;0.22.0eframe版本&#xff1a;0.22.0上一篇&#xff1a;这里 绘制连接 在上一节我们使用painter绘制…

《深度学习初探:使用TensorFlow和Keras构建你的第一个神经网络》

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

GCP之Google Cloud Infrastructure

Google Cloud 的物理网络是如何连接的&#xff1f; Google Cloud 分为 regions&#xff0c;regions 又分为 zones。 region 是一个地理区域&#xff0c;其中一个 VM 到另一个 VM 的往返时间 &#xff08;RTT&#xff09; 通常小于 1毫秒&#xff1b;zone 是 region 中的部署区…

canvas基础笔记

一、简介 Canvas是HTML5中的一个元素&#xff0c;它提供了一个可以使用JavaScript绘制图形的区域。它提供了一个强大的绘图API&#xff0c;可以用于创建各种图形&#xff0c;包括线条、矩形、圆形、文本等 Canvas 是 HTML5 中的一个元素&#xff0c;用于绘制图形、动画和图像。…

架构核心技术之微服务架构

小熊学Java&#xff1a;https://www.javaxiaobear.cn/&#xff0c;文末有免费资源 本文我们来学习微服务的架构设计 主要包括如下内容。 单体系统的困难&#xff1a;编译部署困难、数据库连接耗尽、服务复用困难、新增业务困难。 微服务框架&#xff1a;Dubbo 和 Spring Clou…

sdkman 的安装配置与 sdk 管理

sdkman 的安装配置与 sdk 管理 记录一下项目使用的工具&#xff0c;目前环境的管理有以下几个&#xff1a; sdkmanpyenvnvm 这里主要讲一下 sdkman&#xff0c;我们项目是通过 sdkman 进行 java 和 maven 的管理&#xff0c;这个写的挺简单的&#xff0c;加上一个自己写的自…