8

The output of the code below is "Overflow", but I didn't explicitly call the func function. How does it work?

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

int copy(char *input)
{
    char var[20];
    strcpy(var, input);
    return 0;
}

int func(void)
{
    printf("Overflow\n");
    return 0;
}

int main(int argc, char *argv[])
{
    char str[] = "AAAABBBBCCCCDDDDEEEEFFFFGGGG";
    int *p = (int *)&str[24];
    *p = (int)func;

    copy(str);
    return 0;
}
Jon
  • 428,835
  • 81
  • 738
  • 806
wilbeibi
  • 3,403
  • 4
  • 25
  • 44
  • 3
    you mean buffer overflow...? – JosephH Nov 13 '12 at 13:26
  • 3
    This is exactly how a hacker can get an unsecured program to execute code that it didn't mean to. Understanding it requires low-level knowledge of the compiler, runtime environment, and CPU architecture. – Jon Nov 13 '12 at 13:28
  • 1
    Note this: if the address of func has a zero byte in it, this won't work as you expect it to. – aaronps Nov 13 '12 at 13:45
  • Wow, this is a fantastically evil, nasty, yet highly elegant piece of code, really clears up a lot of things how these instructions are executed... – ppeterka Nov 13 '12 at 14:04
  • If you really want to know how does it work, just go through *Hacking: The Art of Exploitation* by Jon Erickson – jwaliszko Nov 13 '12 at 15:09

1 Answers1

11

The copy function overflows the var buffer in the copy function and overwrites the main return address with the address of the func function.

When copy function returns, instead of returning to main after the copy function call, it returns to func function.

ouah
  • 142,963
  • 15
  • 272
  • 331
  • It will return to the address corresponding at the integer value of "GGGG" ? – pedr0 Nov 13 '12 at 13:59
  • 1
    @pedr0 `GGGG` is replaced by the address of the `func` function in this assignment: `*p = (int)func;`. The `strcpy` will copy this address to the return address. – ouah Nov 13 '12 at 14:08
  • Why array `str` need 4 `int` size more than `var`, rather than 2 or 6? – wilbeibi Nov 13 '12 at 15:03
  • @Wilbeibi `str` needs 8 chars (2 int) more than `var`: 4 to account for the ebp of the stack frame, and 4 to override the 32 bits return address – German Garcia Nov 13 '12 at 16:33