共用方式為


/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++ > 程式碼產生 ] 屬性頁。

  3. 選取 [ 啟用 EH 接續中繼資料 ] 屬性。

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

另請參閱

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