Compartir a través de


/guard:ehcont (Habilitar metadatos de continuación EH)

Habilita la generación de metadatos de continuación EH (EHCONT) por parte del compilador.

Sintaxis

/guard:ehcont[-]

Comentarios

La opción /guard:ehcont hace que el compilador genere una lista ordenada de las direcciones virtuales relativas (RVA) de todos los destinos de continuación de control de excepciones válidos para un binario. Se usa durante el tiempo de ejecución para la validación del puntero de instrucción NtContinue y SetThreadContext. La opción /guard:ehcont está desactivada de forma predeterminada y debe habilitarse explícitamente. Para deshabilitar explícitamente esta opción, utilice /guard:ehcont-.

La opción /guard:ehcont está disponible en Visual Studio 2019, versión 16.7 y posteriores. La característica es compatible con procesos de 64 bits en un sistema operativo de 64 bits.

La tecnología de cumplimiento del flujo de control (CET) es una característica de seguridad basada en hardware que protege frente a los ataques basados en la programación orientada al retorno (ROP). Mantiene una "pila paralela" para cada pila de llamadas con el fin de reforzar la integridad del flujo de control.

Cuando las pilas paralelas están disponibles para evitar los ataques ROP, los atacantes pasan a usar otras técnicas de vulnerabilidad de seguridad. Una técnica que pueden usar es dañar el valor del puntero de instrucción dentro de la estructura CONTEXT. Esta estructura pasa a las llamadas del sistema que redirigen la ejecución de un subproceso, como NtContinue, RtlRestoreContexty SetThreadContext. La estructura CONTEXTse almacena en la memoria. Dañar el puntero de instrucción que lo contiene puede hacer que las llamadas del sistema transfieran la ejecución a una dirección controlada por el atacante. Actualmente, NTContinue se puede llamar con cualquier punto de continuación. Por eso es esencial validar el puntero de instrucción cuando se habilitan las pilas paralelas.

RtlRestoreContext y NtContinue se usan durante el desenredo del Control de excepciones estructurado (SEH) para desenredarlo en el marco de destino que contiene el bloque __except. No se espera que el puntero de instrucción del bloque __except esté en la pila paralela, ya que produciría un error en la validación del puntero de instrucción. El modificador del compilador /guard:ehcont genera una "tabla de continuación de EH". Contiene una lista ordenada de los RVA de todos los destinos de continuación de control de excepciones válidos en el archivo binario. NtContinue comprueba primero la pila paralela en busca del puntero de instrucción proporcionado por el usuario y, si no lo encuentra allí, continúa con la comprobación de la tabla de continuación de EH del binario que contiene el puntero de instrucción. Si el binario que lo contiene no se compiló con la tabla, entonces, por compatibilidad con los archivos binarios heredados, se le permite continuar a NtContinue. Es importante distinguir entre los archivos binarios heredados que no tienen datos EHCONT y los archivos binarios que contienen datos EHCONT, pero no tienen entradas en la tabla. El primero permite que todas las direcciones dentro del archivo binario sean destinos de continuación válidos. Este último no permite ninguna dirección dentro del archivo binario como destino de continuación válido.

La opción /guard:ehcont debe pasarse tanto al compilador como al enlazador para generar las RVA de destino de continuación de EH para un archivo binario. Si el archivo binario se compila mediante un único comando cl , el compilador pasa la opción al vinculador. El compilador también pasa la opción /guard:cf al enlazador. Si compila y vincula por separado, estas opciones deben establecerse en los comandos del compilador y del enlazador.

Puede vincular el código compilado mediante /guard:ehcont a las bibliotecas y los archivos objeto compilados sin él. El enlazador devuelve un error irrecuperable en uno de estos escenarios:

  • Una sección de código tiene "desenredado local". Para obtener más información, consulte Terminación anómala en laInstrucción try-finally.

  • Una sección EH (xdata) contiene los punteros a una sección de código que no son para SEH.

  • Los punteros son para SEH, pero el archivo objeto no se compiló mediante la vinculación de nivel de función (/Gy) para generar COMDAT.

El enlazador devuelve un error irrecuperable porque no puede generar los metadatos en estos escenarios. Esto significa que lanzar una excepción puede causar un bloqueo en tiempo de ejecución.

Para la información de la sección SEH que se encuentra en COMDAT, pero no compilada mediante /guard:ehcont, el enlazador emite la advertencia LNK4291. En este caso, el enlazador genera los metadatos correctos aunque conservadores para la sección. Para omitir esta advertencia, use /IGNORE (Omitir las advertencias específicas).

Si el enlazador no puede generar los metadatos, emite uno de los siguientes errores:

  • 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.

Para comprobar si un archivo binario contiene los datos EHCONT, busque los siguientes elementos al volcar la configuración de carga del binario:

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
...

Para establecer esta opción del compilador en el entorno de desarrollo de Visual Studio

  1. Abra el cuadro de diálogo Páginas de propiedades del proyecto. Para más información, vea Establecimiento del compilador de C++ y de propiedades de compilación en Visual Studio.

  2. Seleccione la página de propiedades Propiedades de configuración>C/C++>Generación de código.

  3. Seleccione la propiedad Habilitar metadatos de continuación EH.

  4. En el control desplegable, elija Sí (/guard:ehcont) para habilitar los metadatos de continuación EH o No (/guard:ehcont-) para deshabilitarlo.

Consulte también

/guard (Habilitar Protección de flujo de control)
Opciones del compilador de MSVC
Sintaxis de la línea de comandos del compilador MSVC