Warnung C30030

Aufrufen einer Speicherzuweisungsfunktion und Übergeben eines Parameters, der ausführbaren Arbeitsspeicher angibt

Einige APIs verfügen über Parameter, mit denen konfiguriert wird, ob der Arbeitsspeicher ausführbar ist oder nicht. Dieser Fehler gibt an, dass Parameter verwendet werden, die dazu führen, dass ausführbare NonPagedPool zugeordnet wird.

Hinweise

Sie sollten eine der verfügbaren Optionen verwenden, um nicht ausführbaren Arbeitsspeicher anzufordern. Eine Liste aller gesperrten Funktionen und Flags, die von diesem Fehler betroffen sind, sowie die empfohlenen Ersetzungen finden Sie unten auf dieser Seite.

Name der Cose-Analyse: BANNED_MEM_ALLOCATION_UNSAFE

Bei Fehlern, die die Parametertypen MM_PAGE_PRIORITY und POOL_TYPE

Nutzen Sie eine der folgenden Optionen:

  • Geben Sie die Präprozessordefinition POOL_NX_OPTIN_AUTO in den Quellen-/Projekteinstellungen an.
  • Geben Sie die Präprozessordefinition POOL_NX_OPTIN in den Quellen-/Projekteinstellungen an, und rufen Sie ExInitializeDriverRuntime(DrvRtPoolNxOptIn) über die Treiberinitialisierungsfunktion (DriverEntry oder DllInitialize) auf.

Hinweis Die Wahl, ob POOL_NX_OPTIN_AUTO oder POOL_NX_OPTIN verwendet werden soll, hängt weitgehend davon ab, auf welche Plattform Sie abzielen und wie viele Binärdateien Sie erstellen. Beide Optionen führen dazu, dass diese beiden Typen für Sie (entweder vom Compiler oder zur Laufzeit) in ihre NX-Entsprechungen geändert werden. Weitere Informationen finden Sie unter den Themenlinks.

Hinweis Möglicherweise wird eine falsch positive Warnung angezeigt, wenn eine der folgenden Bedingungen zutrifft:

  • Die Treiberinitialisierungsfunktion ruft eine weitere Funktion auf, die ExInitializeDriverRuntime(DrvRtPoolNxOptIn) aufruft.
  • Sie erstellen eine DRIVER_LIBRARY und haben POOL_NX_OPTIN angegeben, aber keine Initialisierungsfunktion.
  • Ändern Sie den Zuordnungstyp in einen nicht ausführbaren Typ.

Beispiel (POOL_NX_OPTIN_AUTO):

Die folgende Einstellung in der Quelldatei würde die Warnung zulassen, wenn ein ausführbarer Parameter in einem API-Aufruf angegeben wird:

C_DEFINES=$(C_DEFINES)

Die folgende Einstellung in der Quelldatei vermeidet die Warnung:

C_DEFINES=$(C_DEFINES) -DPOOL_NX_OPTIN_AUTO=1

Beispiel (POOL_NX_OPTIN):

Der folgende Code in der Quelldatei generiert eine Warnung:

C_DEFINES=$(C_DEFINES)

Der folgende Code in der Quelldatei vermeidet die Warnung:

C_DEFINES=$(C_DEFINES) -DPOOL_NX_OPTIN=1

In DriverEntry(), bevor eine Speicherbelegung erfolgt:

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

    ExInitializeDriverRuntime( DrvRtPoolNxOptIn );
…

Beispiel (Ändern des Zuordnungstyps):

Für den MM_PAGE_PRIORITY Typ können Sie dies beheben, indem Sie dem Prioritätstyp das Flag MdlMappingNoExecute hinzufügen. Dies wird nur auf Windows 8 und höher unterstützt.

Der folgende Code generiert eine Warnung:

pPtr = MmGetSystemAddressForMdlSafe( pMdl, NormalPagePriority);

Der folgende Code vermeidet die Warnung:

pPtr = MmGetSystemAddressForMdlSafe( pMdl, NormalPagePriority | MdlMappingNoExecute);

Beispiel (POOL_TYPE)

Für den POOL_TYPE Typ können Sie dies beheben, indem Sie den Anforderungstyp in die nicht ausführbare Version des Typs ändern. Dies wird nur auf Windows 8 und höher unterstützt.

Der folgende Code generiert eine Warnung:

ExAllocatePoolWithTag(NonPagedPool, numberOfBytes, 'xppn');

Der folgende Code vermeidet die Warnung:

ExAllocatePoolWithTag(NonPagedPoolNx, numberOfBytes, 'xppn');

Weitere Sonderfälle:

Es wurde eine Änderung an der ExInitializeNPagedLookasideList-Routine vorgenommen, mit der Sie jetzt nicht ausführbaren Poolspeicher angeben können. Der folgende Code generiert beispielsweise diese Warnung:

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

Der folgende Code vermeidet diese Warnung:

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

Bei Mängeln mit Seitenschutz:

Einige APIs ermöglichen es Ihnen, Seitenschutz anzugeben. ZwMapViewOfSection ist eine dieser ApIs. Verwenden Sie in diesen Fällen die nicht ausführbare Version des Schutztyps.

Veränderung:

  • PAGE_EXECUTE zu einer der folgenden Alternativen oder PAGE_NOACCESS
  • PAGE_EXECUTE_READ zu PAGE_READONLY
  • PAGE_EXECUTE_READWRITE zum PAGE_READWRITE
  • PAGE_EXECUTE_WRITECOPY zu PAGE_WRITECOPY

Der folgende Code generiert eine Warnung:

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

Der folgende Code vermeidet diese Warnung:

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

Bei Fehlern, die Cachetypen betreffen:

Einige APIs weisen Arbeitsspeicher mit ausführbaren Berechtigungen zu, die von einem Cachetyp abhängig sind. Zwei solche APIs sind MmAllocateContiguousMemorySpecifyCache und MmAllocateContiguousMemorySpecifyCacheNode. Wenn der Cachetyp MmCached verwendet wird (siehe MEMORY_CACHING_TYPE), wird ausführbarer Arbeitsspeicher zugeordnet. Um dies zu beheben, wählen Sie entweder einen anderen Cachetyp aus, oder verwenden Sie die API MmAllocateContiguousNodeMemory, wenn zwischengespeicherter Arbeitsspeicher erforderlich ist.

Veränderung:

  • MmCached zu MmNonCached oder MmWriteCombined , wenn kein zwischengespeicherter Arbeitsspeicher erforderlich ist
  • Die API für MmAllocateContiguousNodeMemory , wenn zwischengespeicherter Arbeitsspeicher erforderlich ist

Der folgende Code generiert eine Warnung:

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

Der folgende Code vermeidet diese Warnung, wenn nicht zwischengespeicherter Arbeitsspeicher erforderlich ist:

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

Der folgende Code generiert eine Warnung:

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

Der folgende Code vermeidet diese Warnung, wenn zwischengespeicherter Arbeitsspeicher erforderlich ist:

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

Der folgende Code verwendet die alternative API, wenn kein zwischengespeicherter Arbeitsspeicher erforderlich ist:

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

Gesperrte Funktionen

Gesperrte API Ersetzung(en) Begründung/ Hinweise
ExInitializeNPagedLookasideList()
  • Bitte or/set the flag parameter with/to POOL_NX_ALLOCATION
  • Oder indem Sie die POOL_NX_OPTIN_AUTO / POOL_NX_OPTINoben genannten Methoden verwenden
MmAllocateContiguousMemorySpecifyCache() MmAllocateContiguousNodeMemory() Weitere Informationen finden Sie oben.

Gesperrte Flags

Gesperrtes Flag Ersetzung(en) Begründung/Hinweise
MM_PAGE_PRIORITY

Weitere Informationen finden Sie oben.
POOL_NX_OPTIN_AUTO Dies unterstützt das Erstellen mehrerer Binärdateien für verschiedene Versionen von Windows.
POOL_NX_OPTIN(+ ExInitializeDriverRuntime(DrvRtPoolNxOptIn)) Dies unterstützt eine einzelne Binärdatei, die unter verschiedenen Versionen von Windows ausgeführt wird.
PagePriority / MdlMappingNoExecute Dies funktioniert auf Windows 8 und später
PAGE_EXECUTE PAGE_NOACCESS Weitere Informationen finden Sie oben.
PAGE_EXECUTE_READ PAGE_READONLY
PAGE_EXECUTE_READWRITE PAGE_READWRITE
PAGE_EXECUTE_WRITECOPY PAGE_WRITECOPY

POOL_TYPE