Source Code:
char buf[256];
int main(int argv,char **argc) {
char *pbuf=(char*)malloc(256);
// gets(buf);
strcpy(buf,argc[1]);
free(pbuf);
}
Memory Layout Diagram:
+--------------+ <---0x08049680
|AAAAAAAAAAAAAA| \
|AAAAAAAAAAAAAA| |
|AAAAAAAAAAAAAA| |
|AAAAAAAAAAAAAA| |<--buf[256] (2440 Bytes?!?)
|AAAAAAAAAAAAAA| |
|AAAAAAAAAAAAAA| |
|AAAAAAAAAAAAAA| /
+--------------+ <---0x0804a008
| 0xFFFFFFFC | \
+--------------+ |
| 0xFFFFFFFC | |
+--------------+ |<---pbuf
| AAAAAAAA | |
+--------------+ |
| .dtors - 12 | |
+--------------+ |
| shellcode | /
+--------------+
Size is set to 0xfffffffc (so LSB is 0)
Prev_Size is set to 0xfffffffc
Previous chunk pointer is calculated like this:
0x0804a008 - (0xfffffffc) = 0x0804a00c (rather than 0x08049680)
The "fake chunk" must be at 0x0804a00c
-prev_size and size can be anything (use 0xfffffffc)
-unlink() writes 8 bytes of garbage to 0x08049680, so put 8B of garbage before shellcode
-unlink() writes 4 bytes to bk+8, so you need an \xeb\x0c after 8B to jump over it
-fd points to .dtors - 12
-bk points to buf+8