You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

缓冲区溢出实验中栈内变量间存在“间隙”的原因咨询

缓冲区溢出实验中栈变量间隙的原因解答

首先看你提供的测试代码:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, char **argv) {
    int modified;
    char buffer[64];
    modified = 0;
    gets(buffer);
    if(modified != 0)
        printf("Changed!");
    else
        printf("Not changed!");
}

你的实验场景:

我正在开展缓冲区溢出实验,编译命令为gcc -g -fno-stack-protector test1.c -o test1。当程序执行到if(modified != 0)时,基址指针为0x00007fffffffdfe0,基址指针下方是存储整数0的4字节(对应变量modified),但char buffer[64]并未紧跟在int modified之后,中间存在4字节0与0x00007fff的“间隙”,之后才是我输入的64个A。

问题解答

这个间隙其实是x86-64平台的栈内存对齐机制导致的,具体细节如下:

  • x86-64架构遵循System V应用二进制接口(ABI)规范,其中明确要求函数调用时栈指针必须保持16字节对齐。哪怕你关闭了栈保护(-fno-stack-protector),编译器依然会严格遵守这个底层硬件和ABI的规则。
  • 你的变量modified是4字节的int类型,而buffer是64字节的字符数组。编译器在分配栈空间时,会从高地址向低地址依次安排变量,但为了让后续的buffer以及整个栈帧满足16字节对齐要求,会在modified和buffer之间自动插入4字节的填充(也就是你看到的“间隙”)。这样modified(4字节)+填充(4字节)+buffer(64字节)的总长度是72字节,能完美契合栈对齐的要求。
  • 另外,编译器通常会优先分配小尺寸的非数组变量(比如这里的modified),再分配数组类的大块内存,这种分配顺序加上对齐要求,就必然会产生这段填充间隙。

本质上,这段间隙是编译器为了保证内存访问的效率和正确性,遵循平台规范插入的填充字节,和栈保护没有关系——哪怕你关闭了栈保护,对齐规则依然会生效。

内容的提问来源于stack exchange,提问作者Carol Ward

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 12:37:33