防止stack buffer overflows攻击的方法 : ShadowCallStack
快速鏈接:
.
👉👉👉 個人博客筆記導讀目錄(全部) 👈👈👈
目錄
- 1、介紹
- 2、用法
- 3、相關API
- (1)、__has_feature(shadow_call_stack)
- (2)、__attribute__((no_sanitize("shadow-call-stack")))
- 4、示例
- 5、總結
- 6、參考
1、介紹
ShadowCallStack 是一個檢測通道,目前只為 aarch64 實現,它可以保護程序免受返回地址覆蓋(例如堆棧緩沖區溢出 : stack buffer overflows)。它的工作原理是將函數的返回地址保存到函數序言中單獨分配的“shadow call stack”,子函數并從函數結語中的shadow call stack加載返回地址。
2、用法
要啟用 ShadowCallStack,只需將-fsanitize=shadow-call-stack 標志傳遞給編譯和鏈接命令行。在 aarch64 上,默認使用x18,即-ffixed-x18。
3、相關API
(1)、__has_feature(shadow_call_stack)
在某些情況下,可能需要根據是否啟用 ShadowCallStack 來執行不同的代碼。宏__has_feature(shadow_call_stack)可用于此目的
#if defined(__has_feature) # if __has_feature(shadow_call_stack) // code that builds only under ShadowCallStack # endif #endif(2)、attribute((no_sanitize(“shadow-call-stack”)))
用于__attribute__((no_sanitize("shadow-call-stack")))函數聲明以指定ShadowCallStack檢測不應應用于該函數
4、示例
示例代碼
int foo() {return bar() + 1; }編譯時生成以下 aarch64 程序集
stp x29, x30, [sp, #-16]! mov x29, sp bl bar add w0, w0, #1 ldp x29, x30, [sp], #16 ret添加-fsanitize=shadow-call-stack將輸出以下程序集
str x30, [x18], #8 stp x29, x30, [sp, #-16]! mov x29, sp bl bar add w0, w0, #1 ldp x29, x30, [sp], #16 ldr x30, [x18, #-8]! ret5、總結
傳統的aarch64程序,在一進入子函數時,就會將LR、FP(x30、x29)保存到SP指向的棧中,在函數結束返回之前,再從棧中恢復這兩個寄存器。
然后加入-fsanitize=shadow-call-stack編譯選項后,在一進入子函數時,增加一步驟將LR(X30)也保存到X18寄存器指向的地址中,在函數返回時,再從X18指向的地址處恢復LR。
這種使用單獨的地址(X18指向的地址)來保存LR的值,就可以有效地避免了stack buffer overflows對LR值的攻擊
6、參考
Clang 13 documentation
總結
以上是生活随笔為你收集整理的防止stack buffer overflows攻击的方法 : ShadowCallStack的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android Keystore/key
- 下一篇: 防止stack buffer overf