堆栈上的局部变量 [英] Local variables on stack

查看:17
本文介绍了堆栈上的局部变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

To understand the stack frame concept, I wrote a little program for my own. First I will show you the code, a little sketch about it and then I will present my question:

所以,程序:

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
");
   }
   else{
        printf("Wrong password
");
   }
}

我将密码作为命令行参数提供.如果它等于'a',那么就可以了.所以,我认为这很清楚.

I give the password as a command-line argument. And if it is equal to 'a', then it is ok. So, I think it is clear.

现在,函数 check_pw 的堆栈框架必须如下所示:

Now the sketch how the stack frame of the function check_pw must look like:

               -------------------------         LOW
               |    buffer             |
               -------------------------
               |    valid              |
               -------------------------
               |    old EBP            |
               -------------------------
               |      RET              |
               -------------------------
               |      password         |
               -------------------------        HIGH

现在,我的问题:

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

  • I assume that the sketch is correct. So, then the first local variable "valid" must get a higher memory address than the second variable "buffer", right?

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

But when I use gdb as debugger(I use Ubuntu Lucid Lynx), set my breakpoints at the right places and type the following: x/x &valid and x/x &buffer then I get the address 0xbffff388 for "valid" and 0xbffff38c for "buffer" So, it is obvious that "buffer" has a higher address, but why?

推荐答案

为了防止缓冲区溢出(例如,可以通过使用 strcpy 来利用的缓冲区溢出),有一种技术包括编写一个 pre- 在堆栈上分配的所有数组末尾定义的值.当函数返回时,值(通常称为金丝雀)被验证,如果值被更改,程序将中止.

In order to protect against buffer overflows (like the one which could be exploited through your strcpy use, for instance), there's this technique which consists on writing a pre-defined value at the end of all arrays allocated on stack. When the function returns, the value (usually called canary) is verified and the program aborts if the value is changed.

函数完成后程序必须跳回的地址被压入堆栈.一种常见的攻击是覆盖该值,使程序执行攻击者注入的代码.如果受损缓冲区和指针存在金丝雀,则攻击者必须猜测金丝雀值才能获得对程序执行的控制.

The address where the program has to jump back to after the function finishes is pushed on the stack. A common attack is to override that value making the program execute code injected by the atacker. If there's a canary the compromised buffer and the pointer, the attacker would have to guess the canary value in order to gain control of the program execution.

您可以在维基百科上了解更多信息:http://en.wikipedia.org/wiki/Buffer_overflow_protection#A_canary_example

You can learn more about it on wikipedia: http://en.wikipedia.org/wiki/Buffer_overflow_protection#A_canary_example

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

You can disable that on gcc. If you compile your code like so (let's say your program filename is login.c):

gcc -g -fno-stack-protector login.c

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

You will notice that the variables are no longer rearranged.

这篇关于堆栈上的局部变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆