user3124171
user3124171

Reputation: 401

ret address points to nowhere (?)

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

Answers (2)

EOF
EOF

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

Related Questions