這個問題在這里已經有了答案: 陰影空間示例 2 個答案 為什么 x86-64 / AMD64 System V ABI 要求 16 位元組堆疊對齊? (1 個回答) 5 天前關閉。
(對不起我的英語不好,因為我來自韓國)
我試過這段代碼
lea rcx, QWORD PTR [message]
call [print_message] ;it covered return address to bad address
xor rcx, rcx
ret
并墜毀......
在那之后,我嘗試了另一種方式
sub rsp, 8 ;shadow stack
lea rcx, QWORD PTR [message]
call [print_message]
add rsp, 8
ret
; stack frame
push rbp
mov rbp, rsp
lea rcx, QWORD PTR [message]
call [print_message]
mov rsp, rbp
pop rbp
ret
這兩個代碼可以作業,但問題是......,為什么程式需要這些東西?
這讓我很好奇
問題出在哪里的真實代碼
extern __imp_MessageBoxA : QWORD
.data
message db "1234", 0
.code
entry_point proc
sub rsp, 8
xor ecx, ecx
lea rdx, QWORD PTR [message]
lea r8, QWORD PTR [message]
mov r9, 0
call [__imp_MessageBoxA] ;stdcall
add rsp, 8
ret
entry_point endp
end
uj5u.com熱心網友回復:
不幸的是,我對 64 位代碼沒有太多經驗,所以我不知道確切的細節:
實際上,您不需要影子堆疊或堆疊幀。但是一些 64 位函式需要rsp16 位元組對齊。
這意味著rsp呼叫函式時的值必須是 16 的倍數。
如果您的函式如下所示:
myFunction:
lea rcx, QWORD PTR [message]
call [print_message] ;it covered return address to bad address
...
... thenrsp是指令前 16 的倍數call myFunction。和call myFunction推8個位元組到堆疊,所以rsp不再是16的倍數(但的值rsp可被寫為16×N 8)。
當你執行call [print_message],rsp不是 16 的倍數時,如果函式print_message需要rsp16 位元組對齊,程式就會崩潰。
指令sub rsp, 8andpush rbp將從中減去 8,rsp因此 的值rsp再次是 16 的倍數。
背景是某些 CPU 指令需要一個 16 的倍數的地址作為引數。例子:
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]
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/406280.html
標籤:
上一篇:堆疊的裝配使用
下一篇:如何在MIPS中釋放堆記憶體
