What happened if I rewrote the return address on the stack?

I know this is dangerous behavior, I just want to find out what happened.

The code is as follows:

#include<stdio.h>
#include<stdlib.h>

static int count = 0;

void hello(void){
    count ++;  
    fprintf(stderr,"hello! %d\n",count);
}

void foo(void){
    void *buf[10];
    static int i;

    for(i = 0 ; i < 100 ; i++){ // put enough data to overwrite the return address on stack
        buf[i] = hello;
    }
}

int main(void){
    int buf[1000];
    foo();
    return 0;
}

And the result:

……
hello! 83
hello! 84
hello! 85
hello! 86
hello! 87
hello! 88
hello! 89
Segmentation fault (core dumped)

Why was hello func called 89 times? When foo returns, the pc register gets the address hello func, right? So hello, and do what is inside. So what? Hasn't the program returned to the main function? Where did 89 come from? I have to misunderstand something, please indicate.

+4
source share
3 answers

hello foo 90 , buf. foo , ( ) hello , "" . , " ", , .

hello , foo. , , foo hello . , hello , , , , hello.

hello, , , hello hello , .

, , , , , , , , . hello , .

+9

, undefined. - , "" .

, ( 89 ). , , .

( , , .)

+5

As Nachum says, this behavior is undefined, but this does not mean that it cannot be explained:

100 - 89 = 11

This is exactly the size of your local stack (void * [10] + int).

Try this (undefined behavior, may delete your hard drive or fix global savings):

#include<stdio.h>
#include<stdlib.h>

static int count = 0;

static void hello(void){
    count ++;  
    fprintf(stderr,"hello! %d\n",count);
}

static void foo(void){
    void *buf[1];
    static int i;

    for(i = 0 ; i <= 100 + 2; i++){ // put enough data to overwrite the return address on stack
        buf[i] = hello;
    }
}

static void bye(void) {
    printf("Bye, bye...\n");
    exit(EXIT_SUCCESS);
}

int main(void){
    void *buf[1000];
    int i;

    for (i = 0; i < 1000; ++i) {
        buf[i] = &bye;
    }
    foo();
    return 0;
}
+1
source

All Articles