AddressSanitizer 陰影位元組
我們簡短摘要說明陰影位元組的概念,以及運行時間實 /fsanitize=address
作如何使用它們。 如需進一步的詳細數據,請參閱初始研究 AddressSanitizer - Serebryany 等和目前的 AddressSanitizer 演算法檔。
核心概念
您可以使用一個陰影位元組來描述您應用程式虛擬位址空間中的每 8 個字節。
一個陰影位元組描述目前可存取的位元組數目,如下所示:
- 0 表示所有 8 個字節
- 1-7 表示一到七個字節
- 負數編碼運行時間用於報告診斷的內容。
陰影位元組圖例
請考慮定義所有負數的這個陰影位元組圖例:
對應 ─ 描述您的地址空間
應用程式虛擬位址空間中對齊 「0-mod-8」 的每個 8 個字節,都可以對應至描述虛擬位址空間中該位置的陰影位元組。 此對應可以透過簡單的移位和新增來完成。
在 x86 上:
char shadow_byte_value = *((Your_Address >> 3) + 0x30000000)
在 x64 上:
char shadow_byte_value = *((Your_Address >> 3) + _asan_runtime_assigned_offset)
程式代碼產生 - 測試
請考慮編譯程式產生的程式代碼、靜態數據或運行時間可能會寫入特定陰影位元組的方式。 此虛擬程式代碼示範如何產生任何負載或存放區前面的檢查:
ShadowAddr = (Addr >> 3) + Offset;
if (*ShadowAddr != 0) {
ReportAndCrash(Addr);
}
檢測小於8個字節的記憶體參考時,檢測會稍微複雜一點。 如果陰影值是正數(這表示只能存取 8 位元元中的第一個 K 位元組),我們需要比較地址的最後 3 位與 k。
ShadowAddr = (Addr >> 3) + Offset;
k = *ShadowAddr;
if (k != 0 && ((Addr & 7) + AccessSize > k)) {
ReportAndCrash(Addr);
}
運行時間和編譯程式產生的程式代碼都會寫入陰影位元組。 當範圍結束或記憶體釋出時,這些陰影位元組會允許或撤銷存取權。 上述檢查會讀取陰影位元組,以描述應用程式地址空間中的8位元組「位置」,在程式執行的特定時間。 除了這些明確產生的檢查之外,運行時間也會在攔截CRT中的許多函式之後檢查陰影位元組。
如需詳細資訊,請參閱攔截的 函式清單。
設定陰影位元組
編譯程式產生的程序代碼和 AddressSanitizer 運行時間都可以寫入陰影位元組。 例如,編譯程式可以設定陰影位元組,以允許固定大小的存取內部範圍中定義的堆疊局部變數。 運行時間可以使用陰影位元組括住數據區段中的全域變數。
另請參閱
AddressSanitizer 概觀
AddressSanitizer 已知問題
AddressSanitizer 組建和語言參考
AddressSanitizer 運行時間參考
AddressSanitizer 雲端或分散式測試
AddressSanitizer 調試程式整合
AddressSanitizer 錯誤範例