Assembly Register Calling Convention

Hi

In the book, it says:

There are 16 general purpose registers: RAX, RBX, RCX, RDX, RDI, RSI, RSP, RBP and R8 through R15.
With the following Registers used as parameters when a function is called in x64 assembly: RDI, RSI, RDX, RCX, R8 and R9

Q1: Why registers R10 through R15 are not used as parameters? What are they used for?

It also says:

if there are more than 6 parameters, the program’s stack is used to pass in additional parameters to the function

Q2: How the program’s stack is used in this case? How can I find the memory address of the other parameters?

@lolgrep Can you please help with this when you get a chance? Thank you - much appreciated! :]

  1. Generally, the more registers you have, the less stack space you need to create to store variables. In addition, sometimes you want a register’s value to survive across function calls. That’s the R10-R15

  2. The next chapter does a deep dive on this having you do assembly step by step on what is happening. You can find the values of the parameters by examining the stack pointer or base pointer register. However, the offsets can vary since the stack pointer is changing frequently and the base pointer changes at the function prologue and epilogue. If you stopped right at the start of a function, then you can assume that next parameters will be at RSP + 8, since the RSP value will contain a pointer to the return address.

Again, once are you past this point, it’s anyone’s guess to the values since the stack pointer could be pointing to a new location

Thanks @lolgrep for answering!

1 Like

Hi @lolgrep

I have another sort of question, sorry for keeping asking :smile:
I laid out the registers changes over RSP changes, and wrote some observations in Pages file.

I wrote some comments and coloured the cells of what I have learnt through out the section.
Would you mind take a look at it and let me know if I missed out some important observation?

Here’s a screenshot from the Pages file (511.3 KB)

02%20AM

It has 4 questions:

Q1 : When we execute ret , will we RIP = RSP + 0x8 ?
Q2 : Why the book assumes the next RSP will be at RSP + 0x8 ?
Q3 : How do the computer guarantees the return address pointed at by 0x7ffeefbfd758 is 0x8 in size?
Q4 : Are the first 3 rows what is called function prologue ?

  1. It depends where you are in the function:
    Right at the first instruction: no, because the call instruction put the return address on RSP.
(lldb) x/gx $rsp

Now if you were to take one instruction step into the assembly, you’ll likely hit the following line of assembly:

->  0x1032197e0 <+0>:  push   rbp

This will increment RSP (by 8) and put the value of RBP at the top of the stack

So now you would get the return address by

(lldb) x/gx '$rsp + 8'

Following that instruction is the stack pointer gets moved to the base pointer

    0x1032197e1 <+1>:  mov    rbp, rsp

So now, you can reference the return address via

(lldb) x/gx '$rbp + 8'

Now to answer your question: by the time you are executing the ret instruction, the stack pointer will be pointing to the return address. So it RSP will have the return function, not RSP + 0x8. After the ret, the return address is no longer needed, so it gets popped off. When that happens, RSP+=8. By the way, this is a very common attack against C x86 programs. If you can figure out how to write data on the stack (via string input?), you can change control execution to a different function on return.

  1. A pointer is a 64 bit process will 8 bytes. A pointer in a 32 bit process will be 4 bytes. You can verify via the sizeof C function. You can definitely store a 32 bit value in a 64 address, its just the alignment must always be 8 bytes. You will never have a scenario where the stack is returning from a value that is not modulus sizeof(void*)

  2. Sorta answered in 2?

  3. The function prologue can be variable in size. Whatever amount of assembly that is required to setup up the registers and the stack

This topic was automatically closed after 166 days. New replies are no longer allowed.