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/
This archive was generated by hypermail 2b30 : Wed Apr 24 2002 - 14:55:34 PDT