共用方式為


UnSafeAllocatePool 規則 (wdm)

UnSafeAllocatePool 規則是重要的安全性規則,會檢查驅動程式是否未使用已被取代的 DIS 來配置記憶體。

UnsafeAllocatePool 規則指定驅動程式不應該呼叫:

ExAllocatePool

ExAllocatePoolWithTag

ExAllocatePoolWithQuota

ExAllocatePoolWithQuotaTag

ExAllocatePoolWithTagPriority

此規則適用於預覽 WDK 組建 20236 和更新版本。

Windows 10 版本、版本 2004 和更新版本的驅動程式更新

如果您要建置以 2004 版和更新版本 Windows 10 為目標的驅動程式,請改用取代 API ExAllocatePool2ExAllocatePool3

舊 API 新增 API
ExAllocatePool ExAllocatePool2
ExAllocatePoolWithTag ExAllocatePool2
ExAllocatePoolWithQuota ExAllocatePool2
ExAllocatePoolWithQuotaTag ExAllocatePool2
ExAllocatePoolWithTagPriority ExAllocatePool3

新的 API 預設會零集區配置,以協助避免可能的記憶體洩漏錯誤。

ExAllocatePool/ExAllocatePoolWithTag

// Old code
PVOID Allocation = ExAllocatePoolWithTag(PagedPool, 100, 'abcd');
RtlZeroMemory(Allocation, 100);

// New code
PVOID Allocation = ExAllocatePool2(POOL_FLAG_PAGED, 100, 'abcd');

舊的集區配置 API 接受 POOL_TYPE 自變數,但新的配置 API 會接受 POOL_FLAGS 自變數。 更新任何相關聯的程序代碼,以使用新的 POOL_FLAGS 自變數。

ExAllocatePoolWithQuota/ExAllocatePoolWithQuotaTag

新的函式現在預設會在配置失敗時傳回NULL。 若要讓配置器改為在失敗時引發例外狀況,必須將POOL_FLAG_RAISE_ON_FAILURE旗標傳遞,如 ExAllocatePool2 中所述。

// Old code
PVOID Allocation = ExAllocatePoolWithQuotaTag(PagedPool | POOL_QUOTA_FAIL_INSTEAD_OF_RAISE, 100, 'abcd');
RtlZeroMemory(Allocation, 100);

// New code
PVOID Allocation = ExAllocatePool2(POOL_FLAG_PAGED | POOL_FLAG_USE_QUOTA, 100, 'abcd');

ExAllocatePoolWithTagPriority

// Old code
PVOID Allocation = ExAllocatePoolWithTagPriority(PagedPool, 100, 'abcd', HighPoolPriority);
RtlZeroMemory(Allocation, 100);

// New code
POOL_EXTENDED_PARAMETER params = {0};
params.Type = PoolExtendedParameterPriority;
params.Priority = HighPoolPriority;
PVOID Allocation = ExAllocatePool3(POOL_FLAG_PAGED, 100, 'abcd', &params, 1);

Windows 10 2004 版舊版 Windows 的驅動程式更新

如果您要建置以 Windows 10 版本 2004 之前的 Windows 版本為目標的驅動程式,您必須使用下列強制內嵌包裝函式。

您也必須在驅動程式初始化期間 #define POOL_ZERO_DOWN_LEVEL_SUPPORT 並呼叫 ExInitializeDriverRuntime ,才能呼叫集區配置函式。

本機定義的內嵌函式

PVOID
NTAPI
ExAllocatePoolZero (
    _In_ __drv_strictTypeMatch(__drv_typeExpr) POOL_TYPE PoolType,
    _In_ SIZE_T NumberOfBytes,
    _In_ ULONG Tag
    )

PVOID
NTAPI
ExAllocatePoolQuotaZero (
    _In_ __drv_strictTypeMatch(__drv_typeExpr) POOL_TYPE PoolType,
    _In_ SIZE_T NumberOfBytes,
    _In_ ULONG Tag
    )

PVOID
NTAPI
ExAllocatePoolPriorityZero (
    _In_ __drv_strictTypeMatch(__drv_typeExpr) POOL_TYPE PoolType,
    _In_ SIZE_T NumberOfBytes,
    _In_ ULONG Tag,
    _In_ EX_POOL_PRIORITY Priority
    )

如需這些程式代碼包裝函式的實作程序代碼,請參閱最新的 wdm.h 標頭。 例如,這是 ExAllocatePoolPriorityZero 的實作,其中顯示 RtlZeroMemory 的使用方式。

{
    PVOID Allocation;

    Allocation = ExAllocatePoolWithTagPriority((POOL_TYPE) (PoolType | POOL_ZERO_ALLOCATION),
                                               NumberOfBytes,
                                               Tag,
                                               Priority);

#if defined(POOL_ZERO_DOWN_LEVEL_SUPPORT)

    if ((!ExPoolZeroingNativelySupported) && (Allocation != NULL)) {
        RtlZeroMemory(Allocation, NumberOfBytes);
    }

#endif

    return Allocation;
}

將舊 API 對應至新的 API

舊 API 新增 API
ExAllocatePool ExAllocatePoolZero
ExAllocatePoolWithTag ExAllocatePoolZero
ExAllocatePoolWithQuota ExAllocatePoolQuotaZero
ExAllocatePoolWithQuotaTag ExAllocatePoolQuotaZero
ExAllocatePoolWithTagPriority ExAllocatePoolPriorityZero

範例

// Old code
PVOID Allocation = ExAllocatePoolWithTag(PagedPool, 100, 'abcd');
RtlZeroMemory(Allocation, 100);

// New code

// Before headers are pulled in (or compiler defined)
#define POOL_ZERO_DOWN_LEVEL_SUPPORT

// Once during driver initialization
// Argument can be any value
ExInitializeDriverRuntime(0);

// Replacement for each pool allocation
PVOID Allocation = ExAllocatePoolZero(PagedPool, 100, 'abcd');

驅動程式模型:WDM、泛型

測試方法

在編譯時期:

  1. 執行 靜態驅動程式驗證程式 ,並指定 UnSafeAllocatePool 規則。

  2. 使用下列步驟 (在 Windows 驅動程式中使用靜態驅動程式驗證程式尋找 瑕疵) ,以執行程式碼的分析:

如需詳細資訊,請參閱 使用靜態驅動程式驗證器尋找驅動程式中的瑕疵