Angus
Angus

Reputation: 12621

Stack corruption using buffer

I'm trying to understand what happens when a stack gets corrupted. This is the sample program i tried to understand. I have defined the size of the buffer as 1 byte. But the stack corruption happens after I enter the 13th byte. why is that getting corrupted after 13th byte?

C code :

#include<stdio.h>
#include<string.h>
int main(int argc,char *argv[]){
 char buffer[1];
 strcpy(buffer,argv[1]);
 printf("\n buffer : %s \n",buffer);
 return 0;
}

Assembly code :

        .file   "buffer_overflow.c"
        .section        .rodata
.LC0:
        .string "\n buffer : %s \n"
        .text
.globl main
        .type   main, @function
main:
        pushl   %ebp
        movl    %esp, %ebp
        andl    $-16, %esp
        subl    $32, %esp
        movl    12(%ebp), %eax
        addl    $4, %eax
        movl    (%eax), %eax
        movl    %eax, 4(%esp)
        leal    31(%esp), %eax
        movl    %eax, (%esp)
        call    strcpy
        movl    $.LC0, %eax
        leal    31(%esp), %edx
        movl    %edx, 4(%esp)
        movl    %eax, (%esp)
        call    printf
        movl    $0, %eax
        leave
        ret
        .size   main, .-main
        .ident  "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5"
        .section        .note.GNU-stack,"",@progbits

Upvotes: 0

Views: 622

Answers (3)

MYMNeo
MYMNeo

Reputation: 836

When CPU enter a function, it need to push some values in to memory stack.According to your codes, before call 'strcpy', the stack frame is shown like this on x86 system.

------------  offset 13
char buffer[1]
------------  offset 12
char *argv[]
------------  offset 8
int argc
------------  offset 4
ret
------------  offset 0

So after you wrote 13bytes, strcpy has rewrite the ret area. when main finish, it is corrupted.

Upvotes: 2

selbie
selbie

Reputation: 104514

Most important - The stack got corrupted as you went past the first byte. :) But I digress.

The stack likely had the following pushed onto it just prior to main being invoked.

4 bytes for the return address from this function.

4 bytes for "argc"

4 bytes for "argv".

1 byte for "buffer", but the compiler likely aligned this on 4-byte boundary

So the first 12 bytes of the stack are all variables. Once you corrupt the return address, at around offset 12 or 13, you put the program in a bad state and likely crashed upon attempting to return from this call.

Upvotes: 1

Gabe Sechan
Gabe Sechan

Reputation: 93561

Stacks grow downwards on Intel processors. And variables are placed on the stack. After the function call, the ABI (application binary interface) may also take up a few bytes to store things like frame pointers, pointers to the variable block, and anything else it desires. You can see that in your assembly with it pushing ebp at the beginning.

So why do you see stack corruption only after the 13th byte? Well, 1 byte is ok because you have 1 byte of memory. The next 12 are ok because the ABI pushed additional variables into that room. You may have odd results due to overwriting it, but you won't crash. Then you get into the next variable, which is the return address. Overwrite that and you'll almost certainly crash (short of remarkable luck).

Upvotes: 1

Related Questions