緩衝區溢位是 C/C++ 程式最常見的嚴重弱點。駭客透過精心構造的輸入覆寫堆疊上的返回位址或異常處理器指標,劫持程式執行流程。著名的 Code Red、Slammer、Blaster 病毒皆源於此。
| 版本 | 技術 | 防護重點 |
|---|---|---|
| VC6.0 | 無 | 完全無防護 |
| VC7.0 (VS.NET 2002) | /GS (Security Cookie) | 堆疊 Cookie 偵測返回位址竄改 |
| VC7.1 (VS.NET 2003) | /GS + /SAFESEH | 移動 SEH 記錄至緩衝區下方 + 安全 SEH 驗證 |
| VC8.0 (VS2005) | /GS 強化 | 函數參數複製到區域變數下方,防護函數指標參數竄改 |
| VS2010+ | /GS + /sdl + /guard:cf | 控制流程防護 (CFG)、更嚴格的 SDL 檢查 |
__report_gsfailure → 觸發安全錯誤處理常式 → 終止程式
// 簡化版堆疊佈局 (高位址 → 低位址)
[函數參數]
[返回位址] ← 攻擊目標
[儲存的 EBP]
[Security Cookie] ← /GS 插入
[區域變數/緩衝區] ← 溢位源頭

#include
#include
void __cdecl MySecHandler(int code, void*) {
if (code == _SECERR_BUFFER_OVERRUN) {
printf("偵測到緩衝區溢位!\n");
exit(1);
}
}
int main() {
_set_security_error_handler(MySecHandler);
// ... 程式主體
}
若函數參數包含函數指標或含函數指標的結構體,編譯器會在區域變數區複製一份參數。原始參數若被溢位覆寫,複製本仍完好,函數內部使用複製本,繞過攻擊。
/NXCOMPAT (VS2005+) 標記 PE 相容 DEPstrcpy_s, sprintf_s, memcpy_s...)/analyze + Code Analysis 規則集/GS 不是萬靈丹,但以極低成本(重新編譯即可)大幅提高攻擊門檻。結合安全程式碼撰寫習慣、靜態分析、硬體 DEP,構建多層防禦,才是現代 C/C++ 安全開發的正確路徑。