다음을 통해 공유


경고 C30030

메모리 할당 함수 호출 및 실행 가능한 메모리를 나타내는 매개 변수 전달

일부 API에는 메모리가 실행 가능한지 여부를 구성하는 매개 변수가 있습니다. 이 오류는 실행 파일 NonPagedPool이 할당되는 매개 변수가 사용되었음을 나타냅니다.

설명

실행 불가능한 메모리를 요청하려면 사용 가능한 옵션 중 하나를 사용해야 합니다. 이 오류와 권장되는 대체 항목이 포함된 모든 금지된 함수 및 플래그 목록은 이 페이지의 맨 아래에서 찾을 수 있습니다.

Cose 분석 이름: BANNED_MEM_ALLOCATION_UNSAFE

매개 변수 형식과 관련된 결함의 경우 MM_PAGE_PRIORITYPOOL_TYPE

다음 옵션 중 하나를 사용합니다.

  • 원본/프로젝트 설정에서 전처리기 정의 POOL_NX_OPTIN_AUTO 지정합니다.
  • 소스/프로젝트 설정에서 POOL_NX_OPTIN 사전 프로세서 정의를 지정하고 드라이버 초기화 함수(DriverEntry 또는 DllInitialize)에서 ExInitializeDriverRuntime(DrvRtPoolNxOptIn)을 호출합니다.

참고POOL_NX_OPTIN_AUTO 또는 POOL_NX_OPTIN 사용할지 여부는 주로 대상으로 지정하는 플랫폼과 만드는 이진 파일 수에 따라 달라집니다. 이러한 두 옵션 모두 컴파일러 또는 런타임에 이러한 두 형식이 NX 등가물로 변경됩니다. 자세한 내용은 항목 링크를 참조하세요.

참고 다음 조건 중 하나가 true이면 가양성 경고가 표시될 수 있습니다.

  • 드라이버 초기화 함수는 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');

기타 특수 사례:

ExInitializeNPagedLookasideList 루틴이 변경되어 이제 실행 불가능한 비페이지 풀 메모리를 지정할 수 있습니다. 예를 들어 다음 코드는 이 경고를 생성합니다.

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

다음 코드는 이 경고를 방지합니다.

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

페이지 보호와 관련된 결함의 경우:

일부 API를 사용하면 페이지 보호를 지정할 수 있습니다. ZwMapViewOfSection 은 다음 중 하나입니다. 이러한 경우 보호 유형의 실행 불가능한 버전을 사용합니다.

변경:

  • 아래 대안 또는 PAGE_NOACCESS PAGE_EXECUTE
  • PAGE_EXECUTE_READ to PAGE_READONLY
  • PAGE_EXECUTE_READWRITE to PAGE_READWRITE
  • PAGE_EXECUTE_WRITECOPY to 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입니다. MmCached의 캐시 형식을 사용하는 경우(MEMORY_CACHING_TYPE 참조) 실행 가능한 메모리가 할당됩니다. 이 문제를 해결하려면 다른 캐싱 유형을 선택하거나 캐시된 메모리가 필요한 경우 API MmAllocateContiguousNodeMemory를 사용합니다.

변경:

  • 캐시된 메모리가 필요하지 않은 경우 MmNonCached 또는 MmWriteCombined로MmCached
  • 캐시된 메모리가 필요한 경우 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()
  • 플래그 매개 변수를 /to로 OR/설정하세요. 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