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:
So, the program:
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");
}
}
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.
Now the sketch how the stack frame of the function check_pw
must look like:
------------------------- LOW
| buffer |
-------------------------
| valid |
-------------------------
| old EBP |
-------------------------
| RET |
-------------------------
| password |
------------------------- HIGH
Now, my question:
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?
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?
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.
You can learn more about it on wikipedia: http://en.wikipedia.org/wiki/Buffer_overflow_protection#A_canary_example
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.
来源:https://stackoverflow.com/questions/28386038/local-variables-on-stack