MmSecureVirtualMemory 函数 (ntddk.h)

MmSecureVirtualMemory 例程保护用户空间内存地址范围,以便无法释放用户空间,并且无法限制其页面保护。

语法

HANDLE MmSecureVirtualMemory(
  [in] PVOID  Address,
  [in] SIZE_T Size,
  [in] ULONG  ProbeMode
);

参数

[in] Address

要保护的用户虚拟地址范围的开头。

[in] Size

要保护的虚拟地址范围的大小(以字节为单位)。

[in] ProbeMode

指定允许的最严格的页面保护。 使用PAGE_READWRITE指定地址范围必须同时保持可读和可写,或使用PAGE_READONLY指定地址范围必须仅保持可读性。

ProbeMode 意义
PAGE_READWRITE 无法将保护更改为PAGE_NOACCESS或PAGE_READONLY。 允许进行所有其他保护更改。
PAGE_READONLY 无法将保护更改为PAGE_NOACCESS。 允许进行所有其他保护更改。

返回值

成功后,mmSecureVirtualMemory 将返回驱动程序传递给 MmUnsecureVirtualMemory 例程以取消保护内存地址范围的不透明指针值。 如果例程无法保护内存地址范围,它将返回 NULL

言论

MmSecureVirtualMemory 可用于避免用户模式缓冲区上的某些争用条件。 例如,如果驱动程序检查缓冲区是否可写,但原始用户模式进程将缓冲区更改为只读,然后驱动程序才能写入缓冲区,则争用条件可能会产生。 驱动程序可以将 MmSecureVirtualMemory 与PAGE_READWRITE探测模式配合使用,以确保在驱动程序调用 MmUnsecureVirtualMemory之前,缓冲区将保持可写状态。 该例程还可防止原始用户模式进程释放缓冲区。 下面是关于调用这些例程的一些准则:

  • 使用 PAGE_READONLY 调用 mmSecureVirtualMemory 不能保证缓冲区将保持只读状态。 只读探测模式可防止用户将缓冲区的保护更改为PAGE_NOACCESS。 它不会 防止将保护更改为映射视图的PAGE_READWRITE(或PAGE_WRITECOPY)。

  • 如果驱动程序调用 MmSecureVirtualMemory 且不调用 MmUnsecureVirtualMemory,则进程终止时,内存会自动不安全。

  • 如果驱动程序调用 mmUnsecureVirtualMemory,则必须在最初保护内存的进程上下文中调用它,并在该进程终止之前调用它。

  • 通常情况下,驱动程序在保护内存时需要引用进程,然后稍后调用 KeStackAttachProcess,以便在调用 MmUnsecureVirtualMemory之前切换到该进程的上下文。

  • 若要检测进程终止驱动程序,可以使用 PsSetCreateProcessNotifyRoutine。 或者,进程可以提交 IRP,其中包含在进程退出时由 I/O 管理器调用的取消例程。 在 cancel 例程中,驱动程序可以附加到进程并调用 MmUnsecureVirtualMemory

虽然 MmSecureVirtualMemory 可用于保证读取或写入用户内存不会由于页面权限不足而引发异常,但它不会防范其他类型的异常。 例如,当系统在页面文件中找到错误的磁盘块时,它不会防止引发异常。 因此,驱动程序仍必须将所有用户内存访问包装在 try/except 块之外。 因此,我们建议驱动程序不使用此函数。 有关详细信息,请参阅 处理异常

要求

要求 价值
目标平台 普遍
标头 ntddk.h (包括 Ntddk.h)
NtosKrnl.lib
DLL NtosKrnl.exe
IRQL <=APC_LEVEL
DDI 符合性规则 HwStorPortProhibitedDIs(storport)IrqlMmApcLte(wdm)

另请参阅

mmUnsecureVirtualMemory