Avviso C30030

Chiamata di una funzione di allocazione della memoria e passaggio di un parametro che indica la memoria eseguibile

Alcune API hanno parametri che consentono di configurare se la memoria è eseguibile o meno. Questo errore indica che vengono usati parametri che comportano l'allocazione di NonPagedPool eseguibile.

Commenti

È consigliabile usare una delle opzioni disponibili per richiedere memoria non eseguibile. Un elenco di tutte le funzioni escluse e i flag coperti da questo errore e le sostituzioni consigliate sono disponibili nella parte inferiore di questa pagina.

Nome analisi cose: BANNED_MEM_ALLOCATION_UNSAFE

Per i difetti che coinvolgono i tipi di parametro MM_PAGE_PRIORITY e POOL_TYPE

Usare una delle seguenti opzioni:

  • Specificare la definizione del preprocessore POOL_NX_OPTIN_AUTO nelle impostazioni di origini/progetto.
  • Specificare la definizione del preprocessore POOL_NX_OPTIN nelle impostazioni di origine/progetto e chiamare ExInitializeDriverRuntime(DrvRtPoolNxOptIn) dalla funzione di inizializzazione del driver (DriverEntry o DllInitialize).

Nota La scelta di usare POOL_NX_OPTIN_AUTO o POOL_NX_OPTIN dipende in gran parte dalla piattaforma di destinazione e dal numero di file binari di destinazione. Entrambe queste opzioni comportano la modifica di questi due tipi (dal compilatore o in fase di esecuzione) ai rispettivi equivalenti NX. Per altre informazioni, vedere i collegamenti all'argomento.

Nota È possibile che venga visualizzato un avviso falso positivo se una delle condizioni seguenti è vera:

  • La funzione di inizializzazione del driver chiama un'altra funzione che chiama ExInitializeDriverRuntime(DrvRtPoolNxOptIn)
  • Si sta creando un DRIVER_LIBRARY e si è specificato POOL_NX_OPTIN ma non si dispone di alcuna funzione di inizializzazione.
  • Modificare il tipo di allocazione in un tipo non eseguibile.

Esempio (POOL_NX_OPTIN_AUTO):

L'impostazione seguente nel file di origini consentirà di specificare un parametro eseguibile in una chiamata API:

C_DEFINES=$(C_DEFINES)

L'impostazione seguente nel file di origini evita l'avviso:

C_DEFINES=$(C_DEFINES) -DPOOL_NX_OPTIN_AUTO=1

Esempio (POOL_NX_OPTIN):

Il codice seguente nel file di origini genera un avviso:

C_DEFINES=$(C_DEFINES)

Il codice seguente nel file di origini evita l'avviso:

C_DEFINES=$(C_DEFINES) -DPOOL_NX_OPTIN=1

In DriverEntry(), prima che venga eseguita un'allocazione di memoria:

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

    ExInitializeDriverRuntime( DrvRtPoolNxOptIn );
…

Esempio (Modificare il tipo di allocazione):

Per il tipo di MM_PAGE_PRIORITY è possibile risolvere questo problema aggiungendo il flag MdlMappingNoExecute al tipo di priorità. Questa funzionalità è supportata solo in Windows 8 e versioni successive.

Il codice seguente genera un avviso:

pPtr = MmGetSystemAddressForMdlSafe( pMdl, NormalPagePriority);

Il codice seguente evita l'avviso:

pPtr = MmGetSystemAddressForMdlSafe( pMdl, NormalPagePriority | MdlMappingNoExecute);

Esempio (POOL_TYPE)

Per il tipo di POOL_TYPE è possibile risolvere questo problema modificando il tipo di richiesta alla versione non eseguibile del tipo. Questa funzionalità è supportata solo in Windows 8 e versioni successive.

Il codice seguente genera un avviso:

ExAllocatePoolWithTag(NonPagedPool, numberOfBytes, 'xppn');

Il codice seguente evita l'avviso:

ExAllocatePoolWithTag(NonPagedPoolNx, numberOfBytes, 'xppn');

Altri casi speciali:

È stata apportata una modifica alla routine ExInitializeNPagedLookasideList che ora consente di specificare la memoria del pool non eseguibile non di paging. Ad esempio, il codice seguente genera questo avviso:

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

Il codice seguente evita questo avviso:

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

Per i difetti che comportano la protezione delle pagine:

Alcune API consentono di specificare le protezioni delle pagine, ZwMapViewOfSection è una di queste. In questi casi, usare la versione non eseguibile del tipo di protezione.

Cambiare:

  • PAGE_EXECUTE a una delle seguenti alternative o PAGE_NOACCESS
  • PAGE_EXECUTE_READ a PAGE_READONLY
  • PAGE_EXECUTE_READWRITE a PAGE_READWRITE
  • PAGE_EXECUTE_WRITECOPY a PAGE_WRITECOPY

Il codice seguente genera un avviso:

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

Il codice seguente evita questo avviso:

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

Per i difetti relativi ai tipi di cache:

Alcune API allocano memoria con autorizzazioni eseguibili dipendenti da un tipo di cache. Due api di questo tipo sono MmAllocateContiguousMemorySpecifyCache e MmAllocateContiguousMemorySpecifyCacheNode. Se si usa un tipo di cache MmCached (vedere MEMORY_CACHING_TYPE), verrà allocata la memoria eseguibile. Per risolvere questo problema, selezionare un altro tipo di memorizzazione nella cache oppure se è necessaria la memoria memorizzata nella cache, usare l'API MmAllocateContiguousNodeMemory.

Cambiare:

  • MmCached in MmNonCached o MmWriteCombined se la memoria memorizzata nella cache non è necessaria
  • API a MmAllocateContiguousNodeMemory se è necessaria la memoria memorizzata nella cache

Il codice seguente genera un avviso:

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

Il codice seguente evita questo avviso se la memoria memorizzata nella cache non è necessaria:

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

Il codice seguente genera un avviso:

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

Il codice seguente evita questo avviso se è necessaria la memoria memorizzata nella cache:

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

Il codice seguente usa l'API alternativa quando la memoria memorizzata nella cache non è necessaria:

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

Funzioni escluse

API vietata Sostituzioni Razionale/Note
ExInitializeNPagedLookasideList()
  • OR/impostare il parametro del flag con/su POOL_NX_ALLOCATION
  • Oppure usando i POOL_NX_OPTIN_AUTO / POOL_NX_OPTIN metodi precedenti
MmAllocateContiguousMemorySpecifyCache() MmAllocateContiguousNodeMemory() Per altre informazioni, vedere sopra

Contrassegni vietati

Contrassegno vietato Sostituzioni Razionale/Note
MM_PAGE_PRIORITY

Per altre informazioni, vedere sopra
POOL_NX_OPTIN_AUTO Ciò supporta la creazione di più file binari per versioni diverse di Windows
POOL_NX_OPTIN(+ ExInitializeDriverRuntime(DrvRtPoolNxOptIn)) Questo supporta un singolo file binario in esecuzione in versioni diverse di Windows
PagePriority / MdlMappingNoExecute Questo funzionerà su Windows 8 e versioni successive
PAGE_EXECUTE PAGE_NOACCESS Per altre informazioni, vedere sopra
PAGE_EXECUTE_READ PAGE_READONLY
PAGE_EXECUTE_READWRITE PAGE_READWRITE
PAGE_EXECUTE_WRITECOPY PAGE_WRITECOPY

POOL_TYPE