I am currently reading the book Hacking: The Art of Exploitation by Jon Erickson. I'm following along with the exercises on an x64 Ubuntu 16.04.2 system rather than the virtual machine provided by the book in an effort to bolster my understanding by forcing me to research differences between machines, and 32 and 64 bit systems. I'm currently towards the beginning of the book, and learning about stack frame assembly, but I was confused about the results I got when running this on my machine. When using GCC to compile the code:
void test_function(int a, int b, int c, int d) {
int flag;
char buffer[10];
flag = 31337;
buffer[0] = 'A';
}
int main() {
test_function(1, 2, 3, 4);
}
I am given the assembly:
Dump of assembler code for function main:
0x000000000040058b <+0>: push rbp
0x000000000040058c <+1>: mov rbp,rsp
0x000000000040058f <+4>: mov ecx,0x4
0x0000000000400594 <+9>: mov edx,0x3
0x0000000000400599 <+14>: mov esi,0x2
0x000000000040059e <+19>: mov edi,0x1
0x00000000004005a3 <+24>: call 0x400546 <test_function>
0x00000000004005a8 <+29>: mov eax,0x0
0x00000000004005ad <+34>: pop rbp
0x00000000004005ae <+35>: ret
Dump of assembler code for function test_function:
0x0000000000400546 <+0>: push rbp
0x0000000000400547 <+1>: mov rbp,rsp
0x000000000040054a <+4>: sub rsp,0x40
0x000000000040054e <+8>: mov DWORD PTR [rbp-0x34],edi
0x0000000000400551 <+11>: mov DWORD PTR [rbp-0x38],esi
0x0000000000400554 <+14>: mov DWORD PTR [rbp-0x3c],edx
0x0000000000400557 <+17>: mov DWORD PTR [rbp-0x40],ecx
0x000000000040055a <+20>: mov rax,QWORD PTR fs:0x28
0x0000000000400563 <+29>: mov QWORD PTR [rbp-0x8],rax
0x0000000000400567 <+33>: xor eax,eax
0x0000000000400569 <+35>: mov DWORD PTR [rbp-0x24],0x7a69
0x0000000000400570 <+42>: mov BYTE PTR [rbp-0x20],0x41
0x0000000000400574 <+46>: nop
0x0000000000400575 <+47>: mov rax,QWORD PTR [rbp-0x8]
0x0000000000400579 <+51>: xor rax,QWORD PTR fs:0x28
0x0000000000400582 <+60>: je 0x400589 <test_function+67>
0x0000000000400584 <+62>: call 0x400420 <__stack_chk_fail@plt>
0x0000000000400589 <+67>: leave
0x000000000040058a <+68>: ret
Using GDB to set a break point at test_function, I look at the memory to see the way the stack frame was constructed.
(gdb) x/20hw $rsp
0x7fffffffddd0: 0x00000004 0x00000003 0x00000002 0x00000001
0x7fffffffdde0: 0x00000001 0x00000000 0x004005fd 0x00000000
0x7fffffffddf0: 0x00000000 0x00000000 0x00000000 0x00000000
0x7fffffffde00: 0x004005b0 0x00000000 0x00400450 0x00000000
0x7fffffffde10: 0xffffde20 0x00007fff 0x004005a8 0x00000000
And the registers are set to:
(gdb) i r rip rsp rbp
rip 0x40055a 0x40055a <test_function+20>
rsp 0x7fffffffddd0 0x7fffffffddd0
rbp 0x7fffffffde10 0x7fffffffde10
My question is, why are the arguments to the function located at memory address 0x7fffffffddd0 through 0x7fffffffdddf while the saved frame pointer is at 0x7fffffffde10 and the return address is at 0x7fffffffde18. I would think that these values would be stored right next to each other in memory, but for some reason the compiler stores the arguments a full 64 bits away.
Initially I thought that this might be an alignment issue, and that the free space might be buffer space, but from what I gathered online, memory tends to be aligned on 16 bit intervals, not on 64 bit. If memory is aligned on 16 bit intervals, then why aren't the arguments stored at 0x7fffffffde00 through 0x7fffffffde0f?
Furthermore, does the space between the return addresses and the parameters have any significance, or is this just junk data? The values at 0x7fffffffdde8, 0x7fffffffde00 and 0x7fffffffde08 seem to be a bit interesting for they seems to be memory addresses in the text segment of memory, but it is also possible that this is a consequence of allocating buffer space on a commonly used segment of the stack.
You are likely seeing the "red zone."
See https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-r252.pdf
The tag wiki at https://stackoverflow.com/tags/x86/info has a lot of great links.
And this talks about the red zone https://softwareengineering.stackexchange.com/questions/230089/what-is-the-purpose-of-red-zone
User contributions licensed under CC BY-SA 3.0