Compartilhar via


Aviso C30030

Chamar uma função de alocação de memória e passar um parâmetro que indica memória executável

Algumas APIs têm parâmetros que configuram se a memória é executável ou não. Esse erro indica que são usados parâmetros que resultam na alocação de NonPagedPool executável.

Comentários

Você deve usar uma das opções disponíveis para solicitar memória não executável. Uma lista de todas as funções e sinalizadores proibidos cobertos por esse erro e as substituições recomendadas podem ser encontradas na parte inferior desta página.

Cose analysis name: BANNED_MEM_ALLOCATION_UNSAFE

Para defeitos que envolvem os tipos de parâmetro MM_PAGE_PRIORITY e POOL_TYPE

Use uma das seguintes opções:

  • Especifique a definição do pré-processador POOL_NX_OPTIN_AUTO nas configurações de fontes/projeto.
  • Especifique a definição de pré-processador POOL_NX_OPTIN nas configurações de origem/projeto e chame ExInitializeDriverRuntime(DrvRtPoolNxOptIn) da função de inicialização do driver (DriverEntry ou DllInitialize).

Nota A escolha de usar POOL_NX_OPTIN_AUTO ou POOL_NX_OPTIN depende em grande parte de qual plataforma você está direcionando e quantos binários você está fazendo. Essas duas opções resultam na alteração desses dois tipos para você (pelo compilador ou em tempo de execução) para seus equivalentes de NX. Confira os links do tópico para obter mais informações.

Nota Você poderá ver um aviso falso positivo se uma das seguintes condições for verdadeira:

  • A função de inicialização do driver chama outra função que chama ExInitializeDriverRuntime(DrvRtPoolNxOptIn)
  • Você está criando um DRIVER_LIBRARY e especificou POOL_NX_OPTIN , mas não tem nenhuma função de inicialização.
  • Altere o tipo de alocação para um tipo não executável.

Exemplo (POOL_NX_OPTIN_AUTO):

A seguinte configuração no arquivo de fontes permitiria o aviso caso um parâmetro executável fosse fornecido em uma chamada à API:

C_DEFINES=$(C_DEFINES)

A seguinte configuração no arquivo de fontes evita o aviso:

C_DEFINES=$(C_DEFINES) -DPOOL_NX_OPTIN_AUTO=1

Exemplo (POOL_NX_OPTIN):

O seguinte código no arquivo de fontes gera um aviso:

C_DEFINES=$(C_DEFINES)

O código a seguir no arquivo de fontes evita o aviso:

C_DEFINES=$(C_DEFINES) -DPOOL_NX_OPTIN=1

Em DriverEntry(), antes de qualquer alocação de memória ocorrer:

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

    ExInitializeDriverRuntime( DrvRtPoolNxOptIn );
…

Exemplo (alterar o tipo de alocação):

Para o tipo MM_PAGE_PRIORITY , você pode corrigir isso adicionando o sinalizador MdlMappingNoExecute ao tipo de prioridade. Isso só tem suporte em Windows 8 e posteriores.

O código a seguir gera um aviso:

pPtr = MmGetSystemAddressForMdlSafe( pMdl, NormalPagePriority);

O código a seguir evita o aviso:

pPtr = MmGetSystemAddressForMdlSafe( pMdl, NormalPagePriority | MdlMappingNoExecute);

Exemplo (POOL_TYPE)

Para o tipo de POOL_TYPE , você pode corrigir isso alterando o tipo de solicitação para a versão não executável do tipo. Isso só tem suporte em Windows 8 e posteriores.

O código a seguir gera um aviso:

ExAllocatePoolWithTag(NonPagedPool, numberOfBytes, 'xppn');

O código a seguir evita o aviso:

ExAllocatePoolWithTag(NonPagedPoolNx, numberOfBytes, 'xppn');

Outros casos especiais:

Houve uma alteração na rotina ExInitializeNPagedLookasideList que agora permite especificar a memória do pool não executável não executável. Por exemplo, o código a seguir gera este aviso:

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

O código a seguir evita este aviso:

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

Para defeitos que envolvem proteções de página:

Algumas APIs permitem especificar proteções de página, ZwMapViewOfSection é uma delas. Nesses casos, use a versão não executável do tipo de proteção.

Mudar:

  • PAGE_EXECUTE a qualquer uma das alternativas ou PAGE_NOACCESS abaixo
  • PAGE_EXECUTE_READ to PAGE_READONLY
  • PAGE_EXECUTE_READWRITE to PAGE_READWRITE
  • PAGE_EXECUTE_WRITECOPY to PAGE_WRITECOPY

O código a seguir gera um aviso:

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

O código a seguir evita este aviso:

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

Para defeitos que envolvem tipos de cache:

Algumas APIs alocam memória com permissões executáveis dependentes de um tipo de cache. Duas dessas APIs são MmAllocateContiguousMemorySpecifyCache e MmAllocateContiguousMemorySpecifyCacheNode. Se um tipo de cache de MmCached for usado (consulte MEMORY_CACHING_TYPE), a memória executável será alocada. Para corrigir isso, selecione outro tipo de cache ou, se a memória armazenada em cache for necessária, use a API MmAllocateContiguousNodeMemory.

Mudar:

  • MmCached para MmNonCached ou MmWriteCombined se a memória armazenada em cache não for necessária
  • A API para MmAllocateContiguousNodeMemory se a memória armazenada em cache for necessária

O código a seguir gera um aviso:

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

O código a seguir evita esse aviso se a memória armazenada em cache não for necessária:

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

O código a seguir gera um aviso:

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

O código a seguir evita esse aviso se a memória armazenada em cache for necessária:

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

O código a seguir usa a API alternativa quando a memória armazenada em cache não é necessária:

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

Funções proibidas

API proibida Substituição(s) Racionalidade/Anotações
ExInitializeNPagedLookasideList()
  • Or/set the flag parameter with/to POOL_NX_ALLOCATION
  • Ou usando os POOL_NX_OPTIN_AUTO / POOL_NX_OPTIN métodos acima
MmAllocateContiguousMemorySpecifyCache() MmAllocateContiguousNodeMemory() Confira acima para obter mais informações

Sinalizadores banidos

Sinalizador proibido Substituição(s) Racionalidade/Anotações
MM_PAGE_PRIORITY

Confira acima para obter mais informações
POOL_NX_OPTIN_AUTO Isso dá suporte à criação de vários binários para versões diferentes do Windows
POOL_NX_OPTIN(+ ExInitializeDriverRuntime(DrvRtPoolNxOptIn)) Isso dá suporte a um único binário em execução em diferentes versões do Windows
PagePriority / MdlMappingNoExecute Isso funcionará em Windows 8 e posteriores
PAGE_EXECUTE PAGE_NOACCESS Confira acima para obter mais informações
PAGE_EXECUTE_READ PAGE_READONLY
PAGE_EXECUTE_READWRITE PAGE_READWRITE
PAGE_EXECUTE_WRITECOPY PAGE_WRITECOPY

POOL_TYPE