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() |
|
|
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 |