共用方式為


警告 C30030

呼叫記憶體配置函式,並傳遞指出可執行記憶體的參數

某些 API 具有參數,可設定記憶體是否可執行。 此錯誤表示使用參數會導致配置可執行檔 NonPagedPool。

備註

您應該使用其中一個可用的選項來要求非可執行記憶體。 此錯誤涵蓋的所有禁用函式和旗標清單,以及此頁面底部的建議取代專案。

Cose 分析名稱:BANNED_MEM_ALLOCATION_UNSAFE

對於涉及參數類型MM_PAGE_PRIORITYPOOL_TYPE的瑕疵

使用下列其中一個選項:

  • 在來源/項目設定中 指定 預處理器定義POOL_NX_OPTIN_AUTO。
  • 在 sources/project 設定中指定前置處理器定義POOL_NX_OPTIN,並從驅動程式初始化函式 (DriverEntry 或 DllInitialize) 呼叫 ExInitializeDriverRuntime (DrvRtPoolNxOptIn) 。

注意 選擇要使用 POOL_NX_OPTIN_AUTOPOOL_NX_OPTIN ,主要取決於您的目標平臺,以及您要製作多少二進位檔。 這兩個選項都會為您變更這兩種類型, (編譯程式或運行時間) NX 對等專案。 如需詳細資訊,請參閱主題連結。

注意 如果下列其中一個條件成立,您可能會看到誤判警告:

  • 驅動程式初始化函式會呼叫另一個呼叫 ExInitializeDriverRuntime 的函式, (DrvRtPoolNxOptIn)
  • 您正在建立 DRIVER_LIBRARY ,並已指定 POOL_NX_OPTIN ,但沒有初始化函式。
  • 將配置類型變更為非可執行檔類型。

範例 (POOL_NX_OPTIN_AUTO) :

來源檔案中的下列設定允許在 API 呼叫中提供可執行參數時發出警告:

C_DEFINES=$(C_DEFINES)

來源檔案中的下列設定可避免警告:

C_DEFINES=$(C_DEFINES) -DPOOL_NX_OPTIN_AUTO=1

範例 (POOL_NX_OPTIN) :

來源檔案中的下列程式代碼會產生警告:

C_DEFINES=$(C_DEFINES)

來源檔案中的下列程式代碼可避免警告:

C_DEFINES=$(C_DEFINES) -DPOOL_NX_OPTIN=1

DriverEntry () 中,發生任何記憶體配置之前:

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

    ExInitializeDriverRuntime( DrvRtPoolNxOptIn );
…

範例 (變更配置類型) :

針對 MM_PAGE_PRIORITY 類型,您可以將 MdlMappingNoExecute 旗標新增至優先順序類型來修正此問題。 這僅支援 Windows 8和更新版本。

下列程式代碼會產生警告:

pPtr = MmGetSystemAddressForMdlSafe( pMdl, NormalPagePriority);

下列程式代碼可避免警告:

pPtr = MmGetSystemAddressForMdlSafe( pMdl, NormalPagePriority | MdlMappingNoExecute);

範例 (POOL_TYPE)

針對 POOL_TYPE 類型,您可以將要求類型變更為類型的非可執行版本,以修正此問題。 這僅支援 Windows 8和更新版本。

下列程式代碼會產生警告:

ExAllocatePoolWithTag(NonPagedPool, numberOfBytes, 'xppn');

下列程式代碼可避免警告:

ExAllocatePoolWithTag(NonPagedPoolNx, numberOfBytes, 'xppn');

其他特殊案例:

ExInitializeNPagedLo可sideList 例程中已有變更,現在可讓您指定非可執行的非分頁集區內存。 例如,下列程式代碼會產生此警告:

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

下列程式代碼可避免此警告:

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

對於涉及頁面保護的瑕疵:

某些 API 可讓您指定頁面保護, ZwMapViewOfSection 是其中一項。 在這些情況下,請使用保護類型的非可執行版本。

[變更]:

  • PAGE_EXECUTE下列任何替代方案或PAGE_NOACCESS
  • PAGE_EXECUTE_READ至 PAGE_READONLY
  • PAGE_EXECUTE_READWRITE至 PAGE_READWRITE
  • PAGE_EXECUTE_WRITECOPY至 PAGE_WRITECOPY

下列程式代碼會產生警告:

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

下列程式代碼可避免此警告:

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

對於涉及快取類型的瑕疵:

某些 API 會使用相依於快取類型的可執行許可權來配置記憶體。 兩個這類 API 是 MmAllocateContiguousMemorySpecifyCacheMmAllocateContiguousMemorySpecifyCacheNode。 如果 (查看MEMORY_CACHING_TYPE) 使用 MmCached 的快取類型,則會配置可執行記憶體。 若要修正此問題,請選取另一個快取類型,或如果需要快取記憶體,請使用 API MmAllocateContiguousNodeMemory

[變更]:

  • 如果不需要快取的記憶體,則 MmCachedmmNonCachedmmWriteCombined
  • 如果需要快取記憶體,則為 MmAllocateContiguousNodeMemory 的 API

下列程式代碼會產生警告:

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

如果不需要快取的記憶體,下列程式代碼可避免此警告:

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

下列程式代碼會產生警告:

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

如果需要快取記憶體,下列程式代碼可避免此警告:

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

當不需要快取記憶體時,下列程式代碼會使用替代 API:

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

禁用函式

禁用 API 取代 () 原理/ 附註
ExInitializeNPagedLookasideList()
  • 請 OR/設定具有/to 的旗標參數 POOL_NX_ALLOCATION
  • POOL_NX_OPTIN_AUTO / POOL_NX_OPTIN或使用上述方法
MmAllocateContiguousMemorySpecifyCache() MmAllocateContiguousNodeMemory() 如需詳細資訊,請參閱上方

禁用旗標

禁用旗標 取代 () 原理/附注
MM_PAGE_PRIORITY

如需詳細資訊,請參閱上方
POOL_NX_OPTIN_AUTO 這支援為不同版本的 Windows 建立多個二進位檔
POOL_NX_OPTIN (+ ExInitializeDriverRuntime(DrvRtPoolNxOptIn)) 這支援在不同版本的 Windows 上執行的單一二進位檔
PagePriority / MdlMappingNoExecute 這適用於 Windows 8和更新版本
PAGE_EXECUTE PAGE_NOACCESS 如需詳細資訊,請參閱上方
PAGE_EXECUTE_READ PAGE_READONLY
PAGE_EXECUTE_READWRITE PAGE_READWRITE
PAGE_EXECUTE_WRITECOPY PAGE_WRITECOPY

POOL_TYPE