Search code examples
assemblyx86-64cpu-registersexploit

RIP register size


I've been studying binary exploitation and recently I found a problem that I cannot find an answer for... I have the following code:

void vuln(char *s) {
   char buf[10];
   strcpy(buf, s);
}

int main (int argc, char** argv) {
   vuln(argv[1]);
   printf("YOU LOSE!\n");
   return 0;
}

The strcpy call allows me to exploit a buffer overflow so I can override the RBP and RIP registers... the thing is send 10 'A' to fill the buffer, 8 'B' to fill the RBP and only 6 'C' to fill the RIP?! I cannot understand why only 6 bytes are needed instead of 8, which is the register size (64bit platform)


Solution

  • Could be a duplicate of Why do x86-64 systems have only a 48 bit virtual address space?, but the saved/future RIP (return address) is 64-bit, you just don't need to write the two high zeros. You can only write one anyway, as the terminating zero byte for the C string.

    x86-64 only uses 48 of the 64 bits, and user-space is the low half of the 48-bit "canonical" range of virtual address space. So the top 2 bytes of a return address are already zero. See Why in x86-64 the virtual address are 4 bits shorter than physical (48 bits vs. 52 long)? and related: What is the difference between the ret instruction in x86 and x64?