精华内容
下载资源
问答
  • 堆溢出
    2022-05-24 21:21:39


    注:我的笔记风格,可能不会特别官方,不会晦涩难懂,而是以一个初学者能看懂的方式把知识呈现出来,用最简单的语言把抽象的概念表达出来~

    栈溢出和堆溢出

    栈溢出和堆溢出的简单理解:

    栈溢出:无限循环,无限递归,因为递归会把参数和局部变量放到栈中,无限递归导致栈溢出

    堆溢出:一直new对象,达到堆内存的上限,如果堆可以动态扩容,那就是达到内存申请上限


    总结

    简单的介绍了栈溢出和堆溢出的区别。

    本系列为基础知识分享,日更,有任何问题可以私聊或评论博主哦!
    希望给各位找工作和工作中的小伙伴提供一点微博的帮助,如果觉得有帮助,欢迎点赞评论收藏关注~

    更多相关内容
  • 开头我讨论了在旧版本Windows下利用堆溢出的技术,试着给读者提供一些关于unlink过程是怎样执行的、以及freelist[n]里面的flink/blink是如何被攻击者控制并提供简单的任意“4字节写”操作的实用的知识。本文的主要...
  • 主要介绍了java内存溢出示例(堆溢出、栈溢出),需要的朋友可以参考下
  • 堆溢出

    千次阅读 2019-04-23 20:56:40
    堆溢出是指程序向某个堆块中写入的字节数超过了堆块本身可使用的字节数(之所以是可使用而不是用户申请的字节数,是因为堆管理器会对用户所申请的字节数进行调整,这也导致可利用的字节数都不小于用户申请的字节数)...

    原理

    堆溢出是指程序向某个堆块中写入的字节数超过了堆块本身可使用的字节数(之所以是可使用而不是用户申请的字节数,是因为堆管理器会对用户所申请的字节数进行调整,这也导致可利用的字节数都不小于用户申请的字节数),因而导致了数据溢出,并覆盖到物理相邻的高地址的下一个堆块。
    不难发现,堆溢出漏洞发生的基本前提是
    1、程序向堆上写入数据。
    2、写入的数据大小没有被良好地控制。

    思路主要是
    1、覆盖与其物理相邻的下一个 chunk 的内容。
    A.prev_size
    B.size,主要有三个比特位,以及该堆块真正的大小。
      a.NON_MAIN_ARENA
      b.IS_MAPPED
      c.PREV_INUSE
      d.the True chunk size
    C.chunk content,从而改变程序固有的执行流。
    2、利用堆中的机制(如 unlink 等 )来实现任意地址写入( Write-Anything-Anywhere)或控制堆块中的内容等效果,从而来控制程序的执行流。
    

    实际上 puts 内部会调用 malloc 分配堆内存,覆盖到的可能并不是 top chunk

    重要步骤
    堆分配函数

    calloc(0x20);
    //等同于
    ptr=malloc(0x20);
    memset(ptr,0,0x20);
    

    calloc 与 malloc 的区别是 calloc 在分配后会自动进行清空,这对于某些信息泄露漏洞的利用来说是致命的。

    chunk1=realloc(chunk,32);
    
    当 realloc(ptr,size) 的 size 不等于 ptr 的 size 时
    如果申请 size > 原来 size
    如果 chunk 与 top chunk 相邻,直接扩展这个 chunk 到新 size 大小
    如果 chunk 与 top chunk 不相邻,相当于 free(ptr),malloc(new_size)
    如果申请 size < 原来 size
    如果相差不足以容得下一个最小 chunk(64 位下 32 个字节,32 位下 16 个字节),则保持不变
    如果相差可以容得下一个最小 chunk,则切割原 chunk 为两部分,free 掉后一部分
    当 realloc(ptr,size) 的 size 等于 0 时,相当于 free(ptr)
    当 realloc(ptr,size) 的 size 等于 ptr 的 size,不进行任何操作
    

    找到危险函数
    就是找到哪里堆溢出

    输入函数 ——gets,scanf ,vscanf
    输出函数——sprintf
    字符串
    1、strcpy,字符串复制,遇到 ‘\x00’ 停止
    2、strcat,字符串拼接,遇到 ‘\x00’ 停止
    3、bcopy

    确定填充长度

    这一部分主要是计算我们开始写入的地址与我们所要覆盖的地址之间的距离。 一个常见的误区是 malloc 的参数等于实际分配堆块的大小,但是事实上 ptmalloc 分配出来的大小是对齐的。这个长度一般是字长的 2 倍,比如 32 位系统是 8 个字节,64 位系统是 16 个字节。但是对于不大于 2 倍字长的请求,malloc 会直接返回 2 倍字长的块也就是最小 chunk,比如 64 位系统执行malloc(0)会返回用户区域为 16 字节的块。
    注意用户区域的大小不等于 chunk_hear.size,chunk_hear.size = 用户区域大小 + 2 * 字长
    还有一点是之前所说的用户申请的内存大小会被修改,其有可能会使用与其物理相邻的下一个 chunk 的 prev_size 字段储存内容。

    当 req=24 时,request2size(24)=32。而除去 chunk 头部的 16 个字节。实际上用户可用 chunk 的字节数为 16。而根据我们前面学到的知识可以知道 chunk 的 pre_size 仅当它的前一块块处于释放状态时才起作用。所以用户这时候其实还可以使用下一个 chunk 的 prev_size 字段,正好 24 个字节。实际上 ptmalloc 分配内存是以双字为基本单位,以 64 位系统为例,分配出来的空间是 16 的整数倍,即用户申请的 chunk 都是 16 字节对齐的。

    展开全文
  • 堆溢出检测,防护

    2018-12-01 21:37:06
    内存溢出,错误隐蔽,危害大,debug难,特别时在底层C语言开发环境下,对内存使用比较灵活,一旦内存溢出,造成的错误时非连续性,无逻辑性。很难debug 本文就时
  • 堆溢出处理

    2020-08-18 22:21:41
    在Java程序运行过程中,对象会不断的被新建和回收,而对象大部分情况下是放在空间中的,所以一旦对象太多导致空间不足,就会抛出OOM异常,也就是内存溢出了。 就像查案一样,程序出现问题的时候,先要保持现场...

    在Java程序运行过程中,对象会不断的被新建和回收,而对象大部分情况下是放在堆空间中的,所以一旦对象太多导致堆空间不足,就会抛出OOM异常,也就是堆内存溢出了。

    就像查案一样,程序出现问题的时候,先要保持现场信息,这样才方便排查问题,而JVM也为开发这提供了这样的手段,
    使用参数-XX:+HeapDumpOnOutOfMemoryError,让内存溢出的时候可以导出整个堆的信息,然后再加上-XX:HeapDumpPath参数,把整个堆的信息导出到开发指定的文件路径,方便查找。两个参数配合就做到了当出现OOM时,可以尽可能的保存下现场信息。

    接下来指定程序使用的虚拟机的工作模式为Server,然后指定最大堆大小为10M同时打印GC日志,最后再加上上述的两个参数,整体如下:
    在这里插入图片描述
    测试代码:

    import com.google.common.collect.Lists;
    
    import java.util.List;
    
    /**
     * 堆溢出导出文件
     */
    public class DumpOOM {
    
        public static class User {
            private byte[] p;
        }
    
        public static User createUser() {
            User user = new User();
            //大约1M大小
            user.p = new byte[1 * 1024 * 1024];
            return user;
        }
    
        public static void main(String[] args) {
            List list = Lists.newArrayList();
            for (int i = 0; i < 10; i++) {
                list.add(createUser());
                System.out.println("list中的数量:" + list.size());
            }
        }
    }
    

    以上代码实现的逻辑就是,循环创建User对象实例,并加入到集合list中,因为设置的最大堆大小为10M,而User实例中单单一个p属性就大约为1M了,所以最后的结果肯定会发生OOM。

    运行结果如下:
    在这里插入图片描述
    从输出结果可以发现,User实例有7个,同时也把堆信息文件导出到指定路径了。

    使用Java VisualVM工具分析下堆信息文件,展示如下:
    在这里插入图片描述

    发现byte[]类型占据的空间最多,点击去看下实例视图,如下:
    在这里插入图片描述
    从大到小排列下,会发现前7个实例大致都是1M左右,然后这7个实例都和DumoOOM类下的User类的p属性相关。

    回顾下之前程序的输出,list中的数量也只有7个,后面就抛出OOM了,数量和实例视图是对的上的。

    总结

    堆溢出时可以先导出堆信息文件保存,然后再配合上Java VisualVM工具找出导致堆溢出的对象。

    展开全文
  • 【缓冲区溢出】堆溢出原理

    千次阅读 2020-02-04 19:55:33
    一、操作系统中和栈的区别 待续 参考: https://www.jianshu.com/p/c082b014fdf9 https://www.jianshu.com/p/59cc7c8a44d3

     

    一、操作系统中堆和栈的区别

    堆内存申请,释放,操作,特点:
    1. 堆内存申请环境:堆内存需要程序员在程序中申请 ,动态分配,申请的大小有程序决定。
    2. 堆内存申请方法:C语言中的malloc() 函数 , c++ 中的new()函数。堆内存进行申请时候可能会申请失败,申请成功与失败与计算机性能,当前运行环境等有关。    
    3. 堆内存释放:申请过后的堆内存不能由系统自动进行释放,C语言中采用 free() 函数,c++中采用 delete() 函数进行释放内存。
    4. 堆内存操作:申请过后的内存,会返回指向堆内存的指针,后续对于内存的读写等操作需要通过此指针进行。
    5. 堆内存特点:地址由低向高生长。  堆内存非线性,呈现无序状态。因此用到了链表。

    栈内存申请,释放,操作,特点:
    1. 栈内存的申请是在程序中定义好的,比如数组,包括栈的大小,包含的变量(存储局部变量,数组,栈帧,函数返回地址等)  
    2. 栈内存的释放是有程序自身决定的不用掉用函数,当程序退出时,栈内存会自动销毁,维持栈平衡,否则就会发生内存访问错误。
    3. 栈内存的操作 push pop 只有这两种操作。  
    4. 栈内存的特点:由高地址向低地址生长,呈现线性规划。参考OD中栈缓冲区向上增长,即向低地址增长。

     

    二、堆-heap

    1、动态内存分配的方法

    动态内存分配(Dynamic memory allocation)又称为堆内存分配,是指计算机程序在运行期中分配使用内存。它可以当成是一种分配有限内存资源所有权的方法。 动态分配的内存在被程序员明确释放或被垃圾回收之前一直有效。与静态内存分配的区别在于没有一个固定的生存期。这样被分配的对象称之为有一个“动态生存期”。

    2、堆内存中数据结构——堆块、堆表

    ① 堆块
    出于对性能的考虑,堆区的内存按照不同大小的内存块被组织起来,以字节为单位。
    堆块的结构:堆块分为块首块身
    块首的结构:块首包含当前堆块的主要信息例如:堆块的大小,空闲态还是占用态等状态表信息。
    对块首的识别:当连续进行内存申请时,如果返回的指针地址是有差距的,两个连续的指针之间的差距就是第二个块身的块首。
    块身的结构:块身就是本堆块存放数据的位置,即最终分配给用户的数据区。
    块身位置:块身位于块首的后面紧挨着。
    对块身的操作: 申请堆区成功后返回的指针直接指向的块身的首地址,对块身的操作也就是对堆区的操作

    ② 堆表

    堆表的意义:堆表用来索引堆块。堆表中包含所有堆块的大小,位置,状态等信息。堆表的数据结构决定了堆区的组织方式,是快速检索空闲块,保证堆分配效率的关键。堆表进行设计的时候会考虑二叉树平衡策略,快速查找策略等。现代的操作系统中堆表的数据结构还不止一种。像一个字典一样用来查找堆块,并且在 windows 中索引的是所有空闲态的堆块。

    这里需要严格区分一点:占用态的堆块使用自己的程序索引,堆表只索引所有空闲态的堆块。重要的堆表包含两类:空闲双向链表(简称空表),快速单向链表(块表)。下面逐一对其要点进行分析。

    ——空表(空闲双向链表)

    1. 堆区空闲堆块的块首都包含一对指针,这对指针用于将空闲的堆块组织成双向链表,按照大小的不同,总共分为128条。
    2. 堆区一开始的堆表区中,有一个128项的指针数组,下标从0~127,即 freelist[0]~freelist[127],叫做空表数组索引,该数组的每一项都包含两个指针,用来标示一条空表。
    3. 空表的结构如下:

    freelist[0] 被称为零号空表,并且是节点从第一个 node1(1024bytes) 逐渐增或减 1024bytes 的整数倍,第二个及以后的节点的大小肯定是 >=1024 bytes。注意从第二个链表 freelist[1] 开始,此空闲链表中每个节点是 8bytes,freelist[2] 中每个节点的大小变成了 16bytes,上图中第三列 freelist[2] 中节点大小标记错误,注意一下。即从第二个空表 freeslist[1] 开始:节点的字节数 = 空表的下标 * 8 。此处谨记零号空闲链表,因为在堆分配的时候很重要。空表的特点:可以发生堆块合并,并且分配的效率低。

    ——块表(快速单向链表)

    1. 快速单向链表也就是块表是 windows 加速堆块分配的一种链表
    2. 块表的特点:永远处于占用态意味着不会发生合并,块表包含128项,每项是一个单向链表,每个链表最多只包含4个节点,链表一共128条,下标从0~127,和空表一样,组织结构跟空表很类似,块表总是被初始化为空。
    3. 结构如下图,应该是 blocklist:

    3、堆分配策略——堆块分配、堆块释放、堆块合并

    堆块分配——块表分配、零号空表分配、空表分配

    ① 块表的分配:寻找到精确匹配大小的空闲块,将此空闲块标注为占用状态,从块表中卸下,返回指向堆块块身的指针供程序使用。

    ② 零号空表的分配:零号空表中所有的空闲块是按照从小到大的顺序排列的,因此在分配的时候先从最后的堆块进行分配,看能否满足要求,如果能满足要求,则正向寻找最小能满足要求的堆块进行分配。

    ③ 空表分配:普通空表进行分配时候,寻找最优解决方案,若不满满足最优解决方案,则采用次优解决方案进行分配。空表分配中存在找零钱的现象,即:当无法找到最优解决方案,次优解决方案的时候,就会从大的尾块中割下一小块能够满足要求的堆块,最后把尾块块首的状态信息进行修改即可。
    堆块分配的特点:块表中只存在精确分配,不存在找零钱现象。空表中存在找零钱现象(不考虑堆缓存,碎片化等情况)

    堆块释放

    堆表的释放包括将占用态改为空闲态,释放的堆块链入相应的堆表,所有释放的堆块都链入相应的表尾,分配的时候先从表尾进行分配。块表最多只包含四个节点。

    堆块合并

    经过反反复复的堆块的分配与释放,堆区会出新很多凌乱的碎片,这时候就需要用到堆块的合并,堆块的合并包括几个动作:将堆块从空表中卸下,合并堆块,修改合并后的块首,链接入新的链表(合并的时候还有一种操作叫内存紧缩)。合并的时候只合并相邻的堆块。

     

    三、堆的调试方法

    调试堆与调试栈的方法不同,调试栈可以直接加载或者 attach 程序,但调试堆的时候也这样子的话,堆管理策略就会采用调试状态下的堆管理策略,使用调试状态下的堆管理函数。

    正常堆和调试堆的区别:
    1. 调试堆只采用空表分配,不采用块表分配
    2. 所有的堆块末尾都加上十六个字节的数据用来防止程序溢出(仅仅是用来防止程序溢出,而不是堆溢出),其中这十六个字节包括:8个 0xAB + 8个 0x00
    3. 块首的标志位不同,调试状态下的堆和正常堆的区别类似 debug 下的PE文件和 release 下的PE文件,做堆溢出实验的时候,调试器中可以正常运行 shellcode,单独运行却不行,这很可能就是调试堆与正常堆的差异造成的。

    为避免采用调试状态下的堆,直接在程序中嵌入 int3 断点,然后调用实时调试器即可, 源码:

    #include <windows.h>
    main()
    {
        HLOCAL h1,h2,h3,h4,h5,h6;
        HANDLE hp;
        hp = HeapCreate(0,0x1000,0x10000);
        __asm int 3
    
        h1 = HeapAlloc(hp,HEAP_ZERO_MEMORY,3);
        h2 = HeapAlloc(hp,HEAP_ZERO_MEMORY,5);
        h3 = HeapAlloc(hp,HEAP_ZERO_MEMORY,6);
        h4 = HeapAlloc(hp,HEAP_ZERO_MEMORY,8);
        h5 = HeapAlloc(hp,HEAP_ZERO_MEMORY,19);
        h6 = HeapAlloc(hp,HEAP_ZERO_MEMORY,24);
    
        HeapFree(hp,0,h1); //free to freelist[2] 
        HeapFree(hp,0,h3); //free to freelist[2] 
        HeapFree(hp,0,h5); //free to freelist[4]
    
        HeapFree(hp,0,h4); //coalese h3,h4,h5,link the large block to freelist[8]
        return 0;
    }

    待续。。

     

     

     

    参考:

    https://www.jianshu.com/p/c082b014fdf9

    https://www.jianshu.com/p/59cc7c8a44d3

    https://www.kanxue.com/chm.htm?id=10532&pid=node1000986

     

     

     

     

    展开全文
  • 堆溢出和堆利用

    2014-07-16 18:13:02
    这是一本讲述堆溢出和利用方法的书,第一部分讲基本原理,第二部分讲方法,第三部分讲战略
  • 一道堆方向的pwn(堆溢出、堆拼接) 这道题是17年0ctf的一道题,从里面还是能学到许多东西的 babyheap 这里我就直接记录我的做题过程 在此之前,查看保护信息,发现保护全开,emmmm Arch: amd64-64-little RELRO...
  • 堆溢出和栈溢出

    千次阅读 2020-08-26 17:31:08
    jvm堆溢出和栈溢出 一、jvm堆溢出 1、介绍 在jvm运行java程序时,如果程序运行所需要的内存大于系统的堆最大内存(-Xmx),就会出现堆溢出问题。 2、案例 // 介绍:执行该段代码需要大于10m内存空间 public ...
  • 所以理解起来总是有点晕,经过努力的调试分析后,总结了下面的更为详细的堆溢出原理。如果不准确的地方,希望大佬可以提醒一哈~ 1.堆的结构: struct _LIST_ENTRY{ DWORD Flink; DWORD Blink; } //空闲堆头结构...
  • 加参数在堆溢出dump出当前的堆快照 -XX:+HeapDumpOnOutOfMemoryError 上代码 import java.util.ArrayList; import java.util.List; /** * @author yangyuanliang * @version 1.9 * @date 2022/4/24 21:49 */ ...
  • 堆溢出利用

    千次阅读 2018-10-10 10:57:41
    1 2 代码 #include "stdafx.h" #include &lt;Windows.h&gt; int _tmain(int argc, _TCHAR* argv[]) { //HANDLE和HLOCAL 是 void* HLOCAL h1,h2,h3,h4,h5,h6; HANDLE hp; hp=HeapCre....
  • JVM之栈溢出和堆溢出

    千次阅读 2021-03-08 09:55:49
    jvm堆溢出和栈溢出一、jvm堆溢出1、介绍在jvm运行java程序时,如果程序运行所需要的内存大于系统的堆最大内存(-Xmx),就会出现堆溢出问题。2、案例//介绍:执行该段代码需要大于10m内存空间public classHeadOverflow ...
  • (1)内存泄漏(heap leak):内存指的是程序在运行中根据通过malloc/new等从中分配的一块内存,使用完成后必须通过调用相对应的free/delete释放掉。如果程序设计的错误导致这部分内存没有被释放掉,那么此后...
  • 堆溢出测试报告1

    2022-08-08 19:15:24
    堆溢出检测1.1 SARD-testsuite-6/testcaseid=1572 1)CWE编号 CWE-122: Heap-based Buffer Ove
  • Java 中(堆溢出、内存溢出、栈溢出)
  • aspcode堆溢出利用代码 aspcode确实算得上比较经典的堆溢出利用代码,原来发布的aspcode.c代码里面用于各种调试的垃圾代码比较多,很多人看不怎么明白。这个是自己用的一直没有对外发布的“潜入者”版本。利用代码...
  • pwn中堆溢出的学习
  • 堆溢出VS栈溢出

    2020-05-27 12:00:15
    堆溢出:java.lang.OutOfMemoryError(OOM) 栈溢出:java.lang.StackOverflowError 二、原因 堆溢出:堆中对象大小大于堆的最大大小(往往可能时内存泄漏导致) 栈溢出: 函数体内建立很大的数组 产生了死循环,...
  • 文章目录常见溢出一、堆溢出二、栈溢出1、栈空间不足——StackOverflowError实例2、栈空间不足——OutOfMemberError实例三、永久代溢出1、永久代溢出——常量池溢出2、永久代溢出——方法区溢出四、直接内存溢出原文...
  • 堆溢出利用程序.zip

    2020-03-12 14:43:27
    《0day安全:软件漏洞分析技术》第五章的堆溢出利用,在原来基础上做了修改。
  • 堆溢出漏洞简介

    千次阅读 2018-05-14 11:04:00
    这次来介绍一下堆溢出漏洞。不过这次的堆溢出漏洞比较复杂,不像栈溢出一样容易理解。所以这一次的内容会比较多。我尽量详细的介绍堆溢出漏洞,以及相关的知识。 首先,关于神马是堆溢出。简而言之就是在堆上产生的...
  • jvm堆溢出和栈溢出

    千次阅读 2019-08-14 11:29:45
    jvm堆溢出和栈溢出 一、jvm堆溢出 1、介绍 在jvm运行java程序时,如果程序运行所需要的内存大于系统的堆最大内存(-Xmx),就会出现堆溢出问题。 2、案例 // 介绍:执行该段代码需要大于10m内存空间 public class...
  • 什么是栈溢出和堆溢出

    千次阅读 2019-06-14 12:31:41
    堆溢出的产生是由于过多的函数调用,导致调用堆栈无法容纳这些调用的返回地址,一般在递归中产生。堆溢出很可能由无限递归(Infinite recursion)产生,但也可能仅仅是过多的堆栈层级。 int f(int x) { int a[10]; a...
  • (1)java堆溢出的原因: 程序不断创建对象,超过了java堆的内存。 (2)java堆溢出的现象: java.lang.outofmemoryerror: java heap space (3)java堆溢出的解决思路: 用memory analyzer对其分析,看是泄露...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 158,745
精华内容 63,498
关键字:

堆溢出

友情链接: I2C.zip