数据执行保护

数据执行防护 (DEP) 是一种系统级内存保护功能,从 Windows XP 和 Windows Server 2003 开始,内置于操作系统中。 DEP 使系统能够将一个或多个内存页标记为不可执行。 将内存区域标记为不可执行意味着代码无法从该内存区域运行,这使得利用缓冲区溢出更加困难。

DEP 阻止从默认堆、堆栈和内存池等数据页运行代码。 如果应用程序尝试从受保护的数据页运行代码,则会发生内存访问冲突异常,如果未处理该异常,调用进程将终止。

DEP 并非旨在对所有攻击进行全面防御;它旨在用作另一个可用于保护应用程序的工具。

数据执行防护的工作原理

如果应用程序尝试从受保护的页运行代码,则应用程序会收到异常,状态代码 STATUS_ACCESS_VIOLATION。 如果应用程序必须从内存页运行代码,则必须分配和设置适当的虚拟 内存保护 属性。 分配内存时,分配的内存必须标记为 PAGE_EXECUTEPAGE_EXECUTE_READPAGE_EXECUTE_READWRITEPAGE_EXECUTE_WRITECOPY 。 通过调用 mallocHeapAlloc 函数进行的堆分配是不可执行的。

应用程序无法从默认进程堆或堆栈运行代码。

DEP 是在系统启动时根据启动配置数据中的“不执行页保护策略”设置配置的。 应用程序可以通过调用 GetSystemDEPPolicy 函数来获取当前策略设置。 根据策略设置,应用程序可以通过调用 SetProcessDEPPolicy 函数更改当前进程的 DEP 设置。

编程时的注意事项

应用程序可以使用 VirtualAlloc 函数分配具有相应内存保护选项的可执行内存。 建议应用程序至少设置 PAGE_EXECUTE 内存保护选项。 生成可执行代码后,建议应用程序设置内存保护,以禁止对分配的内存进行写入访问。 应用程序可以使用 VirtualProtect 函数禁止对分配的内存进行写入访问。 禁止写入访问可确保对进程地址空间的可执行区域提供最大保护。 应尝试创建尽可能使用最小可执行地址空间的应用程序,从而最大程度地减少内存被利用的内存量。

还应尝试控制应用程序的虚拟内存布局并创建可执行区域。 这些可执行区域应位于比非可执行区域更低的内存空间中。 通过将可执行区域定位到非可执行区域下方,可以帮助防止缓冲区溢出溢出到内存的可执行区域。

应用程序兼容性

某些应用程序功能与 DEP 不兼容。 执行动态代码生成 ((如实时代码生成) )且未使用执行权限显式标记生成的代码的应用程序在使用 DEP 的计算机上可能存在兼容性问题。 (ATL) 版本 7.1 及更早版本写入活动模板库的应用程序可以尝试在标记为不可执行的页面上执行代码,这会触发 NX 错误并终止应用程序;有关详细信息,请参阅 SetProcessDEPPolicy。 执行与 DEP 不兼容的操作的大多数应用程序必须更新才能正常运行。

少量可执行文件和库可能包含图像文件的数据部分中的可执行代码。 在某些情况下,应用程序可能会在数据部分中放置小段代码 (通常称为 thunks) 。 但是,DEP 将内存中加载的图像文件部分标记为不可执行,除非该部分应用了可执行属性。

因此,数据部分中的可执行代码应迁移到代码部分,或者包含可执行代码的数据节应显式标记为可执行文件。 可执行文件属性 IMAGE_SCN_MEM_EXECUTE,应添加到包含可执行代码的节的相应节标头的 “特征” 字段中。 有关向节添加属性的详细信息,请参阅链接器附带的文档。

数据执行保护

如何在 Windows XP SP2 中配置内存保护