共用方式為


/guard:ehcont (啟用 EH 接續元資料)

可讓編譯程式產生 EH 接續 (EHCONT) 元數據。

語法

/guard:ehcont[-]

備註

選項 /guard:ehcont 會使編譯程式產生二進位檔之所有有效例外狀況處理接續目標的相對虛擬位址 (RVA) 排序列表。 它會在運行時間期間用於 NtContinue 指示 SetThreadContext 指標驗證。 默認為 /guard:ehcont off,且必須明確啟用。 若要明確停用這個選項,請使用 /guard:ehcont-

此選項 /guard:ehcont 適用於Visual Studio 2019 16.7版和更新版本。 64 位作業系統上的64位進程支援此功能。

控制流程強制執行技術 (CET) 是以硬體為基礎的安全性功能,可防範以傳回為導向的程式設計(ROP)型攻擊。 它會維護每個呼叫堆疊的「陰影堆疊」,以強制執行控制流程完整性。

當陰影堆疊可用來防止 ROP 攻擊時,攻擊者會繼續使用其他惡意探索技術。 他們可以使用的其中一個技巧是損毀CONTEXT結構內的指令指標值。 這個結構會傳遞至系統呼叫,以重新導向線程的執行,例如 NtContinueRtlRestoreContextSetThreadContext。 結構 CONTEXT 會儲存在記憶體中。 損毀它所包含的指令指標可能會導致系統呼叫將執行傳送至攻擊者控制的位址。 目前可以使用 NTContinue 任何接續點呼叫。 這就是為什麼在啟用陰影堆疊時驗證指令指標是必要的。

RtlRestoreContextNtContinue 會在結構化例外狀況處理 (SEH) 例外狀況回溯期間使用,以回溯至包含 __except 區塊的目標框架。 區塊的 __except 指令指標不應該位於陰影堆疊上,因為它會失敗指令指標驗證。 編譯程序 /guard:ehcont 參數會產生「EH 接續表」。 它包含二進位檔中所有有效例外狀況處理接續目標的 RVA 排序列表。 NtContinue 首先檢查使用者提供的指令指標的陰影堆疊,如果找不到該指令指標,它會繼續從包含指令指標的二進位檔檢查 EH 接續表。 如果未使用數據表編譯包含的二進位檔,則允許繼續與舊版二進位檔 NtContinue 相容。 請務必區分沒有 EHCONT 數據的舊版二進位檔,以及包含 EHCONT 數據的二進位檔,但沒有數據表專案。 前者允許二進位檔內的所有位址作為有效的接續目標。 後者不允許二進位檔內的任何位址作為有效的接續目標。

選項 /guard:ehcont 必須傳遞至編譯程式和連結器,以產生二進位檔的EH接續目標 RVA。 如果您的二進位檔是使用單一 cl 命令建置,則編譯器會將選項傳遞給連結器。 編譯程式也會將 選項傳遞 /guard:cf 至連結器。 如果您個別編譯和連結,則必須在編譯程式和連結器命令上設定這些選項。

您可以使用 將編譯的程式代碼 /guard:ehcont 連結至未編譯的連結庫和物件檔案。 連結器會在下列任何案例中傳回嚴重錯誤:

  • 程序代碼區段具有「本機回溯」。 如需詳細資訊,請參閱 try-finally 語句中的異常終止。

  • EH (xdata) 區段包含程式碼區段的指標,且不適用於 SEH。

  • 指標適用於 SEH,但對象檔並未使用函式層級連結 (/Gy) 進行編譯,以產生 COMDAT。

鏈接器會傳回嚴重錯誤,因為它無法在這些案例中產生元數據。 這表示擲回例外狀況可能會導致運行時間當機。

若為 COMDAT 中找到的 SEH 區段資訊,但未使用 /guard:ehcont編譯,鏈接器會發出警告 LNK4291。 在此情況下,鏈接器會產生正確但保守的區段元數據。 若要忽略此警告,請使用 /IGNORE (忽略特定警告)。

如果連結器無法產生元數據,它會發出下列其中一個錯誤:

  • LNK2046: module contains _local_unwind but was not compiled with /guard:ehcont

  • LNK2047: module contains C++ EH or complex EH metadata but was not compiled with /guard:ehcont.

若要檢查二進位檔是否包含 EHCONT 數據,請在傾印二進位檔的載入設定時尋找下列元素:

e:\>link /dump /loadconfig CETTest.exe
...
            10417500 Guard Flags
...
                       EH Continuation table present      // EHCONT guard flag present
...
    0000000180018640 Guard EH continuation table
                  37 Guard EH continuation count          // May be 0 if no exception handling is used in the binary. Still counts has having EHCONT data.
...
    Guard EH Continuation Table                           // List of RVAs

          Address
          --------
           0000000180002CF5
           0000000180002F03
           0000000180002F0A
...

在 Visual Studio 開發環境中設定這個編譯器選項

  1. 開啟專案的 [屬性頁] 對話方塊。 如需詳細資料,請參閱在 Visual Studio 中設定 C ++ 編譯器和組建屬性

  2. 選取 [組態屬性>C/C++>Code 產生] 屬性頁。

  3. 選取 [ 啟用 EH 接續元數據 ] 屬性。

  4. 在下拉式清單中,選擇 [是] (/guard:ehcont) 以啟用 EH 接續元數據,或 [否] (/guard:ehcont-) 將其停用。

另請參閱

/guard (啟用控制流程防護)
MSVC 編譯器選項
MSVC 編譯器命令列語法