2007年8月12日 星期日

編譯器選項,緩衝區安全性檢查

Visual C++ 編譯器選項
/GS (緩衝區安全性檢查)

會偵測某些覆寫傳回位址的緩衝區滿溢 (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 開發環境中設定這個編譯器選項

  1. 開啟專案的 [屬性 頁] 對話方塊。如需詳細資訊,請參閱 HOW TO:開啟專案屬性頁

  2. 按一下 [C/C++] 資料夾。

  3. 按一下 [程式碼產生] 屬性頁。

  4. 修改 [緩衝區安全性檢查] 屬性。

若要以程式方式設定這個編譯器選項

請參閱

參考

編譯器選項
設定編譯器選項