软件安全——堆栈基础知识点总结

一、堆栈基础——内存区域

1、内存区域相关概念

内存区域:一个进程可能被分配到不同的内存区域去执行:

代码区:这个区域存储着被装入执行的二进制机器代码,处理器会到这个区域取指并执行。

数据区:用于存储全局变量等。

堆区:进程可以再堆区动态请求一定大小的内存,并在用完之后归还给堆区。动态分配和回收是堆区的特点。

栈区:用于动态地存储函数之间的调用关系,以保证被调用函数在返回时恢复到母函数中继续执行。

一个进程对这些区域进行合理利用的过程:

每个可执行文件包含了二进制级别的机器代码,将被装载到内存中的代码区;处理器(CPU)将到内存的代码区一条一条地取出指令和操作数,并送入算术逻辑单元进行运算;如果代码中请求开辟动态内容,则会在内存的堆区分配一块大小何止的区域返回给代码区的代码使用;

当函数调用发生时,函数的调用关系等信息回动态地保存在内存的栈区,以供处理器在执行完被调用函数的代码时,返回母函数。

2.栈区

栈:是向低地址扩展的数据结构,是一块连续的内存区域。栈顶(esp栈顶指针)的地址和栈的最大容量是系统预先规定好的,在windows下,栈的默认大小是2M,如果申请的空间超过栈的剩余空间时,将提示overflow(栈溢出)。

3.堆区

堆:是向高地址扩展的数据结构,是不连续的内存区域,堆的大小受限与计算机的虚拟内存。

操作系统有一个纪录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表;

操作系统分配堆区大小的操作:

第一种情况:寻找第一个空间大于所申请的堆节点,然后将该节点从空闲节点链表中删除,并将该节点的空间分配给程序。

第二种情况:由于找到的堆节点的大小不一定正好等于申请的大小,系统会自动的将多余的部分重新放入空闲链表中。

4.堆区和栈区的区别

(1)申请方式

栈:由系统自动分配。例如声明一个局部变量 int a,系统自动在栈中为a开辟空间。

堆:需要程序员自己申请。并指明大小,在c中malloc函数,如p=chr(*)malloc(10)。

(2)申请效率

栈:由系统自动分配,速度较快,但程序员是无法控制的。

堆:是由程序员分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来方便。

二、堆栈基础——函数调用

函数调用时候将借助系统栈来完成函数状态的保存和恢复。

以下是一个关于函数调用的代码:

根据上图我们可以知道,函数调用过程为:main函数->func_A()函数->func_B()函数。

1、介绍这些函数在代码区中精确的跳转实现

这些代码区中精确的跳转都是在与系统栈巧妙配合过程中完成的。

当函数被调用时,系统栈会为这个函数开辟一个新的栈帧,并将它压入栈中

栈帧的定义:**每个栈帧对应着一个未运行完的函数。栈帧中保存了该函数的返回地址和局部变量**。从逻辑上讲,栈帧就是一个函数执行的环境:函数参数、函数的局部变量、函数执行完后返回到哪里等信息。

当函数返回时,系统栈会弹出该函数所对应的栈帧

2.详细介绍以上展示代码中函数的跳转过程

当我们双击编译生成的二进制可执行文件后,可执行文件会以进程的形式执行,然后将二进制机器码存放在代码区中,接着处理器到代码区中根据对应的机器码取出数据进行计算。遇到函数调用,此时系统会自动生成一个栈区,main函数的栈帧位于栈区的顶部,因为main函数中需要调用func_A()函数,所以在main函数栈帧的顶部,生成func_A()的栈帧,**该栈帧中包含func_A的变量,返回地址等。根据展示代码内容,我们可以知道func_A()函数还调用了func_B()函数,所以同样需要在func_A()栈帧上创建func_B()函数对应的栈帧。该栈帧同样包括局部变量、返回地址等。当func_B()函数执行完成后,就会返回到func_A中继续执行。因为栈帧对应的是未运行完的函数,所以这时func_B()函数对应的栈帧弹出栈区**。同理当func_A执行结束后,从栈区中弹出func_A()函数对应的栈帧。继续到main函数中执行。

3.函数调用的步骤

(1)参数入栈:将参数从右向左一次压入系统栈中。

(2)返回地址入栈:将当前代码区调用指令的下一条指令地址压入栈中,供函数返回时继续执行。

(3)代码区跳转:处理器从当前代码区跳转到被调用函数的入口处。

(4)栈帧调整:保存当前栈帧状态值,已备后面恢复本栈帧时使用。将当前栈帧切换到新栈帧。

三、堆栈基础——常见寄存器与栈帧

1.寄存器概念

寄存器(register):是中央处理器CPU的组成部分。寄存器是有限存储容量的高数存储部件,它们可用来暂存指令、数据和地址。我们常常看到32位CPU、64位CPU这样的名称,其实指的就是寄存器的大小。32位CPU寄存器大小就是4字节。

指令寄存器:指令寄存器(extend instruction pointer),其内存放着一个指针,该指针永远指向下一条等待执行的指令地址,其作用是:EIP指向哪里,CPU就会去执行哪里的指令。

指令寄存器的实际使用:在栈帧切换的时候,将栈帧的返回地址传递给EIP寄存器,这时CPU就会跳转到返回地址处继续执行,从而完成栈帧切换。

2.栈帧与寄存器的联系

每一个函数独占自己的栈帧空间。当前正在运行的函数的栈帧总是在栈顶。win32系统提供两个特殊的寄存器用于标识位于系统栈顶端的栈帧:

ESP:栈指针寄存器(extended stack pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的栈顶。(即esp指针指向正在运行函数栈帧的栈顶)

EBP:基址指针寄存器(extended base pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的底部。(即ebp指针指向正在运行函数栈帧的底部)

3、函数栈帧定义及其内容

函数栈帧:ESP和EBP之间的内存空间为当前栈帧,EBP标识了当前栈帧的底部,ESP表示当前栈帧的顶部。

示意图如下:

函数栈帧中,一般包含以下几类重要信息:

(1)局部变量:为函数局部变量开辟的内存空间

(2)栈帧状态值:保存前栈帧的顶部和底部(实际上只保存前栈帧的底部,前栈帧的顶部可以通过栈帧平衡计算得到),用于在本栈帧弹出后,恢复出上一个栈帧。

(3)函数返回地址:保存当前函数调用前的指令位置,以便在函数返回时能够恢复到函数被调用前的代码区中继续执行指令。

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

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

相关文章

重拾C++之菜鸟刷算法第10篇---二叉树(下)

十五、合并二叉树 题目 给你两棵二叉树: root1 和 root2 。 想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是&#xff1…

【NR 定位】3GPP NR Positioning 5G定位标准解读(八)- OTDOA定位

前言 3GPP NR Positioning 5G定位标准:3GPP TS 38.305 V18 3GPP 标准网址:Directory Listing /ftp/ 【NR 定位】3GPP NR Positioning 5G定位标准解读(一)-CSDN博客 【NR 定位】3GPP NR Positioning 5G定位标准解读(…

车规芯片为什么需要信息安全(1)

目录 1.汽车出现过被黑客攻击事件吗? 2.汽车信息安全标准汇总 2.1 国际标准 2.2 国内标准 3.车规芯片的信息安全应该从什么地方考虑 3.1 芯片硬件安全防护能力 3.2 车规芯片的信息安全服务 3.3 芯片厂如何证明芯片的信息安全能力 4.小结 这个来自家里人的灵…

WebGL之创建 3D 对象

现在让我们给之前的正方形添加五个面从而可以创建一个三维的立方体。最简单的方式就是通过调用方法 gl.drawElements() 使用顶点数组列表来替换之前的通过方法gl.drawArrays() 直接使用顶点数组。而顶点数组列表里保存着将会被引用到一个个独立的顶点。 其实现在会存在这样一个…

设计模式学习系列 -- 随记

文章目录 前言 一、设计模式是什么? 二、设计模式的历史 三、为什么以及如何学习设计模式? 四、关于模式的争议 一种针对不完善编程语言的蹩脚解决方案 低效的解决方案 不当使用 五、设计模式分类 总结 前言 最近可能工作生活上的稳定慢慢感觉自己丢失…

【轮式平衡机器人】——TMS320F28069片内外设之ePWM

声明:本系列博客参考有关专业书籍,截图均为自己实操,仅供交流学习! 引入 脉冲宽度调制(PWM)是一种对模拟信号进行数字编码的方法,硬件原理是根据相应载荷的变化来调制晶体管栅极或基极的偏置&…

【c++】string模拟实现

string类的接口 namespace zjw {class string{public:typedef char* iterator;typedef const char* const_iterator;private:char* _str;int _size;int _capacity;};这里的迭代器直接使用原生指针来封装。 _str为指向string数组的首地址的指针。 _size为string数组的大小。 …

测试工具使用技巧01-->jmeter链接mysql

前言 在做接口或者性能测试的时候,有时需要jmeter连接数据库做操作,可以看看如下实例。操作实例 在mysql数据库中有如下数据表 在jmeter导入jdbc驱动插件(需要的留言找我拿) 在jmeter测试计划元件最下面,导入jdbc.…

Android平台实现无纸化同屏并推送RTMP或轻量级RTSP服务(毫秒级延迟)

技术背景 在写这篇文章之前,实际上几年之前,我们就有非常稳定的无纸化同屏的模块,本文借demo更新,算是做个新的总结,废话不多说,先看图,本文以Android平台屏幕实时采集推送,Windows…

ActiveRAG—主动学习

原文地址:ActiveRAG — Active Learning 2024 年 2 月 26 日 大型语言模型(LLM)的出现开创了对话式人工智能的新时代。这些模型可以生成非常类似人类的文本,并且比以往更好地进行对话。然而,他们仍然面临着仅仅依靠预先…

面试宝典-【redis】

目录 1.什么是缓存穿透 ? 怎么解决 ? 2.什么是布隆过滤器 3.什么是缓存击穿 ? 怎么解决 ? 4.什么是缓存雪崩 ? 怎么解决 ? 5.redis做为缓存,mysql数据如何与redis进行同步?(双写) 6.排他锁是如何保证读写、读读互斥的呢? 7.你听说过延…

【万题详解】洛谷P1616 疯狂的采药

题目背景 此题为纪念 LiYuxiang 而生。 题目描述 LiYuxiang 是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对…

什么是yocto基本组件(bitbake,recipes,classes,configuration,layer)

文章目录 1基本组件1.1 bitbake1.2 Recipes1.3 Classes1.4 Configurations2 层的理解2.1 层结构2.2 nxp yocto示例2.3 ti yocto示例1基本组件 1.1 bitbake bitbake,是OpenEmbedded构建系统的核心工具,负责解析元数据,从中生成任务列表,然后执行这些任务。bitbake是一个通…

C# LINQ运算符

LINQ运算符 1. 概述1.1 集合->集合1.1.1 筛选运算符1.1.2 映射运算符1.1.3 连接运算符1.1.4 排序运算符1.1.5 分组运算符1.1.6 集合运算符1.1.7 转换方法:Import1.1.8 转换方法:Export 1.2 集合->单个元素或标量值1.2.1 元素运算符1.2.2 聚合方法1.2.3 数量词 1.3 空->…

【MySQL 系列】MySQL 语句篇_DQL 语句

DQL(Data Query Language),即数据查询语言,用来查询数据记录。DQL 基本结构由 SELECT FROM、WHERE、JOIN 等子句构成。 DQL 语句并不会改变数据库,而是让数据库将查询结果发送结果集给客户端,返回的结果是一…

软考72-上午题-【面向对象技术2-UML】-UML中的图3

一、状态图 1-1、状态图的定义 状态图,展现了一个状态机,由:状态、转换、事件和活动组成,是系统的动态视图。 活动(动作) 可以在状态内执行也可以在状态转换(迁移) 时执行。 状态图强调:行为的事件顺序。 1-2、状态图…

SpringBoot项目如何部署到服务器

文章目录 准备:方式一:Jar包方式(推荐)部署步骤: 方式二:War包方式部署步骤: 总结 准备: 云服务器(阿里云、腾讯云等)Linux系统以及运行所需的环境 方式一&a…

力扣--深度优先算法/回溯算法216.组合总和 Ⅲ

思路分析: 深度优先搜索 (DFS): 通过递归实现,尝试从数字 1 到 9 中选择可能的数字,构建和为 n,长度为 k 的组合。递归函数 dfs: 接收参数:result 为最终结果集,path 为当前正在生成…

AWS认证:云计算领域的卓越里程碑

本文由云计算狂魔公众号提供 随着科技的飞速发展,云计算已成为企业与个人必备的技能之一。亚马逊网络服务(Amazon Web Services,简称AWS)作为全球领先的云计算服务提供商,其认证体系无疑是云计算领域的卓越里程碑。本…

【C++】二叉树进阶之二叉搜索树

> 作者简介:დ旧言~,目前大二,现在学习Java,c,c,Python等 > 座右铭:松树千年终是朽,槿花一日自为荣。 > 目标:熟练掌握二叉搜索树,能自己模拟实现二…