C/C++ 直接記憶體操作帶來高效能,也引入緩衝區溢位、指標竄改等風險。MSVC 提供編譯器/連結器層面的多重防護,預設開啟多數選項,構建「纈深防禦」體系。
/GS (Buffer Security Check)alloca、_alloca 的函式。/GS (預設開啟),/GS- 關閉。/SAFESEH (Safe Exception Handlers)/SAFESEH (預設開啟),/SAFESEH:NO 關閉。/NXCOMPAT (DEP 相容)IMAGE_DLLCHARACTERISTICS_NX_COMPAT 旗標,告知 OS 此模組相容 DEP。/NXCOMPAT (預設開啟),/NXCOMPAT:NO 關閉。VirtualAlloc(..., PAGE_EXECUTE_READWRITE))。/DYNAMICBASE (ASLR)IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE,要求 OS 隨機化基址。/DYNAMICBASE (預設開啟),/DYNAMICBASE:NO 關閉。/FIXED:NO (預設),強制固定基址會失效 ASLR。strcpy, sprintf, gets 等不檢查緩衝區長度。strcpy_s, sprintf_s, gets_s 等 `_s` 後綴版本,需傳遞目的緩衝區大小。_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 讓標準名稱自動對應安全版本,或 _CRT_SECURE_NO_WARNINGS 抑制警告 (不推薦)。
char dst[32];
strcpy_s(dst, _countof(dst), "Hello"); // 安全
// strcpy(dst, "Hello"); // 警告 C4996
operator new 失敗處理new 失敗拋出 std::bad_alloc。new (std::nothrow) 失敗回傳 nullptr,適合不支援例外的環境。new_handler (std::set_new_handler) 可在記憶體不足時嘗試釋放快取、記錄日誌、終止程式。
/GS /GL /analyze /W4 /WX /sdl
/SAFESEH /NXCOMPAT /DYNAMICBASE
/D_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1
/guard:cf // Control Flow Guard (VS2015+)
/guard:ehcont // EH Continuation Guard (VS2022+)
/CETCOMPAT // Intel CET Shadow Stacks (VS2022+)
| 技術 | 常見繞過手法 | 補充防禦 |
|---|---|---|
| /GS | Cookie 洩漏 (資訊洩漏)、例外處理器覆寫、長跳轉 (longjmp) 繞過驗證 | /SAFESEH, /guard:cf, 靜態分析 (/analyze) |
| DEP | ROP (Return-Oriented Programming)、JIT 噴射 | ASLR, CFG, CET |
| ASLR | 資訊洩漏揭露基址、部分模組未啟用 ASLR | 強制所有模組 /DYNAMICBASE, 核心模組隨機化 |
| SafeSEH | 僅限 x86,x64 不適用 | x64 使用 UNWIND_INFO + CFG |
MSVC 的 /GS、/SAFESEH、/NXCOMPAT、/DYNAMICBASE、安全 CRT、/guard:cf 等機制構建多層防禦,**預設開啟**即可獲得基礎保護。但**沒有任何單一機制能完全阻止攻擊**,必須結合安全編碼規範 (CERT C++、C++ Core Guidelines)、靜態分析 (/analyze、Coverity、SonarQube)、模糊測試 (AFL、libFuzzer) 並定期更新工具鏈,才能將風險降至最低。