I have the following code example:
int main(int argc, char **argv) {
char *name[2];
name[0] = "/bin/sh";
name[1] = NULL;
execve(name[0], name, NULL);
exit(0);
}
Disassembling the program leads to something similar to:
1. 0x08048250 <main+0>: push %ebp
2. 0x08048251 <main+1>: mov %esp,%ebp
3. 0x08048253 <main+3>: and $0xfffffff0,%esp
4. 0x08048256 <main+6>: sub $0x20,%esp
5. 0x08048259 <main+9>: movl $0x80a6f68,0x18(%esp)
6. 0x08048261 <main+17>: movl $0x0,0x1c(%esp)
7. 0x08048269 <main+25>: mov 0x18(%esp),%eax
8. 0x0804826d <main+29>: movl $0x0,0x8(%esp)
9. 0x08048275 <main+37>: lea 0x18(%esp),%edx
10. 0x08048279 <main+41>: mov %edx,0x4(%esp)
11. 0x0804827d <main+45>: mov %eax,(%esp)
12. 0x08048280 <main+48>: call 0x804f5c0 <execve>
13. 0x08048285 <main+53>: movl $0x0,(%esp)
14. 0x0804828c <main+60>: call 0x8048af0 <exit>
I am trying to understand the assembly:
On line 4 the stackpointer is decreased to allocate space for the local variables, but I don't understand why it reserves 32 bytes (0x20=32 bytes)? As I understand it should only have to allocate:
- 4 bytes for the pointer "name"
- 8 bytes for the string "/bin/sh";
- Does NULL also take up space? If so it is equivalent to 0x0 of 4 bytes right?
- The argc and argv are not part of this stackframe right? they are pushed by mains caller and as such don't need to be reserved in this stackframe.
Also I see some data that is being stored at an offset from the stack pointer but it doesn't seem like all the space is being used.
Could someone maybe explain this piece of assembly? I am having troubles mapping the c code to the given assembly instructions. Especially since the lengths of the reserved space doesn' t seem to match with the c code.
I am particularly interested in:
- Line 3: What is this for?
- Line 9: what does this do?
- Line 11 and 13: what does the (%esp) syntax mean?
Thanks!