栈溢出示例

(信息安全概论作业)缓冲区溢出问题—C语言—溢出攻击 下图a为一段C语言源程序,其中,编译器为变量分配4个字节空间,为 buffer变量分配8个字节空间。程序执行完图中所标记的“strcpy(buffer,password);”语句时,堆栈的布局如下图b所示(注意:低字节数据保存在低地址,例如字符串“1234”存储状态为“0x34333231”)。图 a 验证口令演示程序图 b 调用 valid_flag 子程序时的堆栈布局请分析程序及堆栈特征,回答如下问题:(信息安全概论)(#C)(缓冲区溢出)(溢出攻击) 阅读详情

一、提出问题

    还是先看一段代码:

#include <stdio.h>

#include <stdlib.h>

//Have we invoked this function?
    void why_here(void)

{

    printf("why u r here?!\n");

    exit(0);

}

int main(int argc, char * argv[])

{

    int buff[1];

    buff[2] = (int)why_here;

    return 0;

}

这段代码的运行结果很奇怪,输出 “why u r here?”

很显然,why_here方法没有被调用过,但是为什么会被执行呢?因为不是程序在显式地调用它,而是被操作系统调用了!

具体原因要从内存分配开始讲起……

 

二、C/C++内存分配

此部分内容转自:http://blogold.chinaunix.net/u2/67530/showart_601293.html

在C 中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。

栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区。里面的变量通常是局部变量、函数参数等。 

堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。 

自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。 

全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C 里面没有这个区分了,他们共同占用同一块内存区。 

常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改

明确区分堆与栈 

在bbs上,堆与栈的区分问题,似乎是一个永恒的话题,由此可见,初学者对此往往是混淆不清的,所以我决定拿他第一个开刀。

首先,我们举一个例子: 

void f() { int* p=new int[5]; } 

这条短短的一句话就包含了堆与栈,看到new,我们首先就应该想到,我们分配了一块堆内存,那么指针p呢?他分配的是一块栈内存,所以这句话的意思就是:在栈内存中存放了一个指向一块堆内存的指针p。在程序会先确定在堆中分配内存的大小,然后调用operator new分配内存,然后返回这块内存的首地址,放入栈中,他在VC6下的汇编代码如下: 

00401028 push 14h 

0040102A call operator new (00401060) 

0040102F add esp,4 

00401032 mov dword ptr [ebp-8],eax 

00401035 mov eax,dword ptr [ebp-8] 

00401038 mov dword ptr [ebp-4],eax 

这里,我们为了简单并没有释放内存,那么该怎么去释放呢?是delete p么?澳,错了,应该是delete []p,这是为了告诉编译器:我删除的是一个数组,VC6就会根据相应的Cookie信息去进行释放内存的工作。 

好了,我们回到我们的主题:堆和栈究竟有什么区别? 

主要的区别由以下几点: 

  1、管理方式不同; 

  2、空间大小不同; 

  3、能否产生碎片不同; 

  4、生长方向不同; 

  5、分配方式不同;

  6、分配效率不同; 

管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生memory leak。 

空间大小:一般来讲在32位系统下,堆内存可以达到4G的空间,从这个角度来看堆内存几乎是没有什么限制的。但是对于栈来讲,一般都是有一定的空间大小的,例如,在VC6下面,默认的栈空间大小是1M(好像是,记不清楚了)。当然,我们可以修改: 

打开工程,依次操作菜单如下:Project->Setting->Link,在Category 中选中Output,然后在Reserve中设定堆栈的最大值和commit。 

注意:reserve最小值为4Byte;commit是保留在虚拟内存的页文件里面,它设置的较大会使栈开辟较大的值,可能增加内存的开销和启动时间。 

碎片问题:对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间弹出,在他弹出之前,在他上面的后进的栈内容已经被弹出,详细的可以参考数据结构,这里我们就不再一一讨论了。

生长方向:对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向;对于栈来讲,它的生长方向是向下的,是向着内存地址减小的方向增长。 

分配方式:堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由alloca函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放,无需我们手工实现。 

分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++ 函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。

从这里我们可以看到,堆和栈相比,由于大量new/delete的使用,容易造成大量的内存碎片;由于没有专门的系统支持,效率很低;由于可能引发用户态和核心态的切换,内存的申请,代价变得更加昂贵。所以栈在程序中是应用最广泛的,就算是函数的调用也利用栈去完成,函数调用过程中的参数,返回地址,EBP和局部变量都采用栈的方式存放。所以,我们推荐大家尽量用栈,而不是用堆。 

虽然栈有如此众多的好处,但是由于和堆相比不是那么灵活,有时候分配大量的内存空间,还是用堆好一些。 

无论是堆还是栈,都要防止越界现象的发生(除非你是故意使其越界),因为越界的结果要么是程序崩溃,要么是摧毁程序的堆、栈结构,产生以想不到的结果,就算是在你的程序运行过程中,没有发生上面的问题,你还是要小心,说不定什么时候就崩掉,那时候debug可是相当困难的:)

windbg - 调试栈溢出及一个崩溃示例 栈溢出 程序崩溃,调试显示栈溢出 c0000409 (Security check failure or stack buffer overrun) 系统在此应用程序中检测到基于堆栈的缓冲区溢出。此超限可能会允许恶意用户控制此应用程序。 EXCEPTION_RECORD: (.exr -1) ExceptionAddress: 08f276bd (nvoglv32!vk_optimusGetInstanceProcAddr+0x000c549d) ExceptionCode: c00004 阅读详情

相关推荐

Java堆、栈溢出程序示例

原文地址:http://www.cnblogs.com/panxuejun/p/5882424.html 堆溢出: /** * @author LXA * 堆溢出 */ public class Heap { public static void main(String[] args) { ArrayList list=new A

杨春建的博客 1110

最最最经典的栈溢出攻击,C++,C语言适用,超级详细,干货

常用的汇编指令 call Lea push pop mov 这些请先去自行了解再来看这个文章。

2203_75284620的博客 931

AnyLogic 建立谢林模型

AnyLogic 建立谢林模型说明创建一个新模型创建代理人群体和离散空间双击 people 前的图标,编辑 Person设置 Agent 的形状(Person)在模型中启用离散时间,实现代理行为点击 Person,进行编辑点击运行按钮效果图 说明 我们将把 Schelling 的模型实现为一个基于离散空间/离散时间的代理模型。空间代表一个城市,每个单元格代表一个房子。 agent 是人,是两种颜色:黄色和红色。 最初,人是随机分布在城市中的。人比房子少,所以总是有一个人可能会移动。 这个模型中的 agent

qq_45642410的博客 2577

栈溢出攻击

本文的实验来源于《Computer Systems A Programmer's Perspective》(深入理解计算机系统》一书中第三章的一个实验。      作者给出了一个含有缓冲区溢出的程序bufbomb.c,你需要做的,就是注入给缓冲区些特殊的数据,到底利用缓冲区的目的。 //bufbomb.c /* Bomb program that is solved using a b

lpmygod的专栏 4364

基于单片机自行车码表控制系统设计

*单片机设计介绍,基于单片机自行车码表控制系统设计。

QQ2193276455的博客 1487

C# 死锁:原理、诊断与解决方案深度解析

本文深入探讨了C#中的死锁问题,详细介绍了死锁的基本概念、形成机制、常见场景、诊断方法及解决方案。死锁通常发生在多线程环境下,当多个线程因争夺资源而互相等待时,导致程序无法继续执行。文章通过代码示例展示了常见的死锁场景,如锁的嵌套、同步上下文死锁和线程池死锁,并提供了使用Visual Studio、WinDbg等工具进行死锁诊断的方法。此外,文章还提出了多种预防和解决死锁的策略,包括保持锁顺序一致性、使用锁超时机制、避免同步阻塞异步代码以及使用更高级的同步原语。通过这些方法,开发者可以有效减少死锁的发生,提

记录学习的过程 1407

c++堆栈溢出怎么解决_Windows漏洞利用开发 – 第2部分:栈溢出简介

概观欢迎来到我的Windows漏洞利用开发系列的第2部分。在第一篇文章中,我介绍了一些基本概念,在继续第2部分及其后续部分应该掌握这些基本概念。如果你还没有这样做,我建议看看第一篇文章,以确保你牢牢掌握所有提出的概念。基于这些知识,我现在想讨论一个基于Windows的软件漏洞:基于栈的缓冲区溢出。基于堆栈的缓冲区溢出简介在这一期中,我将以维基百科的简单程序开始:在第1部分中,我提到了将大于11个字...

weixin_40005542的博客 940

Arm Neoverse CMN-700 SLC内存系统与缓存分区技术解析

现代处理器架构中,缓存一致性协议与内存子系统设计直接影响系统性能。Arm Neoverse CMN-700采用的SLC(System Level Cache)通过16-way组相联设计实现高效数据缓存,其物理地址索引机制支持灵活的way分区配置。在软件可配置内存(OCM)模式下,SLC可作为独立内存空间使用,通过寄存器控制实现模式切换与区域锁定。缓存分区技术则通过请求源分类和way-based分配策略,满足实时性任务与吞吐量场景的不同需求。这些技术在5G基站、边缘计算等低延迟场景中具有重要应用价值,特别是C

weixin_30263073的博客 611

c++堆栈溢出怎么解决_栈溢出基础

一. 基础知识什么是缓冲区溢出在深入探讨技术之前, 让我们先了解一下缓冲区溢出的实际内容.想象一个非常简单的程序, 要求你输入你的用户名, 然后返回到它在做什么.从视觉上看, 如下所示注意到括号之间的空格是输入用户名的预期空间.那个空间是我们的缓冲.处理用户名后, 返回地址将告知程序需要执行的下一个指令.现在, 如果我们不仅输入用户名, 而且添加其他数据以溢出此缓冲区空间, 会发生什么情况?不仅如...

weixin_39610422的博客 3591

TPAMI 2025新作LRFormer复现笔记:我的Windows 11 + RTX 4090配置全流程

本文详细记录了在Windows 11系统下使用RTX 4090显卡复现TPAMI 2025顶会论文LRTransformer的完整流程,包括硬件配置、系统优化、Python环境搭建及模型训练中的常见问题解决方案。特别针对Windows平台特有的路径管理、CUDA版本冲突和显存优化等关键技术细节提供了实用指南,帮助开发者高效完成环境搭建和模型训练。

weixin_29094301的博客 411

智慧矿山无人机空地一体化解决方案

未来,随着技术的不断进步和应用场景的不断拓展,智慧矿山无人机空地一体化解决方案将在矿业领域发挥更加重要的作用,为矿山的可持续发展提供更加有力的保障。该系统能够实现矿山的全方位、全天候监测与管理,提升矿山生产效率,降低安全风险,并为矿山的可持续发展提供有力支持。智慧矿山无人机空地一体化解决方案是当前矿业领域技术创新的重要方向,旨在通过集成无人机技术、物联网、大数据、人工智能等先进技术,实现矿山的智能化、高效化和安全化运营。在矿山爆破、挖掘等危险作业中,无人机可进行远程监控和指挥,降低人员安全风险。

专注多旋翼、复合翼无人机技术研究,从事低空经济行业。 1109

一个栈溢出C++示例

本文主要演示、分析、测试函数内变量越界的问题,即栈溢出。

李迟的专栏 1300

XYC Q8开源掌机刷第三方系统教程

分区结束后直接将各种游戏文件放入OD分区的Roms文件夹下

m0_60352504的博客 4566

java内存溢出示例(堆溢出、栈溢出)

堆溢出: /** * @author LXA * 堆溢出 */ public class Heap { public static void main(String[] args) { ArrayLi...

chimeidian9400的博客 144

自抗扰控制(ADRC)理论与工程实践:8.1 自适应ADRC与参数在线整定

自适应自抗扰控制(AADRC)针对传统固定参数ADRC在动态变化系统中的局限性,提出通过在线调整关键参数(如观测器带宽ω₀、控制器带宽ω_c)以适应对象动态变化。主要方法包括基于稳定性理论的自适应律设计和基于性能指标的优化调节,前者保证闭环稳定但设计复杂,后者通过梯度搜索或模糊规则实现性能优化但缺乏严格稳定性证明。当前挑战在于非线性时变系统的稳定性分析、参数变化速率限制及工程实现的计算负担。AADRC拓展了ADRC在变参数系统(如无人机、软体机器人)中的应用,是迈向自主智能控制的关键技术。

技术工作者 214

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

java栈溢出_java内存溢出示例(堆溢出、栈溢出)

堆溢出:/*** @author LXA* 堆溢出*/public classHeap{public static voidmain(String[] args){ArrayList list=newArrayList();while(true){list.add(newHeap());}}}报错:java.lang.OutOfMemoryError: Java heap space栈溢出:/**...

weixin_36409144的博客 287

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

4.8 实战:栈溢出攻击示例

vi -b xxx。

yzm65580952的博客 371

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

什么情况发生栈溢出?思维导图 代码示例(java 架构)

栈溢出是指程序在执行过程中,由于栈空间不足而引发的一种错误。栈是用于存储方法调用时的局部变量和方法调用信息的数据结构。当栈的空间被耗尽时,JVM 将抛出。

qq_33240556的博客 949

栈溢出攻击示例(shellcode打印/etc/passwd内容)

参考:https://blog.youkuaiyun.com/omnispace/article/details/51005934 在实验之前,首先需要关闭操作系统的ASLR,否则每次内存地址都会发生变化。关闭ubuntu操作系统的ASLR需要以root权限执行命令(文件内容默认为2,且操作系统重启后自动恢复): echo 0 > /proc/sys/kernel/randomize_va_space 漏洞代码入下: #include <stdio.h> #include <stdl

danxinzhujian的博客 571

终极指南:解决ESP-IDF tusb_midi示例中的栈溢出问题

ESP-IDF(Espressif IoT Development Framework)是乐鑫科技为其SoC打造的官方开发框架,广泛应用于物联网设备开发。其中tusb_midi示例为开发者提供了USB MIDI设备的快速实现方案,但在实际应用中,栈溢出问题常常困扰新手开发者。本文将详细介绍如何诊断和解决这一常见问题,帮助你稳定运行MIDI应用。 ## 一、认识栈溢出:tusb_midi示例的隐藏

gitblog_00896的博客 371

JVM栈内存调优:深度控制与性能优化(附栈溢出代码示例)

JVM栈内存调优是性能优化的关键环节。本文深入分析了栈内存的基本概念,通过递归调用示例演示了栈溢出问题,并剖析了其三大成因:递归过深、调用链过长和栈空间不足。针对性地提出了优化方案:设置递归终止条件、用迭代替代递归、调整-Xss参数增大栈内存、减少局部变量使用以及优化方法调用链。最后指出下一阶段将探讨JVM堆内存调优,为读者构建完整的JVM性能优化知识体系。

fykam的博客 516

一个程序栈崩溃(栈溢出)的简单示例(* ̄︶ ̄)

#include "stdafx.h" int add(int i, int& nRst) { if (i > 100000) return nRst; nRst += i; i++; return add(i, nRst); } int _tmain(int argc, _TCHAR* argv[]) { int nRst = 0; int i = 0; ...

qq_36308972的博客 721
上一篇: 汉诺塔递归的c语言实现(递归)
下一篇: git checkout 命令详解
csshuke
博客等级 码龄16年 1517粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值