I am doing a simple buffer overflow exercise, here is the source:
//vuln.c
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[]) {
char buf[256];
strcpy(buf,argv[1]);
printf("Input:%s\n",buf);
return 0;
}
Complied with gcc (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609
on Ubuntu 16.04.6 (i686) like this (ASLR disabled):
$ gcc -g -fno-stack-protector -z execstack -o vuln vuln.c
The gdb disassembly:
Dump of assembler code for function main:
0x0804843b <+0>: lea ecx,[esp+0x4]
0x0804843f <+4>: and esp,0xfffffff0
0x08048442 <+7>: push DWORD PTR [ecx-0x4]
0x08048445 <+10>: push ebp
0x08048446 <+11>: mov ebp,esp
0x08048448 <+13>: push ecx
0x08048449 <+14>: sub esp,0x104
0x0804844f <+20>: mov eax,ecx
0x08048451 <+22>: mov eax,DWORD PTR [eax+0x4]
0x08048454 <+25>: add eax,0x4
0x08048457 <+28>: mov eax,DWORD PTR [eax]
0x08048459 <+30>: sub esp,0x8
0x0804845c <+33>: push eax
0x0804845d <+34>: lea eax,[ebp-0x108]
0x08048463 <+40>: push eax
0x08048464 <+41>: call 0x8048310 <strcpy@plt>
0x08048469 <+46>: add esp,0x10
0x0804846c <+49>: sub esp,0x8
0x0804846f <+52>: lea eax,[ebp-0x108]
0x08048475 <+58>: push eax
0x08048476 <+59>: push 0x8048510
0x0804847b <+64>: call 0x8048300 <printf@plt>
0x08048480 <+69>: add esp,0x10
0x08048483 <+72>: mov eax,0x0
0x08048488 <+77>: mov ecx,DWORD PTR [ebp-0x4]
0x0804848b <+80>: leave
0x0804848c <+81>: lea esp,[ecx-0x4]
0x0804848f <+84>: ret
End of assembler dump.
When I am overwriting the EIP with:
aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmmnnnnooooppppqqqqrrrrssssttttuuuuvvvvwwwwxxxxyyyyzzzzAAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUUVVVVWWWWXXXXYYYYZZZZ1111111111111111111111111111111111111111111111111111
It gives me EIP: 0x5a5a5a5a ('ZZZZ')
, meaning that the offset for return address is 208. So how could that be when 256 byte buffer is allocated? How would main() stack layout look like? I thought it should be something like this:
| argc
| argv
| Return address
| Caller's EBP <-- EBP
| Alignment
| Local variables <-- buf ends here
| ...
| Local variables <-- buf starts here
| ...
| ...
| ... <-- ESP
V
Lower addresses
And also I quite confused why I cannot control EIP when the length of the argument string is bigger than 260. Here is what I mean.
This is the result of running gdb-peda$ r `python -c 'print "A"*260'`
This is the result of running gdb-peda$ r `python -c 'print "A"*261'`
And this is the result of running gdb-peda$ r `python -c 'print "A"*262'`
Help is much appreciated. Thanks!