内存管理之:内存空间分布和栈攻击(黑客常用攻击手段)
目录
C语言内存管理及栈攻击
内存管理
Linux虚拟内存空间分布(重要)
栈溢出(栈攻击)
堆栈的特点
栈攻击
栈攻击的实现
原理
编译器选项
实现案例
linux修改栈空间大小方式
内存泄漏
如何避免野指针?
如何杜绝忘记释放内存?(分析诊断工具valgrind)
内存泄漏总结
C语言内存管理及栈攻击
内存管理
Linux虚拟内存空间分布(重要)
(1)bss段存放初始化的变量:
- 1.未初始化的全局变量和静态局部变量
- 初始值为0的全局变量和静态局部变量(依赖于编译器实现)
(2).data数据段存放初始化的变量:
数据段通常用于存放程序中已初始化且初值不为0的全局变量、静态全局变量和静态局部变量。数据段属于静态内存分配(静态存储区),可读可写。其中有一个.rodata段,一般用于存放常量字符串和只读变量。
(3).text(代码段)
可执行文件加载到内存中的只有数据和指令之分,而指令被存放在.text段中,一般是共享的,编译时确定,只读,不允许修改
(4).heap(堆)
用于存放进程运行时动态分配的内存,可动态扩张或缩减,这块内存由程序员自己管理,通过malloc/new可以申请内存,free/delete用来释放内存,heap的地址从低向高扩展,是不连续的空间
(5).stack(栈)
记录函数调用过程相关的维护性信息,栈的地址一般从高地址向低地址扩展,是连续的内存区域
(6)共享库(libc.so)
静态链接库和动态链接库的区别:
- 不同操作系统下后缀不一样
| windows | linux | |
| 静态库 | .lib | .a |
| 动态/共享库 | .dll | .so |
- 加载方法的时间点不同
*.a 在程序生成链接的时候已经包含(拷贝)进来了
*.so 程序在运行的时候才加载使用
- 静态库把包含调用函数的库是一次性全部加载进去的,动态库是在运行的时候,把用到的函数的定义加载进去,所以包含静态库的程序所以用静态库编译的文件比较大,如果静态库改变了,程序得重新编译,相反的,动态库编译的可执行文件较小,但.so改变了,不影响程序,动态库的开发很方便
- 程序对静态库没有依赖性,对动态库有依赖性。

栈溢出(栈攻击)
堆栈的特点
- 栈增长方向(现在的内核):高地址->低地址
- 函数调用栈的示意图

栈攻击
在旧版本的内核,栈空间是向下增长的由于栈空间后面紧挨着内核空间,所有一旦栈溢出,就会对内核空间进行非法访问,这样就是所谓的栈攻击(黑客常用攻击手段)

因此Linux内核在2.0升级维护的时候,在系统内核和栈之间增加了一个保护区,大概2M。作用是一旦栈溢出到了保护区,系统就自动报错(栈溢出错误)
还要一种做法,就是改变栈的增长方向,改为向下增长(Linux内核5.0的做法)。

栈攻击的实现
原理
如果忘了压栈的具体过程,可参考:
C/C++函数调用的压栈模型

当函数从入口函数main函数开始执行时,编译器会将我们操作系统的运行状态,main函数的返回地址、main的参数、main函数中的变量、进行依次压栈;当main函数开始调用func1()函数时,编译器此时会将main函数的运行状态进行压栈,再将func1()函数的返回地址、func1函数的参数、func1定义变量依次压栈;当func1调用func2的时候,编译器此时会将func2函数的运行状态进行压栈,再将func2函数的返回地址、func2函数的参数、func2定义变量依次压栈。
以向上增长的栈为例:
我们可以很容易的想到一种攻击方式,比如我们想要获取func2的使用权,我们可以在func1中使用一个数组,通过增加数组的大小,让它能够触及的地址一直增加,最终就能够越界获取到func2的入口地址,这样就能够获取到func2的使用权限
编译器选项
gcc C文件名 -z execstack -fno-stack-protector
-z execstack开启堆栈可执行机制
-fno-stack-protector关闭堆栈保护机制
实现案例
(这个实例的实现过程其实还是不太明白:已解决!!!见后面)
如图所示,我们定义了两个函数,func1中定义了一个数组,通过赋值传入func2的函数名(即函数的入口地址)给数组成员(注意这里传入的不是func2(),不是调用func2函数);在func2中打印了一句话。最终我们在main函数中调用func1函数


通过逐渐增加数组a[3]=func2中数组成员的下标,最终在a[6]的时候,成功获取使用权

但通过在func1最后加了个while(1),发现func1退出不了,func2就不会被调用,所以最后得出结论:应该是func1的函数返回地址刚好是func2的入口地址

该问题已被我发布在CSDN,可以参考如下:没有被调用的函数其代码为什么会被执行?_xyz-x的博客-CSDN博客
(2023年9月3日)该问题已解决:

结合GPT的回答,可以总结出实现的原理是:
函数的定义通常存放在代码段中,而不是栈中。在程序运行时,代码段是用来存储程序的指令的内存区域,它通常是只读的。函数的定义在编译时就确定了,并且存放在代码段中,以便在程序执行过程中被调用和执行。栈则是用于存放局部变量、函数参数和临时数据等的内存区域,它在函数调用时动态分配和释放,具有先进后出的特性。
所以func1和func2的入口地址和返回地址在编译时已经确定好了,在代码段中。
func1函数中的数组越界操作a[6] = func2。因为在func1函数的栈帧上,局部变量a的下标为 6 的位置处超过了a的实际长度(大小为 4),所以会覆盖到func1函数的返回地址。
因此,func2函数的入口地址被写入到了func1函数的返回地址位置上。当func1函数执行完毕并返回时,CPU会根据返回地址跳转到该地址对应的代码,从而执行了func2函数。
linux修改栈空间大小方式

由于线程使用的线程函数,因此栈空间越大,就能支持越多的线程,常用于网络编程中一个服务类连接更多的客户端
对于堆空间的大小,一般是在创建系统时候决定,堆空间一旦被分配完,如通过malloc或者new的方式再次申请空间就会一直失败。
内存泄漏
内存泄漏有三种情况:越界访问、野指针和内存忘记释放
如何避免野指针?
明确指针的指向
如何杜绝忘记释放内存?(分析诊断工具valgrind)
人无完人,我们人是不可能完全记得释放自己开辟的内存的,尤其在进行大型项目开发时,往往会产生疏忽,因此可以通过内存检测分析工具在写完程序之后进行诊断分析
推荐使用内存分析诊断工具valgrind
安装和使用可参考:linux代码检测工具valgrind之内存检测memcheck_linux代码检查工具_夜雨听萧瑟的博客-CSDN博客
使用时,在编译完程序,使用命令valgrind --tool=memcheck --leak-check=full ./test即可
内存泄漏总结
C语言没有更好的方法杜绝malloc的导致的内存泄漏
相关文章:
内存管理之:内存空间分布和栈攻击(黑客常用攻击手段)
目录 C语言内存管理及栈攻击 内存管理 Linux虚拟内存空间分布(重要) 栈溢出(栈攻击) 堆栈的特点 栈攻击 栈攻击的实现 原理 编译器选项 实现案例 linux修改栈空间大小方式 内存泄漏 如何避免野指针? 如何…...
一米facebook功能点
用户信息批量修改 可批量修改已登录用户的头像、密码、个人说明等信息。 小号批量刷赞、评论 可以批量用facebook小号给帖子、主页等刷赞或评论。 直播帖刷人气/评论/分享 可以直接刷直播帖子的人气、评论,并可一键分享到小组或个人时间线、公共主页等。 小组成员…...
uni-app:监听数据变化(watch监听、@input事件)
方法一:文本框监听,使用input事件 <template><view><input type"text" v-model"wip_entity_name" input"handleInputChange" /></view> </template><script> export default {data() {return {…...
提升C语言的方法?
我个人的习惯,学一门新的编程语言一定是需要目的的。 也就是学这个语言是干什么? 单纯的上学学习C语言一般都是工科的专业作为专业课而开设的学科,这种很多都是使用谭浩强的教材,很多同学也基本没听,所以学习效果也是…...
WPF_布局基础
布局容器 Grid 定义由列和行组成的灵活的网格区域。 行 <Grid.RowDefinitions><RowDefinition/><RowDefinition/></Grid.RowDefinitions> 列 <Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition/></Grid.ColumnDe…...
【SA8295P 源码分析】87 - SA8295P HQNX + Android 编译环境搭建指导
【SA8295P 源码分析】87 - SA8295P HQNX + Android 编译环境搭建指导 一、Android 编译环境搭建:Android + sa8295p-hqx-4-2-4-0_hlos_dev_la.tar.gz1.1 更新 Ubuntu 18.04 源路径1.2 安装基础编译环境1.3 设置JDK8 的环境变量1.4 配置sh为bash(默认为dash)1.5 Android 编译…...
java基础-----第九篇
系列文章目录 文章目录 系列文章目录前言一、GC如何判断对象可以被回收前言 一、GC如何判断对象可以被回收 引用计数法:每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计 数为0时可以回收, 可达性分析法:从 GC Roots 开始向下搜索,搜索所走过的…...
数学建模--整数规划匈牙利算法的Python实现
目录 1.算法流程简介 2.算法核心代码 3.算法效果展示 1.算法流程简介 #整数规划模型--匈牙利算法求解 """ 整数规划模型及概念:规划问题的数学模型一般由三个因素构成 决策变量 目标函数 约束条件;线性规划即以线性函数为目标函数&a…...
OpenCV(十三):图像中绘制直线、圆形、椭圆形、矩形、多边形和文字
目录 1.绘制直线line() 2.绘制圆形circle() 3.绘制椭圆形ellipse() 4.绘制矩形rectangle() 5.绘制多边形 fillPoly() 6.绘制文字putText() 7.例子 1.绘制直线line() CV_EXPORTS_W void line(InputOutputArray img,Point pt1, Point pt2,const Scalar& color,int t…...
[华为云云服务器评测] Unbutnu添加SSH Key、编译启动Springboot项目
系列文章目录 第一章 [linux实战] 华为云耀云服务器L实例 Java、node环境配置 第二章 [linux实战] Unbutnu添加SSH Key、启动Springboot项目 文章目录 系列文章目录前言一、任务拆解二、配置git,添加SSH Key2.1、登录远程主机2.2、配置git用户名和邮箱2.3、生成SSH key2.4、查…...
【MySQL学习笔记】(七)内置函数
内置函数 日期函数示例案例-1案例-2 字符串函数示例 数学函数其他函数 日期函数 示例 获得当前年月日 mysql> select current_date(); ---------------- | current_date() | ---------------- | 2023-09-03 | ---------------- 1 row in set (0.00 sec)获得当前时分秒…...
《Python魔法大冒险》004第一个魔法程序
在图书馆的一个安静的角落,魔法师和小鱼坐在一张巨大的桌子前。桌子上摆放着那台神秘的笔记本电脑。 魔法师: 小鱼,你已经学会了如何安装魔法解释器和代码编辑器。是时候开始编写你的第一个Python魔法程序了! 小鱼:(兴奋地两眼放光)我准备好了! 魔法师: 不用担心,…...
架构,平台,框架的区别和联系
1、解释说明 - 架构:在软件开发中,架构是指软件的整体设计和组织方式。它包括了软件的结构、组件和交互方式等方面的设计。架构定义了系统的高级结构和组织方式,以及各个组件之间的关系和交互方式。一个良好的架构可以提高软件的可维护性、可…...
Mac 安装php多版本,brew安装php8.0
因为需要我要在mac上装两个php版本,先前我已经装过php7.4,下面我们逐步安装php8.0 开始安装8.0: 直接运行安装 brew install php8.0 遇到问题怀疑是仓库太老了,更新一下homebrew ,重新安装 brew update 安装成功了,不过看了下版本好像不能正…...
【100天精通Python】Day53:Python 数据分析_NumPy数据操作和分析进阶
目录 1. 广播 2 文件输入和输出 3 随机数生成 4 线性代数操作 5 进阶操作 6 数据分析示例 1. 广播 广播是NumPy中的一种机制,用于在不同形状的数组之间执行元素级操作,使它们具有兼容的形状。广播允许你在不显式复制数据的情况下,对不同…...
druid连接不上doris有哪些可能原因
如果你在使用Druid连接池连接Doris时遇到问题,无法连接上数据库,可能有以下几个原因和解决方案: 网络配置问题:确保你的应用程序能够与Doris数据库所在的服务器进行通信。检查防火墙设置、网络配置以及Doris数据库的监听端口是否…...
双边滤波 Bilateral Filtering
本文是对图像去噪领域经典的双边滤波法的一个简要介绍与总结,论文链接如下: https://users.soe.ucsc.edu/~manduchi/Papers/ICCV98.pdf 1.前言引入 对一副原始灰度图像,我们将它建模为一张二维矩阵u,每个元素称为一个像素pixel&am…...
PXE批量装机
目录 前言 一、交互式 (一)、搭建环境 (二)、配置dhcp服务 (三)、FTP服务 (四)、配置TFTP服务 (五)、准备pxelinx.0文件、引导文件、内核文件 &#…...
Linux--VMware的安装和Centos
一、VMware和Linux的关系 二、VMware的安装 VM_ware桌面虚拟机 最新中文版 软件下载 (weizhen66.cn) VMware-Workstation-Lite-16.2.2-19200509-精简安装注册版.7z - 蓝奏云 如果安装不成功,则设置BIOS 三、在VMware中加入Centos 下载地址: CentOS-…...
dji uav建图导航系列()ROS中创建dji_sdk节点包(一)项目结构
文章目录 1、整体项目结构1.1、 目录launch1.2、文件CMakeLists.txt1.3、文件package.xml1.4、目录include1.4、目录srv在ROS框架下创建一个无人机的节点dji_sdk,实现必需的订阅(控制指令)、发布(无人机里程计)、服务(无人机起飞降落、控制权得很)功能,就能实现一个类似…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
深度学习水论文:mamba+图像增强
🧀当前视觉领域对高效长序列建模需求激增,对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模,以及动态计算优势,在图像质量提升和细节恢复方面有难以替代的作用。 🧀因此短时间内,就有不…...
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...
Axure 下拉框联动
实现选省、选完省之后选对应省份下的市区...
Matlab实现任意伪彩色图像可视化显示
Matlab实现任意伪彩色图像可视化显示 1、灰度原始图像2、RGB彩色原始图像 在科研研究中,如何展示好看的实验结果图像非常重要!!! 1、灰度原始图像 灰度图像每个像素点只有一个数值,代表该点的亮度(或…...
