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