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