Compartir a través de


Advertencia C30030

Llamar a una función de asignación de memoria y pasar un parámetro que indica la memoria ejecutable

Algunas API tienen parámetros que configuran si la memoria es ejecutable o no. Este error indica que se usan parámetros que dan lugar a que se asigne el ejecutable NonPagedPool.

Comentarios

Debe usar una de las opciones disponibles para solicitar memoria no ejecutable. Una lista de todas las funciones y marcas prohibidas cubiertas por este error y los reemplazos recomendados se pueden encontrar en la parte inferior de esta página.

Nombre del análisis de cose: BANNED_MEM_ALLOCATION_UNSAFE

Para defectos relacionados con los tipos de parámetros MM_PAGE_PRIORITY y POOL_TYPE

Use una de las siguientes opciones:

  • Especifique la definición del preprocesador POOL_NX_OPTIN_AUTO en la configuración de orígenes o proyectos.
  • Especifique la definición del preprocesador POOL_NX_OPTIN en la configuración de orígenes o proyectos y llame a ExInitializeDriverRuntime(DrvRtPoolNxOptIn) desde la función de inicialización del controlador (DriverEntry o DllInitialize).

Nota La elección de si se va a usar POOL_NX_OPTIN_AUTO o POOL_NX_OPTIN depende en gran medida de la plataforma que tenga como destino y de cuántos archivos binarios esté realizando. Ambas opciones dan como resultado que estos dos tipos se cambien por usted (ya sea por el compilador o en tiempo de ejecución) a sus equivalentes de NX. Consulte los vínculos del tema para obtener más información.

Nota Es posible que vea una advertencia de falso positivo si se cumple una de las condiciones siguientes:

  • La función de inicialización del controlador llama a otra función que llama a ExInitializeDriverRuntime(DrvRtPoolNxOptIn)
  • Está creando un DRIVER_LIBRARY y ha especificado POOL_NX_OPTIN pero no tiene ninguna función de inicialización.
  • Cambie el tipo de asignación a un tipo no ejecutable.

Ejemplo (POOL_NX_OPTIN_AUTO):

La siguiente configuración en el archivo de orígenes permitiría que se proporcione un parámetro ejecutable en una llamada API:

C_DEFINES=$(C_DEFINES)

La siguiente configuración en el archivo de orígenes evita la advertencia:

C_DEFINES=$(C_DEFINES) -DPOOL_NX_OPTIN_AUTO=1

Ejemplo (POOL_NX_OPTIN):

El código siguiente en el archivo de orígenes genera una advertencia:

C_DEFINES=$(C_DEFINES)

El código siguiente en el archivo de orígenes evita la advertencia:

C_DEFINES=$(C_DEFINES) -DPOOL_NX_OPTIN=1

En DriverEntry(), antes de que tenga lugar cualquier asignación de memoria:

NTSTATUS
DriverEntry (
    _In_ PDRIVER_OBJECT DriverObject,
    _In_ PUNICODE_STRING RegistryPath
    )
{
    NTSTATUS status;

    ExInitializeDriverRuntime( DrvRtPoolNxOptIn );
…

Ejemplo (cambiar el tipo de asignación):

Para el tipo de MM_PAGE_PRIORITY , puede corregirlo agregando la marca MdlMappingNoExecute al tipo de prioridad. Esto solo se admite en Windows 8 y versiones posteriores.

El código siguiente genera una advertencia:

pPtr = MmGetSystemAddressForMdlSafe( pMdl, NormalPagePriority);

El código siguiente evita la advertencia:

pPtr = MmGetSystemAddressForMdlSafe( pMdl, NormalPagePriority | MdlMappingNoExecute);

Ejemplo (POOL_TYPE)

Para el tipo de POOL_TYPE , puede corregirlo cambiando el tipo de solicitud a la versión no ejecutable del tipo. Esto solo se admite en Windows 8 y versiones posteriores.

El código siguiente genera una advertencia:

ExAllocatePoolWithTag(NonPagedPool, numberOfBytes, 'xppn');

El código siguiente evita la advertencia:

ExAllocatePoolWithTag(NonPagedPoolNx, numberOfBytes, 'xppn');

Otros casos especiales:

Ha habido un cambio en la rutina ExInitializeNPagedLookasideList que ahora le permite especificar memoria del grupo no paginado no ejecutable. Por ejemplo, el código siguiente genera esta advertencia:

ExInitializeNPagedLookasideList(pLookaside,
                NULL,
                NULL,
                0,
                size,
                tag,
                depth);

El código siguiente evita esta advertencia:

ExInitializeNPagedLookasideList(pLookaside,
                NULL,
                NULL,
                POOL_NX_ALLOCATION,
                size,
                tag,
                depth);

Para defectos relacionados con protecciones de página:

Algunas API permiten especificar protecciones de página, ZwMapViewOfSection es una de estas. En estos casos, use la versión no ejecutable del tipo de protección.

Cambie:

  • PAGE_EXECUTE a cualquiera de las siguientes alternativas o PAGE_NOACCESS
  • PAGE_EXECUTE_READ a PAGE_READONLY
  • PAGE_EXECUTE_READWRITE a PAGE_READWRITE
  • PAGE_EXECUTE_WRITECOPY a PAGE_WRITECOPY

El código siguiente genera una advertencia:

Status = ZwMapViewOfSection(   handle,
                NtCurrentProcess(),
                Address,
                0,
                0,
                &SectionOffset,
                Size,
                ViewUnmap,
                MEM_LARGE_PAGES,
                PAGE_EXECUTE_READWRITE
                ); 

El código siguiente evita esta advertencia:

Status = ZwMapViewOfSection(   handle,
                NtCurrentProcess(),
                Address,
                0,
                0,
                &SectionOffset,
                Size,
                ViewUnmap,
                MEM_LARGE_PAGES,
                PAGE_READWRITE
                ); 

Para defectos relacionados con tipos de caché:

Algunas API asignan memoria con permisos ejecutables que dependen de un tipo de caché. Dos de estas API son MmAllocateContiguousMemorySpecifyCache y MmAllocateContiguousMemorySpecifyCacheNode. Si se usa un tipo de caché de MmCached (consulte MEMORY_CACHING_TYPE), se asignará memoria ejecutable. Para corregirlo, seleccione otro tipo de almacenamiento en caché o, si se requiere memoria almacenada en caché, use la API MmAllocateContiguousNodeMemory.

Cambie:

  • MmCached a MmNonCached o MmWriteCombined si no se requiere memoria almacenada en caché
  • La API a MmAllocateContiguousNodeMemory si se requiere memoria almacenada en caché

El código siguiente genera una advertencia:

MmAllocateContiguousMemorySpecifyCache(       numberOfBytes,
                                              lowestAddress,
                                              highestAddress,
                                              NULL,
                                              MmCached,
                                              ); 

El código siguiente evita esta advertencia si no se requiere memoria almacenada en caché:

MmAllocateContiguousMemorySpecifyCache(       numberOfBytes,
                                              lowestAddress,
                                              highestAddress,
                                              NULL,
                                              MmNonCached,
                                              ); 

El código siguiente genera una advertencia:

MmAllocateContiguousMemorySpecifyCacheNode(   numberOfBytes,
                                              lowestAddress,
                                              highestAddress,
                                              NULL,
                                              MmCached,
                                              MM_ANY_NODE_OK
                                              ); 

El código siguiente evita esta advertencia si se requiere memoria almacenada en caché:

MmAllocateContiguousNodeMemory(       numberOfBytes,
                                      lowestAddress,
                                      highestAddress,
                                      NULL,
                                      PAGE_READWRITE,
                                      MM_ANY_NODE_OK
                                      ); 

El código siguiente usa la API alternativa cuando no se requiere memoria almacenada en caché:

MmAllocateContiguousNodeMemory(       numberOfBytes,
                                      lowestAddress,
                                      highestAddress,
                                      NULL,
                                      PAGE_READWRITE | PAGE_NOCACHE,
                                      MM_ANY_NODE_OK
                                      ); 

Funciones prohibidas

API prohibida Reemplazos Racionalización/Notas
ExInitializeNPagedLookasideList()
  • Establezca el parámetro flag con o en . POOL_NX_ALLOCATION
  • O mediante los POOL_NX_OPTIN_AUTO / POOL_NX_OPTIN métodos anteriores
MmAllocateContiguousMemorySpecifyCache() MmAllocateContiguousNodeMemory() Consulte anteriormente para obtener más información.

Marcas prohibidas

Marca prohibida Reemplazos Racionalización y notas
MM_PAGE_PRIORITY

Consulte anteriormente para obtener más información.
POOL_NX_OPTIN_AUTO Esto permite crear varios archivos binarios para diferentes versiones de Windows.
POOL_NX_OPTIN(+ ExInitializeDriverRuntime(DrvRtPoolNxOptIn)) Esto admite una única ejecución binaria en diferentes versiones de Windows.
PagePriority / MdlMappingNoExecute Esto funcionará en Windows 8 y versiones posteriores.
PAGE_EXECUTE PAGE_NOACCESS Consulte anteriormente para obtener más información.
PAGE_EXECUTE_READ PAGE_READONLY
PAGE_EXECUTE_READWRITE PAGE_READWRITE
PAGE_EXECUTE_WRITECOPY PAGE_WRITECOPY

POOL_TYPE