游乐游手机版
首页/网络安全/文章详情

缓冲区溢出解密:原理分析与防御措施(二)

时间:2026-07-21 19:17
函数调用时堆栈经历三步:保存旧栈指针、返回地址及执行函数。主调函数反序压入参数,通过call指令跳转。被调函数先执行程序引入(pushl%ebp;movl%esp,%ebp),再用subl为局部变量分配空间,最后leave和ret恢复栈帧。

首先,我们来探讨堆栈在函数调用过程中扮演的关键角色。当ESP被压入堆栈时,堆栈的内部布局会呈现出以下结构:

|_parametre_I___| EBP 12
|_parametre II__| EBP 8
|_return adress_| EBP 4
|___sa ved_ESP___| EBP ESP
|_local var I __| EBP-4
|_local var II__| EBP-8

上图展示的变量I和II是传递给函数的实际参数。在返回地址和保存的ESP之后,var I和var II属于该函数的局部变量。总结来说,当调用一个函数时,系统会依次执行以下三个核心步骤:

  1. 保存旧的堆栈指针(ESP),并将其压入堆栈。
  2. 保存下一条指令的地址(即返回地址),同样压入堆栈。
  3. 跳转到被调用函数的第一条指令开始执行。

每次函数调用都会严格按照这三个步骤执行,缺一不可。单纯的理论描述可能略显抽象,不如直接通过一个实际运行的示例,来观察堆栈指针(ESP)和基址指针(EBP)的动态变化过程。

以下面这段C语言代码为例进行分析:

void f(int a, int b, int c)
{
        char z[4];
}
void main()
{
        f(1, 2, 3);
}

使用-g编译选项生成调试信息,以便后续通过GDB观察堆栈行为:

[murat@victim murat]$ gcc -g a.c -o a

接下来,我们来拆解main函数内部的具体执行流程:

[murat@victim murat]$ gdb -q ./a
(gdb) disas main
Dump of assembler code for function main:
0x8048448 :       pushl   %ebp
0x8048449 :     movl   %esp, %ebp
0x804844b :     pushl  $0x3
0x804844d :     pushl  $0x2
0x804844f :     pushl  $0x1
0x8048451 :     call   0x8048440 
0x8048456 :    addl   $0xc, %esp
0x8048459 :    lea ve
0x804845a :    ret
End of assembler dump.

main函数的第一条指令是pushl %ebp——将旧的基址指针(EBP)压入堆栈保存。紧接着执行movl %esp, %ebp,将当前堆栈指针(ESP)的值复制到EBP中。从这一刻起,函数内部就可以通过EBP来访问局部变量和参数。这两条指令在汇编中有一个专有名称:函数序言(function prologue)。

接下来,主调函数(main)以逆序方式将参数压入堆栈:先压入常数3,再压入2,最后压入1。随后执行call 0x8048440 指令。如之前所述,call指令会自动将下一条指令的地址(即addl $0xc,%esp的地址0x8048456)压入堆栈,作为返回地址。函数返回后,需要清理堆栈上的三个参数(每个int占用4字节,总计12字节),因此后续跟了一条addl $0xc,%esp指令。最后lea veret指令完成收尾工作,返回到调用者。

那么,被调用的函数f内部又是如何管理堆栈的呢?

(gdb) disas f
Dump of assembler code for function f:
0x8048440 :  pushl   %ebp
0x8048441 :        movl   %esp, %ebp
0x8048443 :        subl   $0x4, %esp
0x8048446 :        lea ve
0x8048447 :        ret
End of assembler dump.

函数f的开头两条指令与main如出一辙,同样是标准的函数序言。关键区别在于subl $0x4, %esp——这条指令从ESP中减去4个字节,目的是为局部变量char z[4]分配栈空间,因为该函数声明了一个包含4个字符的数组。最后函数返回时,lea ve恢复栈帧,ret指令跳转回调用点。

整个调用过程就像搭积木一样:先构建主调函数的栈帧,然后在之上叠加被调函数的栈帧,使用完毕后逐个拆除,保持堆栈整洁。通过这种层层堆叠的机制,堆栈能够高效地管理函数调用与返回时的上下文信息。

来源:https://www.jb51.net/hack/5146.html
上一篇加密办公文档保护文字数据安全 下一篇缓冲区溢出漏洞解密详解第一篇
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
零基础Python网络安全学习指南,包住宿实战培训
网络安全 · 2026-07-25

零基础Python网络安全学习指南,包住宿实战培训

先抛出几个核心判断:网络安全人才缺口确实已经超过70万。这个数字不算夸张,各大招聘网站上安全岗位的薪资涨幅和需求增长都是实实在在的。但实话实说,行业真正缺的是能上手干活的人,不是只懂几个理论概念的新手。因此,一套扎实且成体系的训练方案,对于零基础转行或进阶提升就显得格外关键。 从零基础到能够独立应对

网络安全定义与核心概念详解
网络安全 · 2026-07-25

网络安全定义与核心概念详解

谈到网络安全,不同组织与标准体系对其定义虽有差异,但核心目标高度统一:保护信息与系统不受威胁侵害。以下梳理几种主流定义—— 什么是网络安全? 国际标准化组织(ISO)在ISO-74982文献中将安全定义为:最大程度地降低数据和资源遭受攻击的可能性。该定义虽简短,却精准点出安全的本质——即风险控制。

IIS 7.0网站漏洞利用与修复方法指南
网络安全 · 2026-07-25

IIS 7.0网站漏洞利用与修复方法指南

先来聊聊当前网络安全领域比较流行的一种实战技巧——以PHP环境为例,详细讲解图片马合并与解析漏洞利用的具体操作步骤。整个过程并不复杂,但细节往往决定成败,大家跟着流程逐步操作即可。 合并一张PHP一句话图片马 首先,我们需要将一句话木马脚本与一张正常图片合并,生成一个看似无害的图片文件。合并方式主要

织梦管理系统后台查找功能教程
网络安全 · 2026-07-25

织梦管理系统后台查找功能教程

通过SQL注入漏洞获取织梦CMS(DedeCMS)管理员密码后,满怀期待地准备进入后台,却发现怎么也找不到登录入口——这种情况其实相当常见。别着急,这里有一个实用的技巧值得尝试。 直接在网站地址后面添加以下路径: include dialog select_media php?f=form1 mur

微软IE浏览器BrowseDialog类(ccrpbds6.dll)拒绝服务安全漏洞深度分析
网络安全 · 2026-07-25

微软IE浏览器BrowseDialog类(ccrpbds6.dll)拒绝服务安全漏洞深度分析

BrowseDialog Class (ccrpbds6 dll) 导致 Internet Explorer 拒绝服务漏洞分析 该漏洞的PoC(概念验证代码)实现极为直接——触发浏览器崩溃的条件简单得令人意外。测试环境采用Windows XP Professional SP2(已安装全部补丁)并运行