概述
针对 Windows 10 版本 2004 发布,Microsoft 引入了新池清零 API:ExAllocatePool2 和 ExAllocatePool3,默认进行清零。
wdk-deprecated-apiCodeQL 查询查找驱动程序不应调用的所有已弃用 API 实例。 弃用的 API 包括:
Windows 10 2004 版本之后版本的驱动程序更新
如果要生成面向 Windows 10 版本 2004 及更高版本的驱动程序,请改用替换 API ExAllocatePool2 和 ExAllocatePool3 。
| 旧 API | 新建 API |
|---|---|
| ExAllocatePool | ExAllocatePool2 |
| ExAllocatePoolWithTag | ExAllocatePool2 |
| ExAllocatePoolWithQuota | ExAllocatePool2 |
| ExAllocatePoolWithQuotaTag | ExAllocatePool2 |
| ExAllocatePoolWithTagPriority | ExAllocatePool3 |
默认情况下,新 API 会将池分配设为零,以帮助避免可能的内存泄漏漏洞。
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', ¶ms, 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 | ExAllocatePool优先级零 |
示例:
// Old code
PVOID Allocation = ExAllocatePoolWithTag(PagedPool, 100, 'abcd');
// 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');
其他详细信息
可以在 Microsoft GitHub CodeQL 存储库中找到此查询。 有关 Windows 驱动程序开发人员如何下载和运行 CodeQL 的详细信息 ,请参阅 CodeQL 和静态工具徽标测试 页。