Поделиться через


/guard:ehcont (Включение метаданных продолжения EH)

Включает создание метаданных продолжения EH (EHCONT) компилятором.

Синтаксис

/guard:ehcont[-]

Замечания

Параметр /guard:ehcont приводит к созданию отсортированного списка относительных виртуальных адресов (RVA) всех допустимых целевых объектов продолжения обработки исключений для двоичного файла. Он используется во время выполнения NtContinue и SetThreadContext проверки указателя инструкций. По умолчанию /guard:ehcont отключен и должен быть явно включен. Чтобы явно отключить этот параметр, используйте /guard:ehcont-.

Этот /guard:ehcont параметр доступен в Visual Studio 2019 версии 16.7 и более поздних версий. Эта функция поддерживается для 64-разрядных процессов в 64-разрядной ОС.

Технология принудительного применения потока управления (CET) — это аппаратный компонент безопасности, который защищает от атак на основе возвращаемого программирования (ROP). Он поддерживает "теневой стек" для каждого стека вызовов для обеспечения целостности потока управления.

Если теневые стеки доступны для предотвращения атак ROP, злоумышленники переходят к использованию других методов эксплойтов. Один из способов, которые они могут использовать, заключается в повреждении значения указателя инструкции внутри структуры CONTEXT . Эта структура передается в системные вызовы, которые перенаправляют выполнение потока, например NtContinue, RtlRestoreContextи SetThreadContext. Структура CONTEXT хранится в памяти. Повреждение указателя инструкции, содержащегося в нем, может вызвать системные вызовы для передачи выполнения на управляемый злоумышленником адрес. NTContinue В настоящее время можно вызывать с любой точкой продолжения. Поэтому важно проверить указатель инструкции при включении теневого стека.

RtlRestoreContext и NtContinue используются во время отмены обработки структурированных исключений (SEH) для очистки целевого __except кадра, содержащего блок. Указатель инструкций __except блока не должен находиться в теневом стеке, так как он завершится ошибкой проверки указателя инструкций. Переключатель /guard:ehcont компилятора создает таблицу продолжения EH. Он содержит отсортированный список RVAs всех допустимых целевых объектов обработки исключений в двоичном файле. NtContinue Сначала проверяет теневой стек для указателя инструкции, предоставленного пользователем, и если указатель инструкции не найден там, он продолжает проверять таблицу продолжения EH из двоичного файла, содержащего указатель инструкции. Если содержащий двоичный файл не компилировался с таблицей, то для совместимости с устаревшими двоичными файлами NtContinue разрешено продолжить. Важно различать устаревшие двоичные файлы, у которых нет данных EHCONT, и двоичные файлы, содержащие данные EHCONT, но не записей таблицы. Первый разрешает все адреса внутри двоичного файла в качестве допустимых целевых объектов продолжения. Последний не разрешает какой-либо адрес внутри двоичного файла в качестве допустимого целевого объекта продолжения.

Параметр /guard:ehcont должен быть передан компилятору и компоновщику для создания целевых RVA продолжения EH для двоичного файла. Если двоичный файл создается с помощью одиночной команды cl , компилятор передает параметр в компоновщик. Компилятор также передает /guard:cf параметр компоновщику. При компиляции и связывании отдельно эти параметры необходимо задать как для команд компилятора, так и компоновщика.

Вы можете связать код, скомпилированный с помощью /guard:ehcont библиотек и файлов объектов, скомпилированных без него. Компоновщик возвращает неустранимую ошибку в любом из следующих сценариев:

  • В разделе кода есть "локальная очистка". Дополнительные сведения см. в разделе "Аномальное завершение" в инструкции try-finally.

  • Раздел EH (xdata) содержит указатели на раздел кода, и они не предназначены для SEH.

  • Указатели предназначены для SEH, но файл объекта не компилировался с помощью связывания на уровне функций (/Gy) для создания COMDAT.

Компоновщик возвращает неустранимая ошибку, так как она не может создавать метаданные в этих сценариях. Это означает, что исключение, скорее всего, приведет к сбою во время выполнения.

Сведения о разделе SEH, найденные в COMDATs, но не скомпилированные с помощью /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. Откройте диалоговое окно Страницы свойств проекта. Подробнее см. в статье Настройка компилятора C++ и свойства сборки в Visual Studio.

  2. Перейдите на страницу свойств Свойства конфигурации>C/C++>Создание кода.

  3. Выберите свойство метаданных "Включить продолжение EH".

  4. В раскрывающемся списке выберите "Да" (/guard:ehcont), чтобы включить метаданные продолжения EH или Нет (/guard:ehcont-), чтобы отключить его.

См. также

/guard (включение защиты потока управления)
Параметры компилятора MSVC
Синтаксис командной строки компилятора MSVC