C 標準規定數組越界屬於**未定義行為 (UB)**:編譯器不保證報錯,運行時可能正常、數據悄悄損壞、延遲崩潰、甚至看起來正確。這是 C 語言「信任程序員」設計哲學的體現。
#include
#include
int main() {
int a[10];
int i = 0;
while (1) {
a[i++] = i; // 持續向高地址寫入
// 終將覆蓋棧守護頁或關鍵控制數據,觸發段錯誤/棧溢出
}
return 0;
}
運行結果:`Segmentation fault (core dumped)` 或 `Stack overflow`,通常在幾萬次循環後發生。
void victim() {
char buf[8];
// 攻擊者構造輸入覆蓋 buf 後的返回地址
gets(buf); // 危險函數,無長度檢查
// 返回時跳轉到攻擊者指定地址 → 代碼執行漏洞
}
int main() {
victim();
return 0;
}
| 層級 | 措施 |
|---|---|
| 編碼規範 | 禁用 `gets`/`strcpy`/`sprintf`,改用 `fgets`/`strncpy`/`snprintf`/`memcpy_s` |
| 編譯器保護 | 開啟 `-fstack-protector-strong` (GCC/Clang)、`/GS` (MSVC) 棧保護 |
| 運行時檢查 | AddressSanitizer (`-fsanitize=address`) 開發/測試階段必開 |
| 靜態分析 | Cppcheck、Clang Static Analyzer、Coverity 掃描越界風險 |
| 現代 C++ | 用 `std::vector`/`std::array`/`std::string` 替代裸數組,配合 `.at()` 邊界檢查 |
「不報錯」不代表「沒事」。數組越界是 C/C++ 最大安全隱患來源,務必用工具鏈 + 規範雙重防線。