VirtualProtectFromApp 函数 (memoryapi.h)

更改调用进程的虚拟地址空间中已提交页面区域的保护。

语法

BOOL VirtualProtectFromApp(
  [in]  PVOID  Address,
  [in]  SIZE_T Size,
  [in]  ULONG  NewProtection,
  [out] PULONG OldProtection
);

参数

[in] Address

一个指针,该地址描述要更改其访问保护属性的页面区域的起始页。

指定区域中的所有页面都必须在使用 MEM_RESERVE 调用 VirtualAllocVirtualAllocFromAppVirtualAllocEx 函数时分配 同一保留区域。 页面不能跨通过单独调用 VirtualAlloc、VirtualAllocFromAppVirtualAllocEx(使用 MEM_RESERVE)分配相邻保留区域。

[in] Size

要更改其访问保护属性的区域的大小(以字节为单位)。 受影响页面的区域包括从 Address 参数到 (Address+Size)的范围中包含一个或多个字节的所有页面。 这意味着跨页边界的 2 字节范围会导致两个页面的保护属性发生更改。

[in] NewProtection

内存保护选项。 此参数可以是 内存保护常量之一。

对于映射视图,此值必须与映射视图时指定的访问保护兼容 (请参阅 MapViewOfFileMapViewOfFileExMapViewOfFileExNuma) 。

以下常量生成错误:

  • PAGE_EXECUTE_READWRITE
  • PAGE_EXECUTE_WRITECOPY
只有具有 codeGeneration 功能的应用才允许使用以下常量:
  • PAGE_EXECUTE
  • PAGE_EXECUTE_READ

[out] OldProtection

指向变量的指针,该变量接收指定页区域中第一页的先前访问保护值。 如果此参数为 NULL 或未指向有效的变量,则该函数将失败。

返回值

如果该函数成功,则返回值为非零值。

如果函数失败,则返回值为零。 要获得更多的错误信息,请调用 GetLastError。

注解

你可以从具有实时 (JIT) 功能的 Windows 应用商店应用调用 VirtualProtectFromApp ,以使用 JIT 功能。 应用必须在应用清单文件中包含 codeGeneration 功能才能使用 JIT 功能。

只能在提交的页面上设置访问保护值。 如果未提交指定区域中任何页面的状态,则函数将失败并返回 ,而不会修改指定区域中任何页面的访问保护。

PAGE_GUARD保护修饰符建立保护页。 保护页充当一次性访问警报。 有关更多信息,请参见创建保护页

最好避免使用 VirtualProtectFromApp 更改 GlobalAlloc、HeapAlloc 或 LocalAlloc 分配的内存块上的页面保护,因为单个页面上可能存在多个内存块。 堆管理器假定堆中的所有页面至少授予读取和写入访问权限。

VirtualProtectFromApp 允许将页面标记为可执行文件,但不允许同时设置写入和执行权限。

保护可执行的区域时,调用程序负责在代码设置到位后通过适当调用 FlushInstructionCache 来确保缓存一致性。 否则,尝试在新可执行区域之外执行代码可能会产生不可预知的结果。

要求

要求
最低受支持的客户端 Windows 10 [桌面应用 |UWP 应用]
最低受支持的服务器 Windows Server 2016 [桌面应用 |UWP 应用]
目标平台 Windows
标头 memoryapi.h (包括 Windows.h)
Library WindowsApp.lib
DLL Kernel32.dll

另请参阅

内存管理函数

虚拟内存函数

VirtualAllocFromApp

VirtualProtect

VirtualProtectEx