Stack Frame Assembly - Buffer/garbage space and location of arguments on the stack - Ubuntu x64

0

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.

c
assembly
memory
stack
allocation
asked on Stack Overflow May 30, 2017 by user2985955 • edited May 30, 2017 by user2985955

1 Answer

0

User contributions licensed under CC BY-SA 3.0