Skip to content

Latest commit

 

History

History
87 lines (73 loc) · 2.88 KB

2019-03-20-64bits.md

File metadata and controls

87 lines (73 loc) · 2.88 KB
title date categories layout
Introducing 64-bit ELF Binaries
2019-03-20 02:05:00 -0700
information
post

So far we've been focusing primarily on 32-bit binaries; however, what you've learned so far will also apply to 64-bit binaries with a few key differences. Let's summarize a few of the differences seen in the 64-bit version of stack5 (shown below).

  • the location of the code region is much different
  • the pointer sizes are different.
  • the arguments to main are passed via registers (rdi and rsi) and then saved to the stack (inside of main).
  • there is a canary in place and it uses a segment register
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
  char buffer[64];

  gets(buffer);
}
   0x0000000000400596 <+0>:     push   rbp
   0x0000000000400597 <+1>:     mov    rbp,rsp
   0x000000000040059a <+4>:     sub    rsp,0x60
   0x000000000040059e <+8>:     mov    DWORD PTR [rbp-0x54],edi
   0x00000000004005a1 <+11>:    mov    QWORD PTR [rbp-0x60],rsi
   0x00000000004005a5 <+15>:    mov    rax,QWORD PTR fs:0x28
   0x00000000004005ae <+24>:    mov    QWORD PTR [rbp-0x8],rax
   0x00000000004005b2 <+28>:    xor    eax,eax
   0x00000000004005b4 <+30>:    lea    rax,[rbp-0x50]
   0x00000000004005b8 <+34>:    mov    rdi,rax
   0x00000000004005bb <+37>:    mov    eax,0x0
   0x00000000004005c0 <+42>:    call   0x400480 <gets@plt>
   0x00000000004005c5 <+47>:    mov    eax,0x0
   0x00000000004005ca <+52>:    mov    rdx,QWORD PTR [rbp-0x8]
   0x00000000004005ce <+56>:    xor    rdx,QWORD PTR fs:0x28
   0x00000000004005d7 <+65>:    je     0x4005de <main+72>
   0x00000000004005d9 <+67>:    call   0x400460 <__stack_chk_fail@plt>
   0x00000000004005de <+72>:    leave
   0x00000000004005df <+73>:    ret

x86-64 Register Conventions

Below is a table of naming and usage conventions for the general purpose registers in the x86-64 architecture. The first row is the number of bits specified by the particular register label.

64      32      16    8 
rax     eax     ax    al     return value
rbx     ebx     bx    bl     callee saved 
rcx     ecx     cx    cl     4th argument 
rdx     edx     dx    dl     3rd argument
rsi     esi     si    sil    2nd argument
rdi     edi     di    dil    1st argument 
rbp     ebp     bp    bpl    callee saved 
rsp     esp     sp    spl    stack pointer 
r8      r8d     r8w   r8b    5th argument 
r9      r9d     r9w   r9b    6th argument 
r10     r10d    r10w  r10b   caller saved 
r11     r11d    r11w  r11b   caller saved 
r12     r12d    r12w  r12b   callee saved 
r13     r13d    r13w  r13b   callee saved 
r14     r14d    r14w  r14b   callee saved 
r15     r15d    r15w  r15b   callee saved 

Note: Intstructions that generate 1- or 2-byte values leave the higher order bytes unchanged. Instructions that generate 4-byte values zero out the upper bytes.