关于“DEP数据执行保护”的解决方案



引入场景:在项目中,由于需要采用HOOK技术对记事本及OFFICE进行相关API挂钩,所以就必须应用到远程线程注入技术,我的代码是这样的:
                //修改内存页的属性
                DWORD dwOLD;
                MEMORY_BASIC_INFORMATION  mbi;
                VirtualQuery(lpAddr,&mbi,sizeof(mbi));
                VirtualProtect(lpAddr,sizeof(DWORD),PAGE_READWRITE ,&dwOLD);

                WriteProcessMemory(GetCurrentProcess(),lpAddr, &NewPage, sizeof(DWORD), NULL);

                //恢复内存页的属性
                VirtualProtect(lpAddr,sizeof(DWORD),dwOLD,0);
遗憾的是一运行到这里,就弹出DEP数据执行保户错误,应用程序退出。


介绍:Microsoft Windows XP Service Pack 2 使用一项新的数据执行保护 (DEP) 功能,可禁止执行数据页中的代码。当尝试运行标记的数据页中的代码时,就会立即发生异常并禁止执行代码。这可以防止攻击者使用代码致使数据缓冲区溢出,然后执行该代码。

    与防火墙或防病毒程序不同,DEP 不能阻止在您的计算机上安装有害程序。但是,它会监视您的程序,以确定它们是否安全地使用系统内存。为此,DEP 软件会单独或与兼容的微处理器一起将某些内存位置标记为“不可执行”。如果某个程序尝试从受保护的位置运行代码,DEP 将关闭该程序并通知您。即使该代码不是恶意代码,也会执行此操作。

64 位 Windows 版本上的 DEP

64 位处理器上的 64 位 Windows 版本可以在 64 位模式下运行程序。无论处理器的结构如何,64 位 Windows 版本的内核模式 DEP 均适用于堆栈、页面缓冲池和会话池。默认情况下,在 Windows XP SP2 中启用 DEP,并且无法将其禁用。64 位应用程序将无法从堆栈或默认进程堆中运行。对于需要分配可执行内存的应用程序,可使用带有某个 PAGE_EXECUTE* 内存属性的 VirtualAlloc( ) 来运行。

内核模式 DEP
对于用户模式和内核模式,DEP 的工作原理相同。在内核模式下,不能分别为每个驱动程序启用或禁用内存区域 DEP。默认情况下,在 32 位 Windows 版本上,DEP 仅适用于堆栈。在 64 位 Windows 版本上,DEP 适用于堆栈、页面缓冲池和会话池。内核模式下的访问冲突将导致出现 Bugcheck 0x000000FC:ATTEMPTED_EXECUTE_OF_NONEXECUTE_MEMORY。

兼容性问题

应用程序和驱动程序都可能会发生 DEP 兼容性问题。• 应用程序兼容性有些应用程序行为可能与 DEP 不兼容。执行动态代码生成(如实时代码生成)的应用程序以及不使用“执行”权限明确标记生成的代码的应用程序与 DEP 之间可能存在兼容性问题。
试图违反 DEP 的应用程序将会出现异常,并显示状态代码 STATUS_ACCESS_VIOLATION (0xc0000005)。如果应用程序需要可执行内存,则必须在相应的内存中明确设置此属性,方法是在 Virtual* 内存分配函数的内存保护参数中指定 PAGE_EXECUTE、PAGE_EXECUTE_READ、PAGE_EXECUTE_READWRITE 或 PAGE_EXECUTE_WRITECOPY。

驱动程序兼容性
驱动程序与 DEP 的兼容性问题主要是指由 PAE 模式引起的兼容性问题。DEP 本身可能与以下驱动程序之间存在兼容性问题:执行代码生成的驱动程序或使用其他方法实时生成可执行代码的驱动程序。始终为 64 位 Windows 版本上加载的驱动程序启用 DEP 支持。尽管许多创建可执行代码的驱动程序在 Windows XP SP2 中可能已得到修复,但是不能保证所有驱动程序都已更新。不过,因为使用这些方法的驱动程序非常少,所以 DEP 本身不会产生很多驱动程序兼容性问题。大多数驱动程序兼容性问题与在 32 位系统上运行 PAE 模式有关。如果启用 PAE 模式,有些驱动程序可能无法加载,这是因为该设备可能无法进行 64 位寻址,或者驱动程序可能假定 PAE 模式需要超过 4 GB 的 RAM。这些驱动程序认为,当它们处于 PAE 模式时,它们将始终接收 64 位地址,并认为它们(或其设备)无法解释该地址。
其他驱动程序可通过直接修改系统页表项,以便在 PAE 模式下进行加载,但这会导致系统不稳定。这些驱动程序需要 32 位页表项,但在 PAE 模式下它们收到的却是 64 位页表项。驱动程序与 PAE 之间最大的兼容性问题与直接内存访问 (DMA) 传输和映射寄存器分配有关。许多支持 DMA 的设备(通常是 32 位适配器)都无法进行 64 位物理寻址。当设备在 32 位模式下运行时,它可以对所有物理地址空间进行寻址。在 PAE 模式下,数据可以位于大于 4 GB 的物理地址中。在此情况下,为使具有这些限制的设备能够正常工作,Windows XP SP2 通过提供由映射寄存器指示的 32 位地址,为 DMA 事务提供双缓冲处理。设备可以执行到 32 位地址的 DMA 事务,而且内核将内存复制到为驱动程序提供的 64 位地址。当系统在禁用 PAE 的情况下运行时,32 位设备的驱动程序根本不需要实际内存来支持它们的映射寄存器。这意味着,不需要进行双缓冲处理,因为 32 位地址空间中包含所有设备和驱动程序。根据在基于 x86 和基于 x64 的计算机上对 32 位设备驱动程序进行的测试,大多数经过客户端测试并支持 DMA 的驱动程序都需要无限制的映射寄存器。
为限制兼容性问题,Windows XP SP2 对硬件抽象层 (HAL) 进行了更改以模拟 32 位 HAL DMA 行为。修改后的 HAL 使系统在 PAE 模式下运行时可以具有无限制的映射寄存器。另外,内核内存管理器忽略任何大于 4 GB 的物理地址。由于对 HAL 和内存管理器进行了这些更改,我们预计运行 Windows XP SP2 且支持 DEP 的系统上的设备驱动程序兼容性问题将会降到最低。

开发人员备注
需要可执行内存区域的应用程序在分配内存时,必须使用 PAGE_EXECUTE、PAGE_EXECUTE_READ、PAGE_EXECUTE_READWRITE 或 PAGE_EXECUTE_WRITECOPY 属性。另外,应用程序不能从默认进程堆或堆栈执行。

大多数执行与 DEP 不兼容的操作的应用程序必须进行更新,以便与 DEP 保持兼容。如果某个应用程序从专用堆分配可执行内存,则必须确保该堆内存中设置了 EXECUTE 标志。该应用程序可以使用 VirtualAlloc 应用程序编程接口 (API) 分配具有适当保护设置的内存。

如果应用程序不从专用堆分配可执行内存,则必须对其进行修改以使其从专用堆分配可执行内存。该应用程序必须使用 VirtualAlloc API 创建此堆,并且至少为该内存指定 EXECUTE 标志。生成的任何代码必须放在该可执行堆中。

在生成可执行代码后,我们建议您为该应用程序设置内存保护,以禁止通过 VirtualProtect API 对该堆进行写访问。该措施将为进程地址空间的那些可执行区域提供更多保护。

配置和疑难解答

与数据执行保护支持有关的故障的症状包括:在启用 DEP 时尝试从内存执行的应用程序中发生访问冲突。在此情况下,将出现一个对话框,指示应用程序因 DEP 而出现错误。该对话框包含与以下内容类似的

消息:
数据执行保护
Windows 安全功能检测到一个问题,并关闭了此程序。
名称:应用程序名称
发行商:应用程序发行商

数据执行保护帮助保护免受病毒和其他安全威胁的破坏。它是如何工作的?
(后跟“高级”和“确定”按钮。)
如果 DEP 是导致应用程序出现错误的原因,建议您与应用程序供应商取得联系,以确定是否有可用的更

新,以使应用程序在启用 DEP 时能够正常运行。要解决这些问题,建议您安装此更新。

在单击“确定”后,将出现一个标准的 Windows 错误报告提示,并提供一个发送错误报告的选项。还可

以通过“单击此处”选项查看收集了哪些信息。

在错误报告界面上单击“单击此处”链接后,将出现详细信息界面。在该数据的“错误签名”部分,您可

以查看是否将此错误标识为“事件类型:BEX。BEX 指示与 DEP 相关的错误。

此界面还提供其他信息,这些信息主要来自一些异常参数: 参数 数据
1 应用程序名称
2 应用程序版本
3 应用程序时间戳
4 模块名称
5 模块版本
6 模块时间戳
7 模块偏移
8 异常代码(c0000005=访问冲突、c0000409=缓冲区溢出)

在初始界面上,您还可以单击“高级”来访问 DEP 配置设置。您可以使用这些设置为出现错误的应用程序添加例外项。

“数据执行保护”对话框提供以下三个选项:• 为所有程序启用 DEP(推荐)
• 关闭 DEP(不推荐)
• 帮助保护除下列程序之外的所有程序:
通过选择其中一个选项,您可以排除一个或多个应用程序,或者为整个计算机配置 DEP 设置。如果设置“关闭 DEP”选项,则会为当前运行的 Windows 安装的 boot.ini 配置文件添加一个开关。boot.ini 开关如下所示:• /noexecute — 这是默认开关。启用 DEP。
• /execute — 它禁用 DEP。
注意:建议您不要全局性地禁用 DEP。这会使计算机处于不太安全的状态。

也可以在“系统”属性中访问这些 DEP 设置。

如果没有适用于您的应用程序的更新,请按照下列步骤操作以访问和配置 DEP 配置设置:1. 在应用程序

出现错误时,单击“高级”。
2. 在“数据执行保护”对话框中,选择“帮助保护除下列程序之外的所有程序:”
3. 单击应用程序旁边的复选框,然后单击“应用”。
4. 这时会出现一个提示,告诉您必须重新启动系统。单击“确定”。
5. 再次单击“确定”,然后重新启动系统。
也可以在“系统”属性中执行此过程:1. 单击“开始”,然后单击“控制面板”。
2. 在经典视图中,双击“系统”。
3. 单击“高级”选项卡,单击“性能”,然后单击“设置”。
4. 在“性能选项”对话框中,单击“数据执行保护”选项卡。
5. 选择“为所有程序和服务启用 DEP,但我选择的程序和服务除外:”,然后单击“添加”。
6. 在“打开”对话框中,找到并选择该应用程序,然后单击“打开”。
7. 单击“应用”,然后单击“确定”。将出现一个提示,通知您必须重新启动系统后设置才能生效。单

击“确定”。

解决办法:
作为软件开发者,我们应当尽理避免去采用配置的方法关闭用户系统的DEP保护,于是我试着对代码中相关部分加入EXECUTE权限,即
1.对远程线程注入加入EXECUTE权限
    void *pAddress=VirtualAllocEx(hProcess,NULL,strlen       

(DllName),MEM_COMMIT,PAGE_EXECUTE_READWRITE );
2.对IAT加入EXECUTE权限
    VirtualProtect(lpAddr,sizeof(DWORD),PAGE_EXECUTE_READWRITE ,&dwOLD);
编译,注入,OK!

有的网友说,”必须将跳板函数和钩子函数导出“,幸运的是,经过测试,这个步骤暂时并不需要。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值