4.8 x64dbg 学会扫描应用堆栈

[复制链接]
发表于 2026-10-15 15:23:42 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
堆栈双结构:堆(动态分配)与栈(函数调用/局部变量)及栈溢出风险

【导语】区分计算机中两种核心数据结构:堆(Heap)用于动态内存分配,栈(Stack)遵循 LIFO 原则,用于存储函数调用、局部变量与栈帧,并通过压栈/弹栈管理临时数据;栈溢出(Stack Overflow)发生在向缓冲区写入过多数据时,可能破坏内存、致程序崩溃,严重可被利用控制 EIP 执行恶意代码。

核心观点

  • 堆用于动态内存分配;栈(LIFO)存储函数调用、局部变量与栈帧(压栈/弹栈)
  • 栈溢出源于缓冲区写入越界,可能破坏内存、致程序崩溃
  • 严重情况下栈溢出可被利用控制 EIP,执行恶意代码

适用场景
适用于理解内存布局、排查崩溃与学习缓冲区溢出安全原理的场景。

关键信息
(内存/安全,文中堆栈结构与栈溢出原理见正文。)



堆栈是计算机中的两种重要数据结构 堆(Heap)和栈(Stack)它们在计算机程序中起着关键作用,在内存中堆区(用于动态内存分配)和栈区(用于存储函数调用、局部变量等临时数据),进程在运行时会使用堆栈进行参数传递,这些参数包括局部变量,临时空间以及函数切换时所需要的栈帧等。

  • 栈(Stack)是一种遵循后进先出(LIFO)原则的线性数据结构。它主要用于存储和管理程序中的临时数据,如函数调用和局部变量。栈的主要操作包括压栈(添加元素)和弹栈(移除元素)。
  • 堆(Heap)是一种树形数据结构,通常用于实现优先队列。堆中的每个节点都有一个键值(key),并满足特定性质。最常见的堆类型是二叉堆(包括最大堆和最小堆)。堆在计算机程序中的应用包括堆排序算法和内存管理等。
而针对栈地址的分析在漏洞挖掘中尤为重要,栈溢出(Stack Overflow)是一种计算机程序中的运行时错误,通常发生在缓冲区(buffer)中。缓冲区是一段内存空间,用于临时存储数据。当程序试图向栈中写入过多数据时,可能导致栈溢出,从而破坏其他内存区域或导致程序崩溃,严重的则可能会导致黑客控制EIP指针,而执行恶意代码。
栈溢出的原因主要有以下几点:

  • 递归调用过深:当函数递归调用自身的层次过深时,可能导致栈溢出。这是因为每次函数调用都会在栈中分配内存,用于存储函数的局部变量和返回地址。如果递归层数太多,可能导致栈空间不足,从而引发栈溢出。
  • 局部变量占用过多栈空间:如果函数中的局部变量(尤其是数组和结构体)占用过多栈空间,可能导致栈溢出。这种情况下,可以考虑将部分局部变量移到堆内存中,以减小栈空间的压力。
  • 缓冲区溢出:当程序向缓冲区写入的数据超过其分配的空间时,可能发生缓冲区溢出。这种溢出可能导致栈空间中的其他数据被破坏,从而引发栈溢出。
LyScript 插件中提供了针对堆栈的操作函数,对于堆的开发与释放通常可使用create_alloc()及delete_alloc()在之前的文章中我们已经使用了堆创建函数,本章我们将重点学习针对栈的操作函数,栈操作函数有三种,其中push_stack用于入栈,pop_stack用于出栈,而最有效的还属peek_stack函数,该函数可用于检查指定堆栈位置处的内存参数,使用这个特性就可以实现,对堆栈地址的检测,或对堆栈的扫描等。
读者注意:由于peek_stack命令传入的堆栈下标位置默认从0开始,而输出的结果则一个十进制有符号长整数,一般而言有符号数会出现复数的情形,读者在使用时应更具自己的需求自行转换。
而针对有符号与无符号数的转换也很容易实现,long_to_ulong函数用于将有符号整数转换为无符号整数(long_to_ulong)而与之对应的ulong_to_long函数,则用于将无符号整数转换为有符号整数(ulong_to_long)。这些函数都接受一个整数参数(inter)和一个布尔参数(is_64)。当 is_64 为 False 时,函数处理32位整数;当 is_64 为 True 时,函数处理64位整数。
<ul>
有符号整数转无符号数(long_to_ulong):通过将输入整数与相应位数的最大值执行按位与操作(&)来实现转换。对于32位整数,使用 (1
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表