从汇编代码理解数组越界访问漏洞
数组越界访问漏洞是 C/C++ 语言中常见的缺陷,它发生在程序尝试访问数组元素时未正确验证索引是否在有效范围内。通常情况下,数组的索引从0开始,到数组长度减1结束。如果程序尝试访问小于0或大于等于数组长度的索引位置,就会导致数组越界访问。由于 C/C++ 没有对数组做边界检查,不检查下标是否越界可以提升程序运行的效率,导致在程序编译过程中它并不定会造成编译错误。攻击者可以利用数组越界访问漏洞来读取或修改程序内存中的数据,甚至执行恶意代码。这种漏洞可能会导致程序崩溃、拒绝服务,或者泄露敏感信息。因此,在开发软件时,应该确保对数组访问进行边界检查,以防止发生这种类型的漏洞。
一、漏洞代码示例
首先展示一个包含数组越界访问漏洞的代码:
#include<stdio.h>
int main(){int a[7]={0,1,2,3,4,5,6};for(int i=0;i<=7;i++){a[i]=0;printf("This is a test!\n");}return 0;
}
可以很容易看出,数组的长度为7,下标只能取到6,而在代码的第4行for循环的终止条件却为 i<=7,导致在第6行会执行一个"a[7]=0"的赋值操作,出现数组越界问题。
我们编译并执行上述代码,发现居然成功通过编译,没有任何报错!但是陷入了死循环,并输出了满屏的"This is a test!"。

上述代码中的数组越界访问导致程序陷入死循环,那么为什么会出现这种现象呢?
二、汇编代码分析
我们通过 Compiler Explorer 将上述程序处理为 intel 风格的x86_64汇编代码看看:

下面我们来分析上述汇编代码。
- 4-6行:常规的栈帧初始化,这里不做赘述。
- 7-14行:栈顶指针(rsp)减32字节,为数组及变量开辟空间,接着分别赋入 a[0] - a[6] 以及变量 i 的值。
- 15行:跳转至L2段。
- 24-25行:比较(cmp)指针[rbp-4]处存放的值(变量i的值)与7的大小,如果小于或等于则跳转到L3段(jle,jump when less or equal)。
- 17行:取出指针指向[rbp-4]位置的值,存入寄存器eax中。
- 18行:执行cdqe指令,将32位寄存器eax扩展为64位寄存器rax。
- 19行:到了导致数组越界的关键地方,在这里将0赋值给了[rbp-32+rax*4],我们假设某个时刻rax(存放变量i的寄存器)为7(即下标已经越界),此时,[rbp-32+rax*4] = [rbp-4] = i = 0(如14行)。也就是说,每当i=7时,在源代码第6行a[i]=0处会再次将0赋值给i,就导致for循环中 i=7 -> i=0,最终产生死循环。
小结一下,导致死循环的根本原因是数组赋值语句a[i]=0非法篡改了i的值。假设这里我们将a[i]=0更改为a[i]=7,此时[rbp-32+rax*4]= [rbp-4] = i = 7,程序依然可以正常执行。

三、进一步分析
这里我们更改一下示例代码为:
#include<stdio.h>
void func1()
{long a[2]={0,1};a[3] = 0;a[4] = 0;
}void func2()
{printf("func2 excuted!");
}int main(){func1();printf("No error!");return 0;
}
执行上述代码,会出现异常:

因为在函数func1栈的高地址位存放了其返回地址,当该函数执行完后,cpu依据这个地址信息回到main函数中继续执行后续代码,而第5行a[3]=0处,将数值0覆盖了该返回地址,因此导致程序异常。根据上述逻辑,如果我们将a[3]指向函数func1的返回地址,理论上程序应该也可以正常执行。
同样地,通过Compiler Explorer得到该程序的汇编代码:

将a[3]指向函数func1的返回地址,即修改 a[3]=0 为 a[3]=0x401171,再次执行程序,可以正常得到输出结果:

另外,我们还可以做如下修改:
- a[3]=0x401151;
- a[4]=0x401171;
将数组a指向函数func2的初始化地址,让func1调用并执行func2函数。执行程序,得到如下输出结果:(成功调用了函数func2)。

四、总结
根据上述示例可以发现,通过数组越界来覆盖函数的返回地址可以更改程序的执行流程。同样地,攻击者可以填写存放恶意代码的地址,从而引导函数func1去执行该恶意代码。因此,在编写代码中对数组做边界检查尤为重要。
参考
[1] [汇编杂项]关于_高级语言中 数组越界与汇编中 栈溢出的_联系的思考 - SachieW - 博客园 (cnblogs.com)
[2] 通过查看汇编理解数组越界 - 知乎 (zhihu.com)
[3] CPU眼里的:数组越界 | 堆栈溢出_哔哩哔哩_bilibili
相关文章:
从汇编代码理解数组越界访问漏洞
数组越界访问漏洞是 C/C 语言中常见的缺陷,它发生在程序尝试访问数组元素时未正确验证索引是否在有效范围内。通常情况下,数组的索引从0开始,到数组长度减1结束。如果程序尝试访问小于0或大于等于数组长度的索引位置,就会导致数组…...
skynet 使用protobuf
一、安装protobuf 下面的操作方法都是在 centos 环境下操作 #下载 Protocol Buffers 源代码: #您可以从 Protocol Buffers 的 GitHub 仓库中获取特定版本的源代码。使用以下命令克隆仓库 git clone -b v3.20.3 https://github.com/protocolbuffers/protobuf.git#编译…...
Vue Router 4 与 Router 3 路由配置与区别
文章目录 路由安装路由配置vue-router 3.x版本写法配置路由使用路由 vue-router 4.x版本写法配置路由使用路由 Vue Router 4 与 Vue Router 3 区别 路由安装 Vue 2 (使用 Vue Router 3) :npm install vue-router3 Vue 3 (使用 Vue Router 4) :npm insta…...
python借助elasticsearch实现标签匹配计数
给定一组标签 [{“tag_id”: “1”, “value”: “西瓜”}, {“tag_id”: “1”, “value”: “苹果”}],我想精准匹配到现有的标签库中存在的标签并记录匹配成功的数量。 标签id(tag_id)标签名(tag_name)标签值(tag_name )1水果西瓜1水果苹果1水果橙子2动物老虎 …...
Yolo-world+Python-OpenCV之摄像头视频实时目标检测
上一次介绍了如何使用最基本的 Yolo-word来做检测,现在我们在加opencv来做个实时检测的例子 基本思路 1、读取离线视频流 2、将视频帧给yolo识别 3、根据识别结果 对视频进行绘制边框、加文字之类的 完整代码如下: import datetimefrom ultralytics …...
vue-treeselect 的基本使用
vue-treeselect 的基本使用 1. 效果展示2. 安装 插件3. 引入组件4. 代码 1. 效果展示 2. 安装 插件 vue-treeselect是一个树形的下拉菜单,至于到底有多少节点那就要看你的数据源有多少层了,挺方便的。下面这个这个不用多说吧,下载依赖 npm in…...
Vue(二)
文章目录 1.条件渲染1.关于js中的false的判定2.基本介绍3.v-if1.需求分析2.代码实例 4.v-show实现5.v-if与v-show比较6.课后练习 2.列表渲染1.代码实例2.课后练习 3.组件化编程1.基本介绍2.实现方式一_普通方式2.实现方式二_全局组件方式3.实现方式三_局部组件方式 4.生命周期和…...
Python基于深度学习的车辆特征分析系统
博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…...
推理还原的干货
故事的递进还原 从下层故事到上层故事 设定还原 还原的逻辑 隐藏信息拼凑、因果导致果推因、规则还原现象 设计思路: 真解答 真解答的关键信息 推理逻辑链 哪些环节可以被误导 如何把关键信息变成伪解答 解释变形信息 给出识别变形信息的方法或线索 其实看似一个…...
【Redis 神秘大陆】006 灾备方案
六、Redis 灾备方案 6.1 存储方案 6.1.1 基础对比 RDB持久化AOF持久化原理周期性fork子进程生成持久化文件每次写入记录命令日志文件类型二进制dump快照文件文本appendonly日志文件触发条件默认超过300s间隔且有1s内超过1kb数据变更永久性每秒fsync一次文件位置配置文件中指…...
【Java基础】17.异常处理
文章目录 前言一、异常的概念1.异常的3种类型2.支持异常处理的关键字和类 二、Exception 类的层次三、内置异常类1.非检查性异常2.检查性异常类 四、异常处理1.捕获异常2.多重捕获块3.throws/throw 关键字1.throw 关键字2.throws 关键字 3.finally关键字 五、编译时异常处理方式…...
【python】flask结合SQLAlchemy,在视图函数中实现对数据库的增删改查
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…...
APIGateway的认证
APIGateway的支持的认证如下: 我们从表格中可以看到,HTTP API 不支持资源策略的功能,另外是通过JWT的方式集成Cognito的。 对于REST API则是没有显示说明支持JWT认证,这个我们可以通过Lambda 自定义的方式来实现。 所以按照这个…...
MacOS Github Push项目 精简版步骤
大白菜教程:小白菜 macOS github提交代码-CSDN博客 步骤1:git init步骤2: touch .gitignore 创建ignore文件 open .gitignore 打开ignore文件 编写ignore文件.idea/ 是文件夹的意思.git/ 也是自动生成的文件夹 也不上传.DS_St…...
Eclipse的基本使用讲解(建项目,建包,建类,写代码(基本语法))新手入门必备
目录 一.介绍eclipse 二.操作Eclipse 1.选择工作空间 2.建项目,建包,建类 1.建项目(两种) 2.建包 3.建类 三.写代码(基本语法) 1.代码操作 2.代码规范 3.代码注释 一.介绍eclipse Eclipse 是一个开放源代码的、基于Java的可扩展开发平台。就其…...
3D模型处理的并行化
今天我们将讨论如何使用 Python 多进程来处理大量3D数据。 我将讲述一些可能在手册中找到的一般信息,并分享我发现的一些小技巧,例如将 tqdm 与多处理 imap 结合使用以及并行处理存档。 那么我们为什么要诉诸并行计算呢? 使用数据有时会出现…...
盲人安全导航技巧:科技赋能让出行更自如
作为一名资深记者,长期关注并报道无障碍领域的发展动态。今日,我将聚焦盲人安全导航技巧,探讨这一主题下科技如何赋能视障人士实现更为安全、独立的出行。一款融合了实时避障、拍照识别物体及场景功能的盲人出行辅助应用叫做蝙蝠避障…...
问,由于java存在性能上,以及部分功能上的缺点,请问如何正确使用C,C++,Go,这三个语言,提升Java Web项目的性能?
拓展阅读:版本任你发,我用java8 我明白Java虽然在许多方面表现出色,但在某些特定场景下可能会遇到性能瓶颈或功能限制。为了提升Java Web项目的性能,可以考虑将C、C和Go这三种语言用于特定的组件或服务。以下是如何正确使用这些语…...
【信号与系统 - 9】傅里叶变换的性质习题
1 习题 已知 f ( t ) f(t) f(t) 的傅里叶变换为 F ( j w ) F(jw) F(jw) ,求如下信号的傅里叶变换 (1) t ⋅ f ( 3 t ) t\cdot f(3t) t⋅f(3t) 解: f ( 3 t ) ↔ 1 3 F ( j w 3 ) f(3t)\leftrightarrow \frac{1}{3}F(j\frac{w}…...
C#探索之路基础夯实篇(5):语法糖概念解析
C#探索之路基础夯实篇(5):语法糖概念解析 文章目录 C#探索之路基础夯实篇(5):语法糖概念解析1、概念定义2、Lua中的语法糖3、C#中的语法糖4、C中的语法糖5、优缺点辨析6、适用范围7、总结 从之前一开始接触lua的时候开始,开始第一次接触到语法…...
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...
从面试角度回答Android中ContentProvider启动原理
Android中ContentProvider原理的面试角度解析,分为已启动和未启动两种场景: 一、ContentProvider已启动的情况 1. 核心流程 触发条件:当其他组件(如Activity、Service)通过ContentR…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...
