Reputation: 401
I ve written a small program in order to understand how the stack and buffer overflows work.
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
char array[20];
printf("-=-=-=-=-=-=-=-=-=-= The prize pool is 2000$ -=-=-=-=-=-=-=-=-=--=\n");
printf("-=-=-=-=-=- Whatever you supply goes to array! -=-=-=-=-=-=-=\n");
strcpy(array, argv[1]);
printf("Array now is %p \n\n", &array);
}
I am running the program supplying
(gdb) run `perl -e 'print "A"x20 . "\x95\x84\x04\x08"x4'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/tests/c-tests/myownexamples/simpleover2 `perl -e 'print "A"x20 . "\x95\x84\x04\x08"x4'`
By setting a breakpoint in the last printf we are able to see that:
Breakpoint 3, main (argc=134513813, argv=0x8048495 <main+65>)
at simpleover2.c:19
19 printf("Array now is %p \n\n", &array);
(gdb) info frame
Stack level 0, frame at 0xbffff4a0:
eip = 0x8048489 in main (simpleover2.c:19); saved eip **0x8048495**
source language c.
Arglist at 0xbffff498, args: argc=134513813, argv=0x8048495 <main+65>
Locals at 0xbffff498, Previous frame's sp is 0xbffff4a0
Saved registers:
ebp at 0xbffff498, eip at 0xbffff49c
(gdb) disassemble main
Dump of assembler code for function main:
0x08048454 <+0>: push ebp
0x08048455 <+1>: mov ebp,esp
0x08048457 <+3>: sub esp,0x1c
0x0804845a <+6>: mov DWORD PTR [esp],0x8048560
0x08048461 <+13>: call 0x8048384 <puts@plt>
0x08048466 <+18>: mov DWORD PTR [esp],0x80485a4
0x0804846d <+25>: call 0x8048384 <puts@plt>
0x08048472 <+30>: mov eax,DWORD PTR [ebp+0xc]
0x08048475 <+33>: add eax,0x4
0x08048478 <+36>: mov eax,DWORD PTR [eax]
0x0804847a <+38>: mov DWORD PTR [esp+0x4],eax
0x0804847e <+42>: lea eax,[ebp-0x14]
0x08048481 <+45>: mov DWORD PTR [esp],eax
0x08048484 <+48>: call 0x8048364 <strcpy@plt>
=> 0x08048489 <+53>: mov eax,0x80485e2
0x0804848e <+58>: lea edx,[ebp-0x14]
0x08048491 <+61>: mov DWORD PTR [esp+0x4],edx
0x08048495 <+65>: mov DWORD PTR [esp],eax
0x08048498 <+68>: call 0x8048374 <printf@plt>
0x0804849d <+73>: leave
0x0804849e <+74>: ret
So I have overwritten the RET address but with an address that lies in the CURRENT stack frame.
Following step by step the execution till leave and ret instructions
(gdb) nexti
0x0804849e 21 }
(gdb) i r eip
eip 0x804849e 0x804849e <main+74>
(gdb) i r eip
eip 0x804849e 0x804849e <main+74>
(gdb) nexti
0x08048495 in main (argc=1435550665, argv=0xc35de589) at simpleover2.c:19
19 printf("Array now is %p \n\n", &array);
(gdb) i r eip
eip 0x8048495 0x8048495 <main+65>
We see that the execution INDEED goes there and following with nexti
we get :
(gdb) nexti
0x08048498 19 printf("Array now is %p \n\n", &array);
(gdb) i r eip
eip 0x8048498 0x8048498 <main+68>
(gdb) nexti
Program received signal SIGSEGV, Segmentation fault.
0xb7eeae97 in strchrnul () from /lib/tls/i686/cmov/libc.so.6
So why it segfaults ? Also it looks like it indeed calls printf() for 2nd time but it will not show up..
./simpleover2 `perl -e 'print "A"x20 . "\x95\x84\x04\x08"x4'`
-=-=-=-=-=-=-=-=-=-= The prize pool is 2000$ -=-=-=-=-=-=-=-=-=--=
-=-=-=-=-=- Whatever you supply goes to array! -=-=-=-=-=-=-=
Array now is 0xbf8ed894
Segmentation fault
Again, why it doesnt printf() show since ret points to that? and how and the execution continues there since leave and ret instructions have been executed that actually POP the whole stack frame?
Upvotes: 2
Views: 237
Reputation: 26
Your overwritten return address is changed to main+65 after LEAVE restores the program's original registers. So after "returning" to main+65, you call printf with different parameters than you think, so printf could try to print something that isn't null-terminated. It could then run off the end of the allocated page and cause an unexpected page fault on an unallocated page -> segfault. I can't tell what ABI you're using, so I don't know which registers are used to pass the parameters to printf.
Upvotes: 1
Reputation: 1
You're changing contents of array
, not it's address (you can't change the address actually!!). &array
means '-address of array
-', which I'm sure isn't what you intend. If you want to know the address of the character array on the stack simply refer to array
without the &
operator.
Upvotes: 0