Unfortunately, I don’t have much experience with 64-bit code, so I don’t know about the exact details:

Actually, you don’t need a shadow stack or a stack frame. But some 64-bit functions require `rsp`

to be 16-byte-aligned.

This means that the value of `rsp`

must be a multiple of 16 when a function is called.

If your function looks like this:

```
myFunction:
lea rcx, QWORD PTR [message]
call [print_message] ;it covered return address to bad address
...
```

… then `rsp`

is a multiple of 16 before the instruction `call myFunction`

. And `call myFunction`

pushes 8 bytes to the stack, so `rsp`

is no longer a multiple of 16 (but the value of `rsp`

can be written as 16*n+8).

When you perform `call [print_message]`

, `rsp`

is not a multiple of 16 and the program crashes if the function `print_message`

requires `rsp`

to be 16-byte-aligned.

The instructions `sub rsp, 8`

and `push rbp`

will subtract 8 from the `rsp`

so the value of `rsp`

is a multiple of 16 again.

The background are certain CPU instructions that require an address that is a multiple of 16 as argument. Example:

```
print_message:
sub rsp, 24
; The next instruction will crash if rsp is not
; a multiple of 16. This is the case if rsp was
; not a multiple of 16 before the
; "call print_message" instruction
paddd xmm0, [rsp]
```

CLICK HERE to find out more related problems solutions.