1

For this simple code:

void main(){
  char buf[12];
  buf[11]='\xff';
  puts(buf);
}

I use gdb to debug this code and get its stack info like this:

0xbffff480:     0x40158ff4      0x40158ff4      0xff0494dc      0x40158ff4
0xbffff490:     0x00000000      0x40016ca0      0xbffff4f8      0x40045de3

0xbffff480 is where "buf" starts, and the last two words are EBP and RET, but what the hell is that between buf and EBP? obviously I don't have any other local vars. And I also tried if I allocate 8 bytes for buf on stack, it just continues from EBP, but if I allocate 9 or more bytes, it always has something in between. Could somebody explain this to me please? Thanks a lot! I am on linux 2.6.9

disassembly for main:

0x080483c4 <main+0>:    push   %ebp
0x080483c5 <main+1>:    mov    %esp,%ebp
0x080483c7 <main+3>:    sub    $0x28,%esp
0x080483ca <main+6>:    and    $0xfffffff0,%esp
0x080483cd <main+9>:    mov    $0x0,%eax
0x080483d2 <main+14>:   add    $0xf,%eax
0x080483d5 <main+17>:   add    $0xf,%eax
0x080483d8 <main+20>:   shr    $0x4,%eax
0x080483db <main+23>:   shl    $0x4,%eax
0x080483de <main+26>:   sub    %eax,%esp
0x080483e0 <main+28>:   movb   $0xff,0xfffffff3(%ebp)
0x080483e4 <main+32>:   lea    0xffffffe8(%ebp),%eax
0x080483e7 <main+35>:   mov    %eax,(%esp)
0x080483ea <main+38>:   call   0x80482e4
0x080483ef <main+43>:   leave
0x080483f0 <main+44>:   ret
iceagle
  • 1,507
  • 2
  • 13
  • 13
  • See http://stackoverflow.com/questions/2399072/why-gcc-4-x-default-reserve-8-bytes-for-stack-on-linux-when-calling-a-method – mark4o Nov 12 '10 at 09:24
  • if my gcc makes the stack 16bytes aligned, I think if I allocate 16bytes on stack, it should just continue from EBP, but the fact is not. It still has paddings in between. – iceagle Nov 12 '10 at 09:52

4 Answers4

4

That would be padding. Your compiler is probably aligning EBP on a 8-byte boundary, because aligned memory is almost always easier and faster to work with (from the processor's point of view). Some data types even require proper alignment to work.

You don't see any padding when you allocate only 8 bytes in your buffer because, in that case, EBP is already properly aligned.

Frédéric Hamidi
  • 258,201
  • 41
  • 486
  • 479
1

Normally gcc keep the stack aligned to a multiple of 16 for the sake of being able to use SSE instructions. Reading a disassembly of your main would be instructive.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
1

GCC is known to be somewhat trigger happy with stack usage. It often reserves a bit more stack space than strictly needed. Also, it will try to achieve 16-byte stack alignment even when this is not necessary. This seems to be what happens with the first instructions (40 bytes reserved, then %esp alignment to a multiple of 16).

The code you show, however, contains come strange things, especially the sequence from offsets 9 to 27: this is a long, slow, convoluted way of subtracting 16 from %esp, something which could have been done in a single opcode. Subtracting some bytes from %esp at that point is logical in preparation for calling an external function (puts()), and the count (16) respects alignment, but why doing so in such a weird way ?

It might be possible that this sequence is meant to be patched up in some way (e.g. at link time) to support either stack smashing detection code, or some sort of profiling code. I cannot reproduce this on my own systems. You should specify the version of gcc and libc you are using, the exact compilation flags, and the Linux distribution (because distributors may activate some options by default). The "2.6.9" figure is the kernel version, and it has no bearing whatsoever on the problem at hand (it just tells us that the system is quite old).

Thomas Pornin
  • 72,986
  • 14
  • 147
  • 189
0

You should really include an aseembly dump rather than a pure hex dump. but its more than likely one of 2 things:

  1. A stack frame being restored
  2. A stack check to ensure there was no corupption

the start may also contain a stack alignment, forcing one or both of the above

Necrolis
  • 25,836
  • 3
  • 63
  • 101