C 堆栈上的局部变量

C 堆栈上的局部变量,c,stack,local-variables,C,Stack,Local Variables,为了理解堆栈框架的概念,我自己编写了一个小程序。首先,我将向您展示代码,一个关于它的略图,然后我将提出我的问题: 因此,该计划: int check_pw(char *password){ int valid = 0; char buffer[10]; strcpy(buffer, password); if(strcmp(buffer, "a") == 0){ valid = 1; } return valid; } in

为了理解堆栈框架的概念,我自己编写了一个小程序。首先,我将向您展示代码,一个关于它的略图,然后我将提出我的问题:

因此,该计划:

int check_pw(char *password){
    int valid = 0;
    char buffer[10]; 

    strcpy(buffer, password);

    if(strcmp(buffer, "a") == 0){
       valid = 1;
    }

    return valid;
}

int main(int argc, char *argv[]){
   if(check_pw(argv[1])){
        printf("OK\n");
   }
   else{
        printf("Wrong password\n");
   }
}
我将密码作为命令行参数提供。如果它等于‘a’,那么就可以了。所以,我认为这是清楚的

现在,绘制函数
check\u pw
的堆栈框架的外观:

               -------------------------         LOW
               |    buffer             |
               -------------------------
               |    valid              |
               -------------------------
               |    old EBP            |
               -------------------------
               |      RET              |
               -------------------------
               |      password         |
               -------------------------        HIGH
现在,我的问题是:

  • 我认为草图是正确的。那么,第一个局部变量“valid”必须获得比第二个变量“buffer”更高的内存地址,对吗

  • 但是当我使用gdb作为调试器(我使用Ubuntu Lucid Lynx)时,在正确的位置设置断点并键入以下内容:x/x&validx/x&buffer然后我得到地址0xbffff388表示“valid”,0xbffff38c表示“buffer” 所以,很明显,“缓冲区”有一个更高的地址,但为什么呢


    • 为了防止缓冲区溢出(例如,通过strcpy使用可以利用的溢出),有一种技术,它包括在堆栈上分配的所有数组的末尾写入预定义值。当函数返回时,将验证该值(通常称为canary),如果该值发生更改,程序将中止

      函数完成后程序必须跳回的地址被推送到堆栈上。常见的攻击是重写该值,使程序执行atacker注入的代码。如果在受损的缓冲区和指针中有一个金丝雀,攻击者将不得不猜测金丝雀值,以获得对程序执行的控制

      您可以在维基百科上了解更多信息:

      您可以在gcc上禁用它。如果您这样编译代码(假设您的程序文件名为login.c):


      您会注意到变量不再被重新排列。

      编译器可以在堆栈框架中随意布局局部变量。可能的重复-右侧相关侧栏中似乎还有其他类似问题。它是否也是一种防止“缓冲区溢出”等漏洞的保护机制或者类似的?因为这样我就没有机会溢出“valid”-变量。我担心这些变量的顺序不会影响某人使用草图布局溢出它们的能力(当然,这取决于您的代码和填充方式),您可以溢出有效变量…当然还有RET等等…但是不管怎样。我得到了答案…a)堆栈上局部变量的顺序取决于编译器b)搜索stackoverflow以查找类似的问题?就像在煤矿里充当瓦斯报警器的金丝雀一样?我怀疑这应该是这个词的起源,但我不知道它的词源:p谢谢你用“-fno stack protector”技巧给出的答案……我不知道
      gcc -g -fno-stack-protector login.c