堆栈溢出的原因
- 格式:docx
- 大小:3.23 KB
- 文档页数:2
堆栈溢出攻击原理eax, ebx, ecx, edx, esi, edi, ebp, esp等都是X86 汇编语言中CPU 上的通用寄存器的名称,是32位的寄存器。
如果用C语言来解释,可以把这些寄存器当作变量看待。
比方说:add eax,-2 ; //可以认为是给变量eax加上-2这样的一个值。
这些32位寄存器有多种用途,但每一个都有“专长”,有各自的特别之处。
EAX 是"累加器"(accumulator), 它是很多加法乘法指令的缺省寄存器。
EBX是"基地址"(base)寄存器, 在内存寻址时存放基地址。
ECX 是计数器(counter), 是重复(REP)前缀指令和LOOP指令的内定计数器。
EDX则总是被用来放整数除法产生的余数。
ESI/EDI分别叫做"源/目标索引寄存器"(source/destination index),因为在很多字符串操作指令中, DS:ESI指向源串,而ES:EDI指向目标串.EBP是"基址指针"(BASE POINTER), 它最经常被用作高级语言函数调用的"框架指针"(frame pointer). 在破解的时候,经常可以看见一个标准的函数起始代码:push ebp ;保存当前ebpmov ebp,esp ;EBP设为当前堆栈指针sub esp, xxx ;预留xxx字节给函数临时变量....这样一来,EBP 构成了该函数的一个框架, 在EBP上方分别是原来的EBP, 返回地址和参数. EBP下方则是临时变量. 函数返回时作mov esp,ebp/pop ebp/ret 即可.ESP专门用作堆栈指针,被形象地称为栈顶指针,堆栈的顶部是地址小的区域,压入堆栈的数据越多,ESP也就越来越小。
在32位平台上,ESP每次减少4字节。
esp:寄存器存放当前线程的栈顶指针ebp:寄存器存放当前线程的栈底指针eip:寄存器存放下一个CPU指令存放的内存地址,当CPU执行完当前的指令后,从EIP寄存器中读取下一条指令的内存地址,然后继续执行。
堆栈溢出解决方法我折腾了好久堆栈溢出这事儿,总算找到点门道。
说实话堆栈溢出这事,我一开始也是瞎摸索。
我记得有一次写一个程序,它老是出现堆栈溢出的错误。
我当时就很懵,完全不知道从哪儿下手。
我最先想到的就是查看代码里那些函数调用,因为我觉得可能是函数调用太多了,就像你一层一层地盖房子,结果盖得太高,超过了地基能承受的范围。
我就仔仔细细检查每个函数内部的逻辑,看看有没有可能进入死循环的地方或者不必要的递归。
结果我发现还真有个函数里面有个隐藏的递归调用,在某些特定条件下它就不停地自己调用自己,就像一个人掉进了一个无限循环的陷阱里出不来,这肯定会把栈给撑爆啊。
我赶紧把这个递归条件修改好,以为万事大吉了。
但没想到这个办法并没有完全解决问题。
然后我又觉得是不是我的局部变量申请得太多了。
就好比你在一个小房间(函数栈帧)里面塞了太多东西,空间不够用了。
于是我又检查代码里那些大块头的局部变量,像一些很大的数组之类的。
我尝试把一些不必要在函数内部定义的变量挪到外面去,变成全局变量。
这就像把一些不常用的大件东西从拥挤的小房间搬到宽敞的仓库一样。
有时候还会遇到一种比较隐蔽的情况,就是在多线程编程的时候。
我试过好几个不同的线程同时频繁地调用同一个函数,每个线程都在自己的栈上进行操作,累积起来也很容易导致堆栈溢出。
我处理的方法就是给线程调用函数的频率设置了限制,不能让它们太疯狂地调用。
前几天又试了个新方法,就是增加栈的大小。
不过这就像你把房子的地基扩大一样,虽然有时候能解决问题,但这不是从根本上解决代码问题的好办法,只是一种临时的应急方案。
如果你的程序在不同环境运行,可能其他环境下你没有办法随意更改栈的大小。
我不确定我这些方法是不是能涵盖所有堆栈溢出的情况,但这些都是我真实遇到过并且通过这些方法解决了问题的经验。
如果有谁也遇到堆栈溢出的情况,可以先像我这样从函数调用、局部变量和多线程这几个方面去排查。
总之,一定要有耐心,因为这些问题有时候特别隐蔽,你得像个侦探一样,不放过任何一个可疑的代码片段。
程序溢出的基础和原理一:基础知识计算机内存运行分配的区域分为3个程序段区域:不允许写的数据段区域:静态全局变量是位于数据段并且在程序开始运行的时候被加载堆栈区域:放置程序的动态的用于计算的局部和临时变量则分配在堆栈里面和在过程调用中压入的返回地址数据。
堆栈是一个先入后出的队列。
一般计算机系统堆栈的方向与内存的方向相反。
压栈的xx作push=ESP-4,出栈的xx作是pop=ESP+4. 在一次函数调用中,堆栈中将被依次压入:参数,返回地址,EBP。
如果函数有局部变量,接下来,就在堆栈中开辟相应的空间以构造变量。
函数执行结束,这些局部变量的内容将被丢失。
但是不被清除。
在函数返回的时候,弹出EBP,恢复堆栈到函数调用的地址,弹出返回地址到EIP以继续执行程序。
在C语言程序中,参数的压栈顺序是反向的。
比如func(a,b,c)。
在参数入栈的时候,是:先压c,再压b,最后a.在取参数的时候,指令执行的图例:指令区域执行程序区0 1 2 348 调用100处的函数,参数1(3位),2(10位)C10 0 1 2 3100 执行处理10410810C110 返回调用堆栈区域0 1 2 3如果EBP分配的空间不够xx作就是产生溢出的地方200 保存以前的EBP4位(数据段的指针,用于可以使用局部动态变量)现在的EBP等于当前的ESP-动态数据的大小值,ESP=200204 0C 00 00 00此处是程序的返回地址208 参数1,填充1位20C 参数2填充2位210讲解例子WIN下的程序DEMO,演示参数导致的返回地址的变化讲清主要4位的填充问题另外溢出还会导致数据段的改变3:如何利用堆栈溢出原理可以概括为:由于字符串处理函数(gets,strcpy等等)没有对数组越界加以监视和限制,我们利用字符数组写越界,覆盖堆栈中的老元素的值,就可以修改返回地址。
在DEMO的例子中,这导致CPU去访问一个不存在的指令,结果出错。
标题: 堆栈溢出系列讲座(1)本文以及以下同系列各文为ipxodi根据alphe one, Taeho Oh 的英文资料所译及整理,你可以任意复制和分发。
序言:通过堆栈溢出来获得root权限是目前使用的相当普遍的一项黑客技术。
事实上这是一个黑客在系统本地已经拥有了一个基本账号后的首选攻击方式。
他也被广泛应用于远程攻击。
通过对daemon进程的堆栈溢出来实现远程获得rootshell的技术,已经被很多实例实现。
在windows系统中,同样存在着堆栈溢出的问题。
而且,随着internet的普及,win系列平台上的internet服务程序越来越多,低水平的win程序就成为你系统上的致命伤。
因为它们同样会被远程堆栈溢出,而且,由于win系统使用者和管理者普遍缺乏安全防范的意识,一台win系统上的堆栈溢出,如果被恶意利用,将导致整个机器被敌人所控制。
进而,可能导致整个局域网落入敌人之手。
本系列讲座将系统的介绍堆栈溢出的机制,原理,应用,以及防范的措施。
希望通过我的讲座,大家可以了解和掌握这项技术。
而且,会自己去寻找堆栈溢出漏洞,以提高系统安全。
堆栈溢出系列讲座入门篇本讲的预备知识:首先你应该了解intel汇编语言,熟悉寄存器的组成和功能。
你必须有堆栈和存储分配方面的基础知识,有关这方面的计算机书籍很多,我将只是简单阐述原理,着重在应用。
其次,你应该了解linux,本讲中我们的例子将在linux上开发。
1:首先复习一下基础知识。
从物理上讲,堆栈是就是一段连续分配的内存空间。
在一个程序中,会声明各种变量。
静态全局变量是位于数据段并且在程序开始运行的时候被加载。
而程序的动态的局部变量则分配在堆栈里面。
从操作上来讲,堆栈是一个先入后出的队列。
他的生长方向与内存的生长方向正好相反。
我们规定内存的生长方向为向上,则栈的生长方向为向下。
压栈的操作push=ESP-4,出栈的操作是pop=ESP+4.换句话说,堆栈中老的值,其内存地址,反而比新的值要大。
浅析JVM堆溢出和栈溢出以及其产⽣可能原因的排查要点⼀、JVM 堆溢出 在 jvm 运⾏ java 程序时,如果程序运⾏所需要的内存⼤于系统的堆最⼤内存(-Xmx),就会出现堆溢出问题。
创建对象时如果没有可以分配的堆内存,JVM就会抛出OutOfMemoryError:java heap space异常。
// 执⾏该段代码需要⼤于10m内存空间public class HeadOverflow {public static void main(String[] args) {List<Object> listObj = new ArrayList<Object>();for(int i=0; i<10; i++){Byte[] bytes = new Byte[1*1024*1024];listObj.add(bytes);}System.out.println("添加success");}}// 设置该程序的jvm参数信息-Xms1m -Xmx10m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError初始堆内存和最⼤可以堆内存 Gc详细⽇志信息ng.OutOfMemoryError: Java heap spaceDumping heap to java_pid2464.hprof ...Heap dump file created [16991068 bytes in0.047 secs]Exception in thread "main" ng.OutOfMemoryError: Java heap spaceat com.ghs.test.OOMTest.main(OOMTest.java:16) 在正式项⽬部署环境程序默认读取的是系统的内存,⼀般设置程序的堆初始内存(-Xms) == 堆最⼤可⽤内存(-Xmx)。
51单片机堆栈深入剖析用C语言进行MCS51系列单片机程序设计是单片机开发和应用的必然趋势。
Keil公司的C51编译器支持经典8051和8051派生产品的版本,通称为Cx51。
应该说,Cx51是C语言在MCS51单片机上的扩展,既有C语言的共性,又有它自己的特点。
本文介绍的是Cx51程序设计时堆栈的计算方法。
1.堆栈的溢出问题。
MCS51系列单片机将堆栈设置在片内RAM中,由于片内RAM资源有限,堆栈区的范围也是有限的。
堆栈区留得太大,会减少其他数据的存放空间,留得太少则很容易溢出。
所谓堆栈溢出,是指在堆栈区已经满了的时候还要进行新的压栈操作,这时只好将压栈的内容存放到非堆栈区的特殊功能寄存器(SFR)中或者堆栈外的数据区中。
特殊功能寄存器的内容影响系统的状态,数据区的内容又很容易被程序修改,这样一来,之后进行出栈操作(如子程序返回)时内容已变样,程序也就乱套了。
因此,堆栈区必须留够,宁可大一些。
要在Cx51程序设计中防止堆栈的溢出,要解决两个问题:第一,精确计算系统分配给用户的堆栈大小,假设是M;第二,精确计算用户需要堆栈的大小,假设是N。
要求M≥N,下面分别分析这两个问题。
2.计算系统分配给用户的堆栈大小Cx51程序设计中,因为动态局部变量是长驻内存中的,实际上相当于局部静态变量,即使在函数调用结束时也不释放空间(这一点不同于标准C语言)。
Cx51编译器按照用户的设置,将所有的变量存放在片内和片外的RAM中。
片内变量分配好空间后,将剩下的空间全部作为堆栈空间,这个空间是最大可能的堆栈空间。
当然,因为Cx51是一种可以访问寄存器的C语言(特殊功能寄存器),因此可在程序中访问SP,将堆栈空间设置得小一点。
不过,一般没有人这么做。
本文只是讨论放在片内RAM的变量。
我们把变量分为两种情况:①用作函数的参数和函数返回值的局部变量。
这种变量尽量在寄存器组中存放。
为了讨论方便,假设统一用寄存器组0,具体的地址为0x00~0x07。
单片机中的异常处理与故障排除方法总结摘要:单片机是嵌入式系统的核心组成部分,它在各种电子设备中起着至关重要的作用。
然而,在单片机的开发和运行过程中,可能会遇到各种异常和故障情况。
本文总结单片机中常见的异常处理与故障排除方法,旨在帮助开发人员更好地理解和应对这些问题。
1. 异常种类及原因单片机中的异常情况主要包括硬件故障和软件异常两大类。
硬件故障可能由于电压波动、温度过高、电磁干扰等因素导致,例如芯片损坏、外设连接错误等。
而软件异常则主要由于程序编写错误、资源竞争、中断处理不当等原因引起。
2. 异常处理方法2.1 硬件故障处理方法当单片机遭遇硬件故障时,必须从硬件层面进行排查和修复。
首先,检查电源供应情况,确保电源电压稳定,并使用适当的电源滤波电路来减少电压波动。
此外,还要注意外设的正确连接,确保信号线的质量。
其次,使用示波器等仪器来检测时钟信号的频率和占空比,以确保时钟信号的准确传输。
还可以通过温度统计数据来判断是否存在过热问题,并采取相应措施来降低温度。
最后,如果发现单片机芯片损坏,需要更换芯片,并进行相应的焊接和编程操作。
2.2 软件异常处理方法软件异常通常表现为死循环、系统崩溃等情况,为了解决这些问题,可以采取以下方法:首先,通过调试工具(如Keil、IAR等)来定位程序中的错误。
这些工具可以提供单步执行、断点调试等功能,帮助开发人员逐行扫描程序,并查找潜在的错误。
其次,检查程序中的资源竞争问题。
例如,当多个任务同时访问共享资源时,可能会出现数据错乱的情况。
为了解决这个问题,可以使用互斥量或信号量来同步任务之间的访问。
另外,如若发现中断处理有误,可以检查中断优先级和中断服务程序的编写。
确保中断服务程序的执行时间尽可能短,并正确处理各种中断。
最后,对代码进行优化,以提高程序的效率和稳定性。
可以采取合理的数据结构和算法,避免过多的循环和递归操作。
此外,及时释放不再使用的内存空间,以避免内存溢出等问题。
cad 堆栈溢出的原因及解决方式
近期有用户反馈在打开AutoCad 2007 的时候频繁出现卡死的情况,
并提示还提示0x00000FD 堆栈溢出,重启电脑和重装软件都无法解决。
针对
该问题小编整理了一些方法供大家参考。
1、排除了系统的问题就可能是软件的原因,但是我们重装之后,问题还是存在,那就不是软件的原因,那就可能是我们打开的文件问题,可是我们换了别的文件打开,还是有问题,那就排除了打开文件的因素;
2、剩下的问题就出在了打开CAD 的时候运行的文件的上面了。
大
家都知道在打开CAD 的时候,它会加载许多的预置文件,此次堆栈溢出的
问题就出现在这些文件上面,其中的某个文件将CAD 卡死了。
我们用CAD 的时候,经常打开图纸,有时候遇到图纸太大或者别的原因导致CAD 卡死,重新打开会发现CAD 崩溃,提示堆栈溢出的问题。
重
启电脑,重装软件都不能解决。
当然重装系统,再重装CAD 是肯定能解决的。
网友们也提出了多种解决问题的办法,但是作为亲身经历者,不少人看的是模棱两可,可能部分网友也是稀里糊涂的将问题解决。
下面就根据我的亲身经历,将这个问题的解决办法详细介绍一下。
cad 堆栈溢出的原因及解决方式近期有用户反馈在打开AutoCad 2007 的时候频繁出现卡死的情况,并提示还提示0x00000FD 堆栈溢出,重启电脑和重装软件都无法解决。
针对该问题小编整理了一些方法供大家参考。
1、排除了系统的问题就可能是软件的原因,但是我们重装之后,问题还是存在,那就不是软件的原因,那就可能是我们打开的文件问题,可是我们换了别的文件打开,还是有问题,那就排除了打开文件的因素;2、剩下的问题就出在了打开CAD 的时候运行的文件的上面了。
大家都知道在打开CAD 的时候,它会加载许多的预置文件,此次堆栈溢出的问题就出现在这些文件上面,其中的某个文件将CAD 卡死了。
我们用CAD 的时候,经常打开图纸,有时候遇到图纸太大或者别的原因导致CAD 卡死,重新打开会发现CAD 崩溃,提示堆栈溢出的问题。
重启电脑,重装软件都不能解决。
当然重装系统,再重装CAD 是肯定能解决的。
网友们也提出了多种解决问题的办法,但是作为亲身经历者,不少人看的是模棱两可,可能部分网友也是稀里糊涂的将问题解决。
下面就根据我的亲身经历,将这个问题的解决办法详细介绍一下。
遇到上面出现的CAD 堆栈溢出问题的时候,基本可以排除系统,软件的原因。
因为是卡死之后,才出现的崩溃,之前一直可以正常使用,所以基本可以排除系统的原因。
即要是不兼容,在你安装好之后,首次运行不兼容的问题大都会暴露了。
大家都知道在打开CAD 的时候,它会加载许多的预置文件,此次堆栈溢出的问题就出现在这些文件上面。
其中的某个文件将CAD 卡死了。
这些预置文件大都是在C 盘的。
不管你的CAD 是否安装在C 盘,这些文件都是在C 盘的用户文件夹里面的。
具体请参看下图的路径,其他版本的CAD 路径大致相同。
图中打了马赛克的地方,是自己的用户名,一般默认是Administrator.参考路径C:\Users\Administrator\AppData\Roaming\Autodesk\AutoCAD 2007\R17.0在这些文件夹中的某个运行的文件有问题。
CAD堆栈溢出如何处理
我们用CAD的时候,常常会遇到打开大图纸卡死的问题。
重启CAD 之后,发现系统警告说CAD堆栈溢出,常见的有0x00000FD堆栈溢出。
那么遇到这些问题的时候,我们该如何处理呢。
下面就是我的亲身经历解决办法
出现了堆栈溢出,基本排除是系统的问题。
如果软件不兼容,那么安装好软件之后,首次运行就会有提示。
重装了CAD,问题还是存在,说明不是软件本身的问题。
换了别的图纸打开,还是出现问题,说明不是打开的图纸的问题。
综合分析:应该是CAD运行的文件问题。
我们都知道,在打开CAD的时候,它自己会加载一些CAD内部的预置文件。
问题就出在这些预置文件里面。
下面给出参考的文件路径:
C:\Users\Administrator\AppData\Roaming\Autodesk\AutoCA D 2007\R17.0。
其中的Administrator,是默认用户名,用户要根据自己的实际用户名更改。
在其中的文件夹中找到Support文件夹。
问题就出现在这个文件夹的内容上。
为了快速的解决问题,我这里以360安全卫士自带的查到大文件的功能为例。
在最后一步中,找到Acaddoc.lsp的文件,问题就出在这个文件上,直接删掉就OK.
注意:不管你的CAD是装在哪个盘,查找的时候路径都是C盘。
其他版本的CAD溢出问题都可以用这个方法处理。
堆栈溢出的原因
堆栈溢出是一种常见的安全漏洞,它的发生原因主要是由于程序在执行过程中,使用了过多的栈空间,导致栈溢出,从而破坏了程序的正常执行流程。
本文将从堆栈溢出的原因、危害以及防范措施等方面进行探讨。
堆栈溢出的原因主要有两个方面:一是程序设计不当,二是攻击者利用漏洞进行攻击。
在程序设计不当的情况下,程序员可能会在函数中使用过多的局部变量,或者使用了过多的递归调用,导致栈空间不足,从而引发堆栈溢出。
而在攻击者利用漏洞进行攻击的情况下,攻击者可能会通过输入过长的数据,或者利用格式化字符串漏洞等方式,来覆盖栈中的返回地址,从而控制程序的执行流程。
堆栈溢出的危害主要表现在以下几个方面:一是程序崩溃,导致数据丢失或者系统崩溃;二是攻击者可以利用堆栈溢出漏洞,执行恶意代码,从而获取系统权限或者窃取敏感信息;三是攻击者可以利用堆栈溢出漏洞,进行拒绝服务攻击,从而使系统无法正常运行。
为了防范堆栈溢出漏洞,我们可以采取以下几个措施:一是在程序设计时,尽量减少使用局部变量和递归调用,从而减少栈空间的使用;二是对输入数据进行有效的检查和过滤,避免输入过长的数据;三是使用编译器提供的安全选项,如-fstack-protector等,来检测和防范堆栈溢出漏洞;四是使用堆栈随机化技术,来增加攻击者的难度,从而提高系统的安全性。
堆栈溢出是一种常见的安全漏洞,它的发生原因主要是由于程序设计不当和攻击者利用漏洞进行攻击。
为了防范堆栈溢出漏洞,我们需要采取有效的措施,从而提高系统的安全性。