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 可用于避免用户模式缓冲区上的某些争用条件。 例如,如果驱动程序检查缓冲区是否可写,但原始用户模式进程在驱动程序写入缓冲区之前将缓冲区更改为只读,则可能会导致争用条件。 驱动程序可以使用具有 PAGE_READWRITE 探测模式的 MmSecureVirtualMemory ,以确保缓冲区在驱动程序调用 MmUnsecureVirtualMemory 之前保持可写性。 例程还防止源用户模式进程释放缓冲区。 下面是有关调用这些例程的一些准则:

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

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

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

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

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

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

要求

要求
目标平台 通用
标头 ntddk.h (包括 Ntddk.h)
Library NtosKrnl.lib
DLL NtosKrnl.exe
IRQL <=APC_LEVEL
DDI 符合性规则 HwStorPortProhibitedDDI (storport) IrqlMmApcLte (wdm)

另请参阅

MmUnsecureVirtualMemory