會偵測某些覆寫傳回位址的緩衝區滿溢 (Buffer Overrun),這是一種利用未強制執行緩衝區大小限制之程式碼的常用技術,這是藉由將安全性檢查插入已編譯的程式碼來達成。
/GS[-]
/GS 預設為開啟。如果您希望應用程式沒有安全性漏洞,請使用 /GS。
如需 /GS 的詳細資訊,請參閱 Compiler Security Checks In DepthCompiler Security Checks In Depth。
此編譯器會插入具有本機字串緩衝區的簽入函式,或是 x86 上具有例外處理的函式。字串緩衝區是定義為陣列,其項目大小是一個或兩個位元組,而整個陣列的大小至少是五個位元組,或任何以 _alloca 配置的緩衝區。
在 所有平台上,如果此函式有本機字串緩衝區,編譯器會插入 Cookie 來保護函式的傳回位址。函式結束碼上,以及在 64 位元作業系統上的框架回溯期間或是在 x86 上有某種形式之例外處理的函式上,會檢查此 Cookie。在 x86 上,編譯器也會插入 Cookie 來保護函式之例外處理常式的位址;在框架回溯期間會檢查這個 Cookie。
/GS 主要會嘗試偵測直接緩衝區滿溢至傳回位址。緩衝區滿溢較容易運用於呼叫慣例的機器,該呼叫慣例會在堆疊上儲存函式呼叫的傳回位址。例如,x86 所使用的呼叫慣例會在堆疊上儲存函式呼叫的傳回位址。
有關編譯器認為可能發生緩衝區滿溢問題的函式,該編譯器會在傳回位址前配置堆疊空間。當函式進入時,這個配置的空間會載入一個會在模組載入時記算一次的安全性 Cookie。然後,在函式離開時,會呼叫 Helper 函式來確定這個 Cookie 的值是否仍然一樣。
如果該值不再相同,可能是發生了堆疊覆寫,處理序只好結束。在 Visual C++ 2005 之前,會顯示一個對話方塊,指出發生了堆疊覆寫的情況。
/GS 也會防止有弱點的參數傳遞至函式。有弱點的參數是指標、C++ 參考,或者是含有指標、字串緩衝區或 C++ 參考的 C 結構 (C++ POD 型別)。
有 弱點的參數會先配置,然後才配置 Cookie 和本機變數。緩衝區滿溢可以覆寫這些參數,函式中使用這些參數的程式碼可能會在函式傳回之前導致發生攻擊,從而避開了安全性檢查。為了將此危險性降到最 低,編譯器會在函式初構期間製作有弱點的參數之複本,並將它們放在任何緩衝區的儲存區域下。
在下列情況中,編譯器不會針對有弱點的參數提供任何安全性保護措施:
-
沒有包含緩衝區的函式
-
在沒有啟用最佳化 (/O 選項 (最佳化程式碼)) 的情況下
-
具有可變個數引數清單 (...) 的函式
-
以 naked (C++) 標記的函式。
-
在第一個陳述式中包含內嵌組譯程式碼的函式
-
在緩衝區滿溢的事件中,如果僅以比較不可能遭利用的方式來使用參數
/GS 需要初始化安全性 Cookie,必須要先初始化這個 Cookie 之後,任何使用此 Cookie 的函式才會執行。一旦進入到 EXE 或 DLL 之後,就必須初始化此安全性 Cookie。當使用預設 CRT 進入點 (mainCRTStartup、wmainCRTStartup、WinMainCRTStartup、wWinMainCRTStartup 或 _DllMainCRTStartup) 時,會自動處理這項作業;如果您使用替代的進入點,則必須透過 __security_init_cookie 的呼叫來以手動方式進行。
當使用 /clr (Common Language Runtime 編譯) 編譯時,Managed 函式會支援 /GS。
/GS 並未保護所有的緩衝區滿溢安全性不受攻擊。例如,如果物件中有緩衝區與 vtable,緩衝區滿溢可能會損毀 vtable 並讓攻擊有機可趁。
即使使用 /GS,仍應致力編寫安全的程式碼。也就是說,請確保程式碼不會發生緩衝區滿溢。如果程式碼中確實有緩衝區滿溢的危險,則 /GS 可以保護您的應用程式。
若要在 Visual Studio 開發環境中設定這個編譯器選項
-
開啟專案的 [屬性 頁] 對話方塊。如需詳細資訊,請參閱 HOW TO:開啟專案屬性頁。
-
按一下 [C/C++] 資料夾。
-
按一下 [程式碼產生] 屬性頁。
-
修改 [緩衝區安全性檢查] 屬性。
若要以程式方式設定這個編譯器選項
參考
編譯器選項設定編譯器選項