代码

#include <windows.h>
int main()
{HLOCAL h1,h2,h3,h4,h5,h6;HANDLE hp;hp = HeapCreate(0,0x1000,0x10000);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);_asm int 3HeapFree(hp,0,h1);HeapFree(hp,0,h3);HeapFree(hp,0,h5);_asm int 3HeapFree(hp,0,h4);return 0;
}

实验目的

了解HeapAlloc函数的操作过程

实验准备

环境:windows 2k professional
编译器:vc++
调试器:OD

实验过程

1.首先观察链表是怎么装载进去的

CPU Disasm
Address   Hex dump          Command                                  Comments
77FCC8E6  |.  8066 05 10    AND BYTE PTR DS:[ESI+5],10 //对堆块中Flag位进行更改,使其为占用态

2.然后修改被装载进去堆块的地址,先改被占用堆块的第一项,第二项,再去修改Freelist[1]中的第一项第二项,然后再把可用的总空间加起来放进堆块一开始偏移0x28的地方。

77FCC909  |.  8D46 08       LEA EAX,[ESI+8]
77FCC90C  |.  8918          MOV DWORD PTR DS:[EAX],EBX
77FCC90E  |.  894E 0C       MOV DWORD PTR DS:[ESI+0C],ECX
77FCC911  |.  8901          MOV DWORD PTR DS:[ECX],EAX
77FCC913  |.  8943 04       MOV DWORD PTR DS:[EBX+4],EAX             //把地址进行替换
77FCC916  |.  8B45 D0       MOV EAX,DWORD PTR SS:[EBP-30]
77FCC919  |.  0147 28       ADD DWORD PTR DS:[EDI+28],EAX              //add last part
77FCC91C  |>  834D FC FF    OR DWORD PTR SS:[EBP-4],FFFFFFFF

3.然后再把int 3断点往下再移一位,观察堆的拆卸,装载这一系列的操作。先开头还是一些准备的传参的工作,上线程锁啊这些的。然后就进入了关键的函数。这是函数的一波传参。

77FCC8CA  |.  6A 00         PUSH 0                                   //Arg4 = 0
77FCC8CC  |.  8D45 D0       LEA EAX,[LOCAL.12]
77FCC8CF  |.  50            PUSH EAX                                 //Arg3 = 指向堆栈中存放数组的指针
77FCC8D0  |.  56            PUSH ESI                                 //Arg2 = 指向Free的那个堆块的堆块头部
77FCC8D1  |.  57            PUSH EDI                                 //Arg1 = 指向整个堆块的最前面
77FCC8D2  |.  E8 EA000000   CALL 77FCC9C1                             //ntdll.77FCC9C1

4.然后的代码就是判断上一个堆块的一些数据,来判断要不要合并

77FCC9C1  /$  55            PUSH EBP                                 // ntdll.77FCC9C1(guessed Arg1,Arg2,Arg3,Arg4)
77FCC9C2  |.  8BEC          MOV EBP,ESP
77FCC9C4  |.  53            PUSH EBX
77FCC9C5  |.  56            PUSH ESI
77FCC9C6  |.  8B75 0C       MOV ESI,DWORD PTR SS:[ARG.2]             //指向Free的那个堆块的堆块头部
77FCC9C9  |.  8B5D 08       MOV EBX,DWORD PTR SS:[ARG.1]             //指向HeapCreate堆块的头
77FCC9CC  |.  57            PUSH EDI
77FCC9CD  |.  8BFE          MOV EDI,ESI
77FCC9CF  |.  0FB746 02     MOVZX EAX,WORD PTR DS:[ESI+2]            //读取上一节的长度
77FCC9D3  |.  C1E0 03       SHL EAX,3
77FCC9D6  |.  2BF8          SUB EDI,EAX
77FCC9D8  |.  3BFE          CMP EDI,ESI                              //判断前面的那个堆块是不是只和一块空表连着的,如果连着的判断是不是尾块
77FCC9DA  |.  74 0A         JE SHORT 77FCC9E6
77FCC9DC  |.  F647 05 01    TEST BYTE PTR DS:[EDI+5],01              //观察前一块的是否是占用态
77FCC9E0  |.^ 0F84 98E9FFFF JZ 77FCB37E

5.然后就进行了相加的操作,那个Call 778953A的作用应该是检测那个堆块所对应的链表。

77FCB37E  |> /8B4D 10       MOV ECX,DWORD PTR SS:[EBP+10]
77FCB381  |. |0FB707        MOVZX EAX,WORD PTR DS:[EDI]
77FCB384  |. |8B09          MOV ECX,DWORD PTR DS:[ECX]
77FCB386  |. |03C8          ADD ECX,EAX                              //上一节堆块的大小再加上这一节的进行合并
77FCB388  |. |81F9 00FE0000 CMP ECX,0FE00
77FCB38E  |. |0F87 52160000 JA 77FCC9E6
77FCB394  |. |807D 14 00    CMP BYTE PTR SS:[EBP+14],0
77FCB398  |. |0F85 6A370000 JNE 77FCEB08
77FCB39E  |> |57            PUSH EDI                                 //指向Free的那个堆块的前一个堆块
77FCB39F  |. |53            PUSH EBX                                 //指向整个堆块的最前面
77FCB3A0  |. |E8 95E1FBFF   CALL 77F8953A                            // ntdll.77F8953A

6.先把之前的那个表从链表中拿出来,同时还检测了这块上再上面一块,如果这再上面一块不是占用态的话还要继续进行合并。再把堆块最前面对大小的说明的那一部分进行改动。

77FCB3A5  |.  8B4F 0C       MOV ECX,DWORD PTR DS:[EDI+0C]
77FCB3A8  |.  8B47 08       MOV EAX,DWORD PTR DS:[EDI+8]
77FCB3AB  |.  3BC1          CMP EAX,ECX                              //看看前面的再前面的那个堆块是不是只和一块空表连着的
77FCB3AD  |.  8901          MOV DWORD PTR DS:[ECX],EAX
77FCB3AF  |.  8948 04       MOV DWORD PTR DS:[EAX+4],ECX             //把和Free合并的那个堆块从链表中取出来
77FCB3B2  |.  74 4D         JE SHORT 77FCB401
77FCB3B4  |>  8A47 05       MOV AL,BYTE PTR DS:[EDI+5]
77FCB3B7  |.  A8 04         TEST AL,04                               //检测标志位。(不是很懂
77FCB3B9  |.^ 0F85 21FDFFFF JNZ 77FCB0E0
77FCB3BF  |>  8A46 05       MOV AL,BYTE PTR DS:[ESI+5]
77FCB3C2  |.  24 10         AND AL,10
77FCB3C4  |.  A8 10         TEST AL,10
77FCB3C6  |.  8847 05       MOV BYTE PTR DS:[EDI+5],AL               //把合并进来的堆块调成空闲态
77FCB3C9  |.  0F85 CB170000 JNZ 77FCCB9A
77FCB3CF  |>  0FB70F        MOVZX ECX,WORD PTR DS:[EDI]
77FCB3D2  |.  8B45 10       MOV EAX,DWORD PTR SS:[EBP+10]
77FCB3D5  |.  8BF7          MOV ESI,EDI                              //再往上看一个堆块
77FCB3D7  |.  0108          ADD DWORD PTR DS:[EAX],ECX               //加起来
77FCB3D9  |.  0FB70F        MOVZX ECX,WORD PTR DS:[EDI]
77FCB3DC  |.  294B 28       SUB DWORD PTR DS:[EBX+28],ECX            //从总的里面减
77FCB3DF  |.  66:8B00       MOV AX,WORD PTR DS:[EAX]
77FCB3E2  |.  F647 05 10    TEST BYTE PTR DS:[EDI+5],10              //又判断是不是尾块
77FCB3E6  |.  66:8907       MOV WORD PTR DS:[EDI],AX                 //堆块头部的大小进行了替换 合并
77FCB3E9  |.  0F85 F7150000 JNZ 77FCC9E6
77FCB3EF  |.  8B45 10       MOV EAX,DWORD PTR SS:[EBP+10]
77FCB3F2  |.  8B08          MOV ECX,DWORD PTR DS:[EAX]
77FCB3F4  |.  66:8B00       MOV AX,WORD PTR DS:[EAX]
77FCB3F7  |.  66:8944CF 02  MOV WORD PTR DS:[ECX*8+EDI+2],AX         //把下一节中描述上一节大小的量进行变化
77FCB3FC  |.  E9 E5150000   JMP 77FCC9E6

6.然后又看下一节是不是占用态,不是占用态的话继续合并。

77FCC9E0  |.^\0F84 98E9FFFF JZ 77FCB37E
77FCC9E6  |>  F646 05 10    TEST BYTE PTR DS:[ESI+5],10
77FCC9EA  |.  75 0F         JNZ SHORT 77FCC9FB
77FCC9EC  |.  8B45 10       MOV EAX,DWORD PTR SS:[EBP+10]
77FCC9EF  |.  8B00          MOV EAX,DWORD PTR DS:[EAX]
77FCC9F1  |.  F644C6 05 01  TEST BYTE PTR DS:[EAX*8+ESI+5],01        //看下一节是不是占用态
77FCC9F6  |.  8D3CC6        LEA EDI,[EAX*8+ESI]
77FCC9F9  |.  74 09         JZ SHORT 77FCCA04

7.看下一节是不是尾块,不是的话继续合并、

77FCCA04  |> \0FB70F        MOVZX ECX,WORD PTR DS:[EDI]
77FCCA07  |.  03C8          ADD ECX,EAX
77FCCA09  |.  81F9 00FE0000 CMP ECX,0FE00
77FCCA0F  |.^ 77 EA         JA SHORT 77FCC9FB
77FCCA11  |.  807D 14 00    CMP BYTE PTR SS:[EBP+14],0
77FCCA15  |.  0F85 FB210000 JNE 77FCEC16
77FCCA1B  |>  8A47 05       MOV AL,BYTE PTR DS:[EDI+5]
77FCCA1E  |.  24 10         AND AL,10
77FCCA20  |.  A8 10         TEST AL,10                               //看是不是尾块
77FCCA22  |.  8846 05       MOV BYTE PTR DS:[ESI+5],AL
77FCCA25  |.  75 4B         JNZ SHORT 77FCCA72
77FCCA27  |>  57            PUSH EDI                                 //下一节的地址
77FCCA28  |.  53            PUSH EBX                                 //堆块的地址
77FCCA29  |.  E8 0CCBFBFF   CALL 77F8953A                            //\ntdll.77F8953A
77FCCA2E  |.  8B4F 0C       MOV ECX,DWORD PTR DS:[EDI+0C]
77FCCA31  |.  8B47 08       MOV EAX,DWORD PTR DS:[EDI+8]
77FCCA34  |.  3BC1          CMP EAX,ECX                              //看看是不是表里只有一个
77FCCA36  |.  8901          MOV DWORD PTR DS:[ECX],EAX
77FCCA38  |.  8948 04       MOV DWORD PTR DS:[EAX+4],ECX             //把表改成指向自己,清空
77FCCA3B  |.^ 0F84 12E9FFFF JE 77FCB353

8.然后修改堆块头,改下一节对上一节大小的说明

77FCCA41  |> \8A47 05       MOV AL,BYTE PTR DS:[EDI+5]
77FCCA44  |.  A8 04         TEST AL,04
77FCCA46  |.^ 0F85 CBE6FFFF JNZ 77FCB117
77FCCA4C  |>  0FB70F        MOVZX ECX,WORD PTR DS:[EDI]
77FCCA4F  |.  8B45 10       MOV EAX,DWORD PTR SS:[EBP+10]
77FCCA52  |.  0108          ADD DWORD PTR DS:[EAX],ECX               //上面加的又加上下一节
77FCCA54  |.  0FB70F        MOVZX ECX,WORD PTR DS:[EDI]
77FCCA57  |.  294B 28       SUB DWORD PTR DS:[EBX+28],ECX            //从总的里面减
77FCCA5A  |.  66:8B08       MOV CX,WORD PTR DS:[EAX]
77FCCA5D  |.  F646 05 10    TEST BYTE PTR DS:[ESI+5],10              //确认不是尾块
77FCCA61  |.  66:890E       MOV WORD PTR DS:[ESI],CX                 //又一次修改堆块头的大小
77FCCA64  |.^ 75 95         JNZ SHORT 77FCC9FB
77FCCA66  |.  8B08          MOV ECX,DWORD PTR DS:[EAX]
77FCCA68  |.  66:8B00       MOV AX,WORD PTR DS:[EAX]
77FCCA6B  |.  66:8944CE 02  MOV WORD PTR DS:[ECX*8+ESI+2],AX         //修改下一节中对上一节的大小的描述
77FCCA70  |.^ EB 89         JMP SHORT 77FCC9FB

9.找一个空闲的空表放进去

77FCC8E6  |.  8066 05 10    AND BYTE PTR DS:[ESI+5],10               //确认堆块的Flag位
77FCC8EA  |.  0FB745 D0     MOVZX EAX,WORD PTR SS:[LOCAL.12]
77FCC8EE  |.  8D9CC7 780100 LEA EBX,[EAX*8+EDI+178]                  //找一个Freelist
77FCC8F5  |.  895D C4       MOV DWORD PTR SS:[LOCAL.15],EBX
77FCC8F8  |.  391B          CMP DWORD PTR DS:[EBX],EBX               //看这个表是不是空闲的空表
77FCC8FA  |.^ 0F84 CBF5FFFF JE 77FCBECB
77FCC90C  |.  8918          MOV DWORD PTR DS:[EAX],EBX
77FCC90E  |.  894E 0C       MOV DWORD PTR DS:[ESI+0C],ECX
77FCC911  |.  8901          MOV DWORD PTR DS:[ECX],EAX
77FCC913  |.  8943 04       MOV DWORD PTR DS:[EBX+4],EAX             //按照顺序改堆块里面的地址
77FCC916  |.  8B45 D0       MOV EAX,DWORD PTR SS:[EBP-30]            //堆溢出就在这一个点,就把那个指针替换掉
77FCC919  |.  0147 28       ADD DWORD PTR DS:[EDI+28],EAX            //改空表里面的地址

堆溢出 对HeapFree函数的详细调试相关推荐

  1. 堆溢出-House of orange 学习笔记(看雪论坛)

    https://www.jianshu.com/p/4b0a73f321f9 前几天把House of orange重新学习了一下,比照着glibc malloc的源码好好分析了一下,希望做到真正做到 ...

  2. linux函数 取值溢出,Linux eCryptfs工具parse_tag_3_packet()函数堆溢出漏洞

    发布日期:2009-07-28 更新日期:2009-07-29 受影响系统: Linux kernel 2.6.30.3 描述: ----------------------------------- ...

  3. CVE-2012-0003:Microsoft Windows Media Player winmm.dll MIDI 文件堆溢出漏洞调试分析

    0x01 蜘蛛漏洞攻击包 前言:2012 年 2月,地下黑产中流行着一款国产名为蜘蛛漏洞的攻击包 -- "Zhi-Zhu Exploit Pack",该工具包含 5 个漏洞,都是在 ...

  4. 堆(heap)系列_0x0A:3种方法一次性解决堆溢出问题

    概述:本篇文章主要介绍堆问题中最常见的堆溢出问题的排查思路:常规思路 + 页堆思路 + 应用程序验证器思路 前提:可以看到懂得DPH(点击查看)和会使用应用程序验证器(点击查看)和WinDbg 文章目 ...

  5. Netgear R6400v2 堆溢出漏洞分析与利用

    2020 年 6 月,ZDI发布了一个关于Netgear R6700型号设备上堆溢出漏洞的安全公告,随后又发布了一篇关于该漏洞的博客,其中对该漏洞进行了详细分析,并给出了完整的漏洞利用代码.该漏洞存在 ...

  6. 《0Day安全》之堆溢出

    最近重读<0Day安全>,由于栈溢出比较简单,所以直接从堆溢出开始读起. 在学习堆溢出之前,需要读者对堆的结构有一定的了解.先写一个小程序,分配一个新的堆来供我们研究它的结构,代码如下 # ...

  7. 堆溢出(二)空表DWORD SHOOT

    0x000 环境 虚拟机 VirtualBox 5.0.20 系统 windows 2000 Kali linux 工具 VC++6.0 OllyDbg 1.10 汉化版 AsmToE v5.20 0 ...

  8. 堆溢出(DwordShoot)利用SEH异常处理

    异常处理的身影处处可见,最常见的处理方式就是当异常发生时,在异常处理模块中记录日志,便于程序员事后定位.但是,被异常处理包含的代码真的会在异常发生时让程序优雅的退出吗?在程序的世界里什么都可能发生,所 ...

  9. 【缓冲区溢出】堆溢出原理

    一.操作系统中堆和栈的区别 堆内存申请,释放,操作,特点: 1. 堆内存申请环境:堆内存需要程序员在程序中申请 ,动态分配,申请的大小有程序决定. 2. 堆内存申请方法:C语言中的malloc() 函 ...

  10. 漏洞学习笔记——堆溢出原理

    最近在学习堆的溢出原理,但是查了网上和书上的一些讲解,总是感觉缺少一些关键点.所以理解起来总是有点晕,经过努力的调试分析后,总结了下面的更为详细的堆溢出原理.如果不准确的地方,希望大佬可以提醒一哈~ ...

最新文章

  1. opencart导入导出export/import功能插件
  2. 超图预览osgb格式倾斜摄影文件
  3. 基于 Spring Boot 的车牌识别系统(附项目地址)ba
  4. Python学习系列day2-python基础
  5. 北大计算机学院冯岩松,冯岩松__北京理工大学机电学院
  6. 【PL/SQL】学习笔记 (1)一个简单的PL/SQL程序
  7. testmarkdown
  8. 单机俄罗斯方块游戏制作心得(四)
  9. [2018.03.13 T3]联盟(alliances)
  10. Linux驱动开发 / 字符设备驱动内幕 (1)
  11. MT4跨平台跟单系统(API跟单、EA跟单、NJ4X跟单)的实现方式和技术原理
  12. 约翰·冯·诺依曼的开挂人生
  13. 【烈日炎炎战后端】Git(0.1万字)
  14. 深度学习(七)——图像验证码破解(数字加减验证码)
  15. 2022研究生学术与职业素养讲座(MOOC)期末答案
  16. 平行世界真的存在吗?镜像宇宙的三个科学奥秘
  17. 如何让百度搜索到我的博客或者网站
  18. 最先进的智能采茶机器人_一种智能采茶机器人的制作方法
  19. GUI素材-FLASH模板集
  20. 前端三剑客 - HTML

热门文章

  1. 数据结构与算法——深入理解红-黑树!
  2. 黑轴、青轴、茶轴、红轴、白轴的区别
  3. GNSS 周跳探测方法 之 TurboEdit
  4. 快递查询接口-快递鸟对接方案
  5. 中级php工程师笔试,PHP工程师笔试题目及行测题型示例
  6. 22-Consent 确认逻辑实现
  7. HTTP TFP状态解释
  8. 台式计算机的电流是多少,电脑台式机一天耗电大概是多少
  9. JSON字符串中带有反斜杠
  10. jquery图片3D旋绕效果 rotate3Di的操作