Jeremie Le Hen writes: > Hi list, > > (Please Cc: me when replying, I am not subscribed to this list. Thank.) > > For the last couple of day, I've looked at the assembly generated by > various GCC releases. FYI, I'm working on FreeBSD but according to my > verifications, there doesn't seem to have much difference with Linux. > > All compilations have been performed with the -O flag. > > > I've written the following useless (and vulnerable) program: > % #include <string.h> > % > % int > % main(int ac, char *av[]) > % { > % char buf[16]; > % > % if (ac < 2) > % return 0; > % strcpy(buf, av[1]); > % return 1; > % } > > > Theorically, the most basic The corresponding stack right before > main() function should be calling strcpy(): > something like this: > > % push %ebp % | av | > % mov %esp, %ebp % | ac | > % sub $16, %esp % | ret | > % cmp $1, 8(%ebp) % ebp-> | sebp | (saved ebp) > % jle .byebye0 % |/ / / / | ^ > % mov 12(%ebp), %eax % | / / / /| | > % push 4(%eax) % |/ / / / | | (buf, 16 bytes) > % push -16(%ebp) % | / / / /| v > % call strcpy % | av[1] | > % mov $1, %eax % esp-> | &buf | > % jmp .byebye % > % byebye0: % > % mov $0, %eax % > % byebye: % > % leave % > % ret % > > > [ ... gcc 2.x and 3.x examples deleted ... ] > With GCC 4.2.1. things are weird too but differently. Functionnaly > it is correct but it is very far from what I've expected initially. > > In the prolog, before creating a new stack frame, the stack is > aligned on a 16 bytes boundary. Then `ret' is pushed once more and > the new stack frame is then created. Afterward the address of `ac' > is pushed and a 36-bytes buffer (9 words) is allocated. This > buffer will actually contain the 4 words buf in the top of it and > the 2 arguments for strcpy() in the bottom. But there are still 3 > unused words. Why so? This just looks to me like 16-aligning the stack; we do this for performance. Andrew. -- Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SL4 1TE, UK Registered in England and Wales No. 3798903