数据执行防护
数据执行防护(DEP)是一项系统级内存保护功能,从 Windows XP 和 Windows Server 2003 开始,内置于作系统中。 DEP 使系统能够将一个或多个内存页标记为非可执行文件。 将内存区域标记为非可执行文件意味着无法从内存区域运行代码,这使得开发缓冲区溢出变得更加困难。
DEP 可防止从数据页(例如默认堆、堆栈和内存池)运行代码。 如果应用程序尝试从受保护的数据页运行代码,则会发生内存访问冲突异常,如果未处理异常,调用进程将终止。
DEP 不是针对所有攻击的全面防御:它旨在成为可用于保护应用程序的另一个工具。
数据执行防护的工作原理
如果应用程序尝试从受保护的页面运行代码,则应用程序会收到状态代码 STATUS_ACCESS_VIOLATION异常。 如果应用程序必须从内存页运行代码,则必须分配并设置适当的虚拟 内存保护 属性。 分配的内存必须在分配内存时标记为 PAGE_EXECUTE、PAGE_EXECUTE_READ、PAGE_EXECUTE_READWRITE或 PAGE_EXECUTE_WRITECOPY。 通过调用 malloc 和 HeapAlloc 函数进行的堆分配是非可执行的。
应用程序无法从默认进程堆或堆栈运行代码。
DEP 在系统启动时根据启动配置数据中的“未执行页面保护”策略设置进行配置。 应用程序可以通过调用 GetSystemDEPPolicy 函数来获取当前策略设置。 根据策略设置,应用程序可以通过调用 SetProcessDEPPolicy 函数来更改当前进程的 DEP 设置。
编程注意事项
应用程序可以使用 VirtualAlloc 函数通过适当的内存保护选项分配可执行内存。 建议至少设置应用程序集 PAGE_EXECUTE 内存保护选项。 生成可执行代码后,建议应用程序设置内存保护,以禁止对分配的内存进行写入访问。 应用程序可以使用 VirtualProtect 函数禁止对分配的内存进行写入访问。 禁止写入访问可确保对进程地址空间的可执行区域的最大保护。 应尝试创建可能使用最小可执行地址空间的应用程序,从而最大程度地减少暴露在内存利用中的内存量。
还应尝试控制应用程序的虚拟内存布局并创建可执行区域。 这些可执行区域应位于内存空间低于非可执行区域的内存空间中。 通过在非可执行区域下面定位可执行区域,可以帮助防止缓冲区溢出到内存的可执行区域。
应用程序兼容性
某些应用程序功能与 DEP 不兼容。 执行动态代码生成(如 Just-In-Time 代码生成)且未显式标记具有执行权限的生成的代码的应用程序在使用 DEP 的计算机上可能存在兼容性问题。 写入到活动模板库 (ATL) 版本 7.1 及更早版本的应用程序可以尝试在标记为非可执行文件的页面上执行代码,这会触发 NX 错误并终止应用程序;有关详细信息,请参阅 SetProcessDEPPolicy。 执行与 DEP 不兼容的作的大多数应用程序都必须更新为正常运行。
少量的可执行文件和库可能包含图像文件的数据部分中的可执行代码。 在某些情况下,应用程序可能会在数据部分中放置少量代码段(通常称为 thunk)。 但是,DEP 会将内存中加载的图像文件的节标记为非可执行文件,除非该节应用了可执行属性。
因此,数据节中的可执行代码应迁移到代码节,或者包含可执行代码的数据节应显式标记为可执行文件。 可执行文件属性 IMAGE_SCN_MEM_EXECUTE应添加到包含可执行代码的节的相应节标头的 特征 字段。 有关向节添加属性的详细信息,请参阅链接器附带的文档。
相关主题
如何在 Windows XP SP2 中配置内存保护