... local variables of main saved registers of main return address of main argc argv envp stack from startup code argc argv pointers NULL that ends argv[] environment pointers NULL that ends envp[] ELF Auxiliary Table argv strings environment strings program name NULLand ends at 0xc0000000. Let us dump a stack, and look. The argv strings and environment strings are character strings, most of the rest are 4-byte integers or pointers, so let us dump things that way.
#include <stdio.h> extern char **environ; int main(int argc, char **argv) { unsigned int a, *x; unsigned char *y; printf("argv = %08x\n", (unsigned int) argv); printf("argv[0] = %08x\n", (unsigned int) argv[0]); printf("environ = %08x\n", (unsigned int) environ); printf("environ[0] = %08x\n", (unsigned int) environ[0]); printf("\n\n"); x = (unsigned int *) ((unsigned int) &a & ~0xf); while ((unsigned int) x < (unsigned int) argv[0]) { printf("%08x:", (unsigned int) x); for (a=0; a<4; a++) printf(" %08x", x[a]); printf("\n"); x += 4; } printf("\n\n"); y = (unsigned char *) ((unsigned int) argv[0] & ~0xf) - 16; while ((unsigned int) y < 0xc0000000) { printf("%08x:", (unsigned int) y); for (a=0; a<16; a++) printf(" %02x", y[a]); printf(" "); for (a=0; a<16; a++) putchar((y[a] > 32 && y[a] < 127) ? y[a] : '.'); printf("\n"); y += 16; } return 0; }
% ./dumpstack aap noot miesOutput (all is in hex), with comments interspersed:
argv = bffff534 argv[0] = bffff6d0 environ = bffff548 environ[0] = bffff6ea
bffff4a0: bffff4a0 00000001The saved frame pointer %ebp and the return address of main
bffff4a0: bffff508 4004b500The parameters of main: argc, argv, envp
bffff4b0: 00000004 bffff534 bffff548
bffff4b0: 40017970 bffff4c0: 40147bd0 400168c0 08048600 bffff508 bffff4d0: bffff4b0 4004b4c5 00000000 00000000 bffff4e0: 00000000 40016cbc 00000004 08048360 bffff4f0: 00000000 4000ca40 4000d330 40016cbc bffff500: 00000004 08048360 00000000The following was produced by glibc:sysdeps/i386/elf/start.S:_start (push the parameters for __libc_start_main and call it)
Return address for the call of __libc_start_main at 0x804837c, points to the final hlt
bffff500: 08048381Eight values pushed by _start: main, argc, argv, __libc_csu_init, __libc_csu_fini, %edx (rtld_fini), %esp, %eax (padding)
bffff510: 0804841c 00000004 bffff534 08048670 bffff520: 08048600 4000d330 bffff52c 00000000The first seven are the parameters of __libc_start_main().
argc, followed by the array of argv pointers, followed by NULL:
bffff530: 00000004 bffff6d0 bffff6dc bffff6e0 bffff540: bffff6e5 00000000The global variable environ has the value 0xbffff548. It points at an array of string pointers, closed by NULL.
bffff540: bffff6ea bffff703 bffff550: bffff74d bffff75d bffff78f bffff79e bffff560: bffff7c5 bffff7ec bffff7f7 bffff802 bffff570: bffff812 bffff823 bffff831 bffff84d bffff580: bffff85f bffff872 bffff88d bffff896 bffff590: bffffb57 bffffb77 bffffb85 bffffb90 bffff5a0: bffffb9e bffffbb2 bffffbc5 bffffc5e bffff5b0: bffffc67 bffffc85 bffffc9a bffffcaf bffff5c0: bffffcc7 bffffcd8 bffffcef bffffd5d bffff5d0: bffffd74 bffffd7c bffffd8b bffffda9 bffff5e0: bffffdb6 bffffdd5 bffffde8 bffffe03 bffff5f0: bffffe24 bffffe6c bffffe77 bffffe90 bffff600: bffffe9c bffffea8 bffffefd bfffff15 bffff610: bfffff3b bfffff6e bfffff7b bfffff98 bffff620: bfffffad bfffffc5 bfffffd1 bfffffdf bffff630: 00000000
AT_SYSINFO=32 | VSYSCALL_ENTRY: 0xffffe400 |
AT_SYSINFO_EHDR=33 | VSYSCALL_BASE: 0xffffe000 |
AT_HWCAP=16 | hardware capabilities: 0x0183f9ff |
AT_PAGESZ=6 | page size: 4096 |
AT_CLKTCK=17 | clock frequency for times(): 100 Hz |
AT_PHDR=3 | address program headers: 0x08048034 |
AT_PHENT=4 | size of program header: 32 |
AT_PHNUM=5 | number of program headers: 8 |
AT_BASE=7 | base address of interpreter: 0x40000000 |
AT_FLAGS=8 | flags: 0 |
AT_ENTRY=9 | program entry point: 0x08048360 |
AT_UID=11 | uid: 500 |
AT_EUID=12 | effective uid: 500 |
AT_GID=13 | gid: 100 |
AT_EGID=14 | effective gid: 100 |
AT_SECURE=23 | secure mode boolean: 0 |
AT_PLATFORM=15 | address of platform string: 0xbffff6cb |
AT_NULL=0 | end of table |
bffff630: 00000020 ffffe400 00000021 bffff640: ffffe000 00000010 0183f9ff 00000006 bffff650: 00001000 00000011 00000064 00000003 bffff660: 08048034 00000004 00000020 00000005 bffff670: 00000008 00000007 40000000 00000008 bffff680: 00000000 00000009 08048360 0000000b bffff690: 000001f4 0000000c 000001f4 0000000d bffff6a0: 00000064 0000000e 00000064 00000017 bffff6b0: 00000000 0000000f bffff6cb 00000000 bffff6c0: 00000000Padding and platform string
bffff6c0: 00000000 69000000 00363836The kernel part of the stack, starting with argc, is aligned on a 16-byte boundary, while the strings are packed towards the end, so one needs 0-15 bytes of padding in between. Here there is 7 bytes of padding.
platform: i686
bffff6c0: 69 36 38 36 00 i686.
argv strings: ./dumpstack aap noot mies
bffff6d0: 2e 2f 64 75 6d 70 73 74 61 63 6b 00 61 61 70 00 ./dumpstack.aap. bffff6e0: 6e 6f 6f 74 00 6d 69 65 73 00 noot.mies.
bffff6e0: 4c 45 53 53 4b 45 LESSKE bffff6f0: 59 3d 2f 65 74 63 2f 6c 65 73 73 6b 65 79 2e 62 Y=/etc/lesskey.b bffff700: 69 6e 00 4d 41 4e 50 41 54 48 3d 2f 75 73 72 2f in.MANPATH=/usr/... ... _=./dumpstack OLDPWD=/home/aeb
bfffffd0: 00 5f 3d 2e 2f 64 75 6d 70 73 74 61 63 6b 00 4f ._=./dumpstack.O bfffffe0: 4c 44 50 57 44 3d 2f 68 6f 6d 65 2f 61 65 62 00 LDPWD=/home/aeb.
bffffff0: 2e 2f 64 75 6d 70 73 74 61 63 6b 00 ./dumpstack.
bffffff0: 00 00 00 00 ....
% objdump -d dumpstackWe see that the entry point 0x08048360 is the label _start.
dumpstack: file format elf32-i386 Disassembly of section .init: 08048300 <_init>: 8048300: 55 push %ebp 8048301: 89 e5 mov %esp,%ebp 8048303: 83 ec 08 sub $0x8,%esp 8048306: e8 79 00 00 00 call 8048384 <call_gmon_start> 804830b: e8 e0 00 00 00 call 80483f0 <frame_dummy> 8048310: e8 bb 03 00 00 call 80486d0 <__do_global_ctors_aux> 8048315: c9 leave 8048316: c3 ret Disassembly of section .plt: 8048318: ff 35 6c 98 04 08 pushl 0x804986c 804831e: ff 25 70 98 04 08 jmp *0x8049870 8048324: 00 00 add %al,(%eax) 8048326: 00 00 add %al,(%eax) 08048328 <putchar@plt>: 8048328: ff 25 74 98 04 08 jmp *0x8049874 804832e: 68 00 00 00 00 push $0x0 8048333: e9 e0 ff ff ff jmp 8048318 <_init+0x18> 08048338 <__libc_start_main@plt>: 8048338: ff 25 78 98 04 08 jmp *0x8049878 804833e: 68 08 00 00 00 push $0x8 8048343: e9 d0 ff ff ff jmp 8048318 <_init+0x18> 08048348 <printf@plt>: 8048348: ff 25 7c 98 04 08 jmp *0x804987c 804834e: 68 10 00 00 00 push $0x10 8048353: e9 c0 ff ff ff jmp 8048318 <_init+0x18> Disassembly of section .text: 08048360 <_start>: 8048360: 31 ed xor %ebp,%ebp 8048362: 5e pop %esi 8048363: 89 e1 mov %esp,%ecx 8048365: 83 e4 f0 and $0xfffffff0,%esp 8048368: 50 push %eax 8048369: 54 push %esp 804836a: 52 push %edx 804836b: 68 00 86 04 08 push $0x8048600 8048370: 68 70 86 04 08 push $0x8048670 8048375: 51 push %ecx 8048376: 56 push %esi 8048377: 68 1c 84 04 08 push $0x804841c 804837c: e8 b7 ff ff ff call 8048338 <__libc_start_main> 8048381: f4 hlt 8048382: 90 nop 8048383: 90 nop 08048384 <call_gmon_start>: 8048384: 55 push %ebp 8048385: 89 e5 mov %esp,%ebp 8048387: 53 push %ebx 8048388: e8 00 00 00 00 call 804838d <call_gmon_start+0x9> 804838d: 5b pop %ebx 804838e: 81 c3 db 14 00 00 add $0x14db,%ebx 8048394: 52 push %edx 8048395: 8b 83 18 00 00 00 mov 0x18(%ebx),%eax 804839b: 85 c0 test %eax,%eax 804839d: 74 02 je 80483a1 <call_gmon_start+0x1d> 804839f: ff d0 call *%eax 80483a1: 58 pop %eax 80483a2: 5b pop %ebx 80483a3: c9 leave 80483a4: c3 ret 80483a5: 90 nop 80483a6: 90 nop 80483a7: 90 nop 80483a8: 90 nop 80483a9: 90 nop 80483aa: 90 nop 80483ab: 90 nop 80483ac: 90 nop 80483ad: 90 nop 80483ae: 90 nop 80483af: 90 nop 080483b0 <__do_global_dtors_aux>: 80483b0: 55 push %ebp 80483b1: 89 e5 mov %esp,%ebp 80483b3: 50 push %eax 80483b4: 50 push %eax 80483b5: 80 3d 88 98 04 08 00 cmpb $0x0,0x8049888 80483bc: 75 2e jne 80483ec <__do_global_dtors_aux+0x3c> 80483be: a1 84 97 04 08 mov 0x8049784,%eax 80483c3: 8b 10 mov (%eax),%edx 80483c5: 85 d2 test %edx,%edx 80483c7: 74 1c je 80483e5 <__do_global_dtors_aux+0x35> 80483c9: 8d b4 26 00 00 00 00 lea 0x0(%esi),%esi 80483d0: 83 c0 04 add $0x4,%eax 80483d3: a3 84 97 04 08 mov %eax,0x8049784 80483d8: ff d2 call *%edx 80483da: a1 84 97 04 08 mov 0x8049784,%eax 80483df: 8b 10 mov (%eax),%edx 80483e1: 85 d2 test %edx,%edx 80483e3: 75 eb jne 80483d0 <__do_global_dtors_aux+0x20> 80483e5: c6 05 88 98 04 08 01 movb $0x1,0x8049888 80483ec: c9 leave 80483ed: c3 ret 80483ee: 89 f6 mov %esi,%esi 080483f0 <frame_dummy>: 80483f0: 55 push %ebp 80483f1: 89 e5 mov %esp,%ebp 80483f3: 51 push %ecx 80483f4: 51 push %ecx 80483f5: 8b 15 64 98 04 08 mov 0x8049864,%edx 80483fb: 85 d2 test %edx,%edx 80483fd: 74 19 je 8048418 <frame_dummy+0x28> 80483ff: b8 00 00 00 00 mov $0x0,%eax 8048404: 85 c0 test %eax,%eax 8048406: 74 10 je 8048418 <frame_dummy+0x28> 8048408: 83 ec 0c sub $0xc,%esp 804840b: 68 64 98 04 08 push $0x8049864 8048410: e8 eb 7b fb f7 call 0 <_init-0x8048300> 8048415: 83 c4 10 add $0x10,%esp 8048418: c9 leave 8048419: c3 ret 804841a: 90 nop 804841b: 90 nop 0804841c <main>: 804841c: 55 push %ebp 804841d: 89 e5 mov %esp,%ebp 804841f: 83 ec 18 sub $0x18,%esp 8048422: 83 e4 f0 and $0xfffffff0,%esp 8048425: b8 00 00 00 00 mov $0x0,%eax 804842a: 29 c4 sub %eax,%esp 804842c: 83 ec 08 sub $0x8,%esp 804842f: ff 75 0c pushl 0xc(%ebp) 8048432: 68 18 87 04 08 push $0x8048718 8048437: e8 0c ff ff ff call 8048348 <_init+0x48> 804843c: 83 c4 10 add $0x10,%esp 804843f: 83 ec 08 sub $0x8,%esp 8048442: 8b 45 0c mov 0xc(%ebp),%eax 8048445: ff 30 pushl (%eax) 8048447: 68 25 87 04 08 push $0x8048725 804844c: e8 f7 fe ff ff call 8048348 <_init+0x48> 8048451: 83 c4 10 add $0x10,%esp 8048454: 83 ec 08 sub $0x8,%esp 8048457: ff 35 84 98 04 08 pushl 0x8049884 804845d: 68 35 87 04 08 push $0x8048735 8048462: e8 e1 fe ff ff call 8048348 <_init+0x48> 8048467: 83 c4 10 add $0x10,%esp 804846a: 83 ec 08 sub $0x8,%esp 804846d: a1 84 98 04 08 mov 0x8049884,%eax 8048472: ff 30 pushl (%eax) 8048474: 68 47 87 04 08 push $0x8048747 8048479: e8 ca fe ff ff call 8048348 <_init+0x48> 804847e: 83 c4 10 add $0x10,%esp 8048481: 83 ec 0c sub $0xc,%esp 8048484: 68 5c 87 04 08 push $0x804875c 8048489: e8 ba fe ff ff call 8048348 <_init+0x48> 804848e: 83 c4 10 add $0x10,%esp 8048491: 8d 45 fc lea 0xfffffffc(%ebp),%eax 8048494: 83 e0 f0 and $0xfffffff0,%eax 8048497: 89 45 f8 mov %eax,0xfffffff8(%ebp) 804849a: 8b 55 0c mov 0xc(%ebp),%edx 804849d: 8b 45 f8 mov 0xfffffff8(%ebp),%eax 80484a0: 3b 02 cmp (%edx),%eax 80484a2: 72 02 jb 80484a6 <main+0x8a> 80484a4: eb 61 jmp 8048507 <main+0xeb> 80484a6: 83 ec 08 sub $0x8,%esp 80484a9: ff 75 f8 pushl 0xfffffff8(%ebp) 80484ac: 68 5f 87 04 08 push $0x804875f 80484b1: e8 92 fe ff ff call 8048348 <_init+0x48> 80484b6: 83 c4 10 add $0x10,%esp 80484b9: c7 45 fc 00 00 00 00 movl $0x0,0xfffffffc(%ebp) 80484c0: 83 7d fc 03 cmpl $0x3,0xfffffffc(%ebp) 80484c4: 76 02 jbe 80484c8 <main+0xac> 80484c6: eb 27 jmp 80484ef <main+0xd3> 80484c8: 83 ec 08 sub $0x8,%esp 80484cb: 8b 45 fc mov 0xfffffffc(%ebp),%eax 80484ce: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx 80484d5: 8b 45 f8 mov 0xfffffff8(%ebp),%eax 80484d8: ff 34 10 pushl (%eax,%edx,1) 80484db: 68 67 87 04 08 push $0x8048767 80484e0: e8 63 fe ff ff call 8048348 <_init+0x48> 80484e5: 83 c4 10 add $0x10,%esp 80484e8: 8d 45 fc lea 0xfffffffc(%ebp),%eax 80484eb: ff 00 incl (%eax) 80484ed: eb d1 jmp 80484c0 <main+0xa4> 80484ef: 83 ec 0c sub $0xc,%esp 80484f2: 68 6d 87 04 08 push $0x804876d 80484f7: e8 4c fe ff ff call 8048348 <_init+0x48> 80484fc: 83 c4 10 add $0x10,%esp 80484ff: 8d 45 f8 lea 0xfffffff8(%ebp),%eax 8048502: 83 00 10 addl $0x10,(%eax) 8048505: eb 93 jmp 804849a <main+0x7e> 8048507: 83 ec 0c sub $0xc,%esp 804850a: 68 5c 87 04 08 push $0x804875c 804850f: e8 34 fe ff ff call 8048348 <_init+0x48> 8048514: 83 c4 10 add $0x10,%esp 8048517: 8b 45 0c mov 0xc(%ebp),%eax 804851a: 8b 00 mov (%eax),%eax 804851c: 83 e0 f0 and $0xfffffff0,%eax 804851f: 83 e8 10 sub $0x10,%eax 8048522: 89 45 f4 mov %eax,0xfffffff4(%ebp) 8048525: 81 7d f4 ff ff ff bf cmpl $0xbfffffff,0xfffffff4(%ebp) 804852c: 76 05 jbe 8048533 <main+0x117> 804852e: e9 c5 00 00 00 jmp 80485f8 <main+0x1dc> 8048533: 83 ec 08 sub $0x8,%esp 8048536: ff 75 f4 pushl 0xfffffff4(%ebp) 8048539: 68 5f 87 04 08 push $0x804875f 804853e: e8 05 fe ff ff call 8048348 <_init+0x48> 8048543: 83 c4 10 add $0x10,%esp 8048546: c7 45 fc 00 00 00 00 movl $0x0,0xfffffffc(%ebp) 804854d: 83 7d fc 0f cmpl $0xf,0xfffffffc(%ebp) 8048551: 76 02 jbe 8048555 <main+0x139> 8048553: eb 25 jmp 804857a <main+0x15e> 8048555: 83 ec 08 sub $0x8,%esp 8048558: 8b 45 fc mov 0xfffffffc(%ebp),%eax 804855b: 03 45 f4 add 0xfffffff4(%ebp),%eax 804855e: 8a 00 mov (%eax),%al 8048560: 25 ff 00 00 00 and $0xff,%eax 8048565: 50 push %eax 8048566: 68 6f 87 04 08 push $0x804876f 804856b: e8 d8 fd ff ff call 8048348 <_init+0x48> 8048570: 83 c4 10 add $0x10,%esp 8048573: 8d 45 fc lea 0xfffffffc(%ebp),%eax 8048576: ff 00 incl (%eax) 8048578: eb d3 jmp 804854d <main+0x131> 804857a: 83 ec 0c sub $0xc,%esp 804857d: 68 75 87 04 08 push $0x8048775 8048582: e8 c1 fd ff ff call 8048348 <_init+0x48> 8048587: 83 c4 10 add $0x10,%esp 804858a: c7 45 fc 00 00 00 00 movl $0x0,0xfffffffc(%ebp) 8048591: 83 7d fc 0f cmpl $0xf,0xfffffffc(%ebp) 8048595: 76 02 jbe 8048599 <main+0x17d> 8048597: eb 44 jmp 80485dd <main+0x1c1> 8048599: 83 ec 0c sub $0xc,%esp 804859c: 8b 45 fc mov 0xfffffffc(%ebp),%eax 804859f: 03 45 f4 add 0xfffffff4(%ebp),%eax 80485a2: 80 38 20 cmpb $0x20,(%eax) 80485a5: 76 1d jbe 80485c4 <main+0x1a8> 80485a7: 8b 45 fc mov 0xfffffffc(%ebp),%eax 80485aa: 03 45 f4 add 0xfffffff4(%ebp),%eax 80485ad: 80 38 7e cmpb $0x7e,(%eax) 80485b0: 77 12 ja 80485c4 <main+0x1a8> 80485b2: 8b 45 fc mov 0xfffffffc(%ebp),%eax 80485b5: 03 45 f4 add 0xfffffff4(%ebp),%eax 80485b8: ba 00 00 00 00 mov $0x0,%edx 80485bd: 8a 10 mov (%eax),%dl 80485bf: 89 55 f0 mov %edx,0xfffffff0(%ebp) 80485c2: eb 07 jmp 80485cb <main+0x1af> 80485c4: c7 45 f0 2e 00 00 00 movl $0x2e,0xfffffff0(%ebp) 80485cb: ff 75 f0 pushl 0xfffffff0(%ebp) 80485ce: e8 55 fd ff ff call 8048328 <_init+0x28> 80485d3: 83 c4 10 add $0x10,%esp 80485d6: 8d 45 fc lea 0xfffffffc(%ebp),%eax 80485d9: ff 00 incl (%eax) 80485db: eb b4 jmp 8048591 <main+0x175> 80485dd: 83 ec 0c sub $0xc,%esp 80485e0: 68 6d 87 04 08 push $0x804876d 80485e5: e8 5e fd ff ff call 8048348 <_init+0x48> 80485ea: 83 c4 10 add $0x10,%esp 80485ed: 8d 45 f4 lea 0xfffffff4(%ebp),%eax 80485f0: 83 00 10 addl $0x10,(%eax) 80485f3: e9 2d ff ff ff jmp 8048525 <main+0x109> 80485f8: b8 00 00 00 00 mov $0x0,%eax 80485fd: c9 leave 80485fe: c3 ret 80485ff: 90 nop 08048600 <__libc_csu_fini>: 8048600: 55 push %ebp 8048601: 89 e5 mov %esp,%ebp 8048603: 83 ec 18 sub $0x18,%esp 8048606: 89 5d f4 mov %ebx,0xfffffff4(%ebp) 8048609: e8 ba 00 00 00 call 80486c8 <__i686.get_pc_thunk.bx> 804860e: 81 c3 5a 12 00 00 add $0x125a,%ebx 8048614: 89 7d fc mov %edi,0xfffffffc(%ebp) 8048617: 8d 83 14 ff ff ff lea 0xffffff14(%ebx),%eax 804861d: 8d bb 14 ff ff ff lea 0xffffff14(%ebx),%edi 8048623: 89 75 f8 mov %esi,0xfffffff8(%ebp) 8048626: 29 f8 sub %edi,%eax 8048628: c1 f8 02 sar $0x2,%eax 804862b: 85 c0 test %eax,%eax 804862d: 8d 70 ff lea 0xffffffff(%eax),%esi 8048630: 75 12 jne 8048644 <__libc_csu_fini+0x44> 8048632: e8 bd 00 00 00 call 80486f4 <_fini> 8048637: 8b 5d f4 mov 0xfffffff4(%ebp),%ebx 804863a: 8b 75 f8 mov 0xfffffff8(%ebp),%esi 804863d: 8b 7d fc mov 0xfffffffc(%ebp),%edi 8048640: 89 ec mov %ebp,%esp 8048642: 5d pop %ebp 8048643: c3 ret 8048644: ff 14 b7 call *(%edi,%esi,4) 8048647: 89 f0 mov %esi,%eax 8048649: 4e dec %esi 804864a: 85 c0 test %eax,%eax 804864c: 75 f6 jne 8048644 <__libc_csu_fini+0x44> 804864e: 89 f6 mov %esi,%esi 8048650: e8 9f 00 00 00 call 80486f4 <_fini> 8048655: 8b 5d f4 mov 0xfffffff4(%ebp),%ebx 8048658: 8b 75 f8 mov 0xfffffff8(%ebp),%esi 804865b: 8b 7d fc mov 0xfffffffc(%ebp),%edi 804865e: 89 ec mov %ebp,%esp 8048660: 5d pop %ebp 8048661: c3 ret 8048662: 8d b4 26 00 00 00 00 lea 0x0(%esi),%esi 8048669: 8d bc 27 00 00 00 00 lea 0x0(%edi),%edi 08048670 <__libc_csu_init>: 8048670: 55 push %ebp 8048671: 89 e5 mov %esp,%ebp 8048673: 83 ec 18 sub $0x18,%esp 8048676: 89 5d f4 mov %ebx,0xfffffff4(%ebp) 8048679: 89 75 f8 mov %esi,0xfffffff8(%ebp) 804867c: 31 f6 xor %esi,%esi 804867e: e8 45 00 00 00 call 80486c8 <__i686.get_pc_thunk.bx> 8048683: 81 c3 e5 11 00 00 add $0x11e5,%ebx 8048689: 89 7d fc mov %edi,0xfffffffc(%ebp) 804868c: e8 6f fc ff ff call 8048300 <_init> 8048691: 8d 93 14 ff ff ff lea 0xffffff14(%ebx),%edx 8048697: 8d 83 14 ff ff ff lea 0xffffff14(%ebx),%eax 804869d: 29 c2 sub %eax,%edx 804869f: c1 fa 02 sar $0x2,%edx 80486a2: 39 d6 cmp %edx,%esi 80486a4: 73 15 jae 80486bb <__libc_csu_init+0x4b> 80486a6: 89 45 f0 mov %eax,0xfffffff0(%ebp) 80486a9: 89 d7 mov %edx,%edi 80486ab: 90 nop 80486ac: 8d 74 26 00 lea 0x0(%esi),%esi 80486b0: ff 14 b0 call *(%eax,%esi,4) 80486b3: 46 inc %esi 80486b4: 8b 45 f0 mov 0xfffffff0(%ebp),%eax 80486b7: 39 fe cmp %edi,%esi 80486b9: 72 f5 jb 80486b0 <__libc_csu_init+0x40> 80486bb: 8b 5d f4 mov 0xfffffff4(%ebp),%ebx 80486be: 8b 75 f8 mov 0xfffffff8(%ebp),%esi 80486c1: 8b 7d fc mov 0xfffffffc(%ebp),%edi 80486c4: 89 ec mov %ebp,%esp 80486c6: 5d pop %ebp 80486c7: c3 ret 080486c8 <__i686.get_pc_thunk.bx>: 80486c8: 8b 1c 24 mov (%esp),%ebx 80486cb: c3 ret 80486cc: 90 nop 80486cd: 90 nop 80486ce: 90 nop 80486cf: 90 nop 080486d0 <__do_global_ctors_aux>: 80486d0: 55 push %ebp 80486d1: 89 e5 mov %esp,%ebp 80486d3: 53 push %ebx 80486d4: 52 push %edx 80486d5: bb 54 98 04 08 mov $0x8049854,%ebx 80486da: a1 54 98 04 08 mov 0x8049854,%eax 80486df: 83 f8 ff cmp $0xffffffff,%eax 80486e2: 74 0c je 80486f0 <__do_global_ctors_aux+0x20> 80486e4: 83 eb 04 sub $0x4,%ebx 80486e7: ff d0 call *%eax 80486e9: 8b 03 mov (%ebx),%eax 80486eb: 83 f8 ff cmp $0xffffffff,%eax 80486ee: 75 f4 jne 80486e4 <__do_global_ctors_aux+0x14> 80486f0: 58 pop %eax 80486f1: 5b pop %ebx 80486f2: 5d pop %ebp 80486f3: c3 ret Disassembly of section .fini: 080486f4 <_fini>: 80486f4: 55 push %ebp 80486f5: 89 e5 mov %esp,%ebp 80486f7: 53 push %ebx 80486f8: e8 00 00 00 00 call 80486fd <_fini+0x9> 80486fd: 5b pop %ebx 80486fe: 81 c3 6b 11 00 00 add $0x116b,%ebx 8048704: 50 push %eax 8048705: e8 a6 fc ff ff call 80483b0 <__do_global_dtors_aux> 804870a: 59 pop %ecx 804870b: 5b pop %ebx 804870c: c9 leave 804870d: c3 ret
In the above, main() did
804841c: 55 push %ebp 804841d: 89 e5 mov %esp,%ebp 804841f: 83 ec 18 sub $0x18,%esp 8048422: 83 e4 f0 and $0xfffffff0,%esp ... 80485fd: c9 leave 80485fe: c3 retWith gcc4 we see
8048474: 8d 4c 24 04 lea 0x4(%esp),%ecx 8048478: 83 e4 f0 and $0xfffffff0,%esp 804847b: ff 71 fc pushl 0xfffffffc(%ecx) 804847e: 55 push %ebp 804847f: 89 e5 mov %esp,%ebp 8048481: 51 push %ecx 8048482: 83 ec 24 sub $0x24,%esp ... 80486c3: 83 c4 24 add $0x24,%esp 80486c6: 59 pop %ecx 80486c7: 5d pop %ebp 80486c8: 8d 61 fc lea 0xfffffffc(%ecx),%esp 80486cb: c3 retThat is, the address of the first parameter (traditionally argc) to main is taken, the stack pointer is aligned to 0 (mod 16), another copy of the return address is pushed, the frame pointer is saved, a new frame pointer is set up, and and the address of argc is pushed. Upon return, the "outer" return address is used, the one below argc. For people contemplating buffer overflow attacks, this means that the first thing overwritten is not the return address, but the address of the location following that of the return address. (However, this is for main() only, not for other functions.)