如何使我的程序与 DEP 兼容?

Posted

技术标签:

【中文标题】如何使我的程序与 DEP 兼容?【英文标题】:How to make my program DEP-compatible? 【发布时间】:2010-09-25 22:39:51 【问题描述】:

我有一个 Windows 窗体 (.net 3.0) 项目,由于 DEP 错误,该项目无法在我客户的 vista 计算机上运行。它在我的 vista 机器上运行,并在虚拟机中的 vista sp1 的干净版本中运行。我无法找到使我的程序 DEP(数据执行保护)兼容的方法。我真的不能对最终用户机器做任何事情,它只需要运行。有什么办法可以摆脱这个最新的 vista 开发噩梦吗?我的程序使用 devexpress 控件、sql express 和 .net 即网络浏览器控件。我已经跳出了ie控制,但无济于事。我有其他程序在同一台机器上使用 devexpress 和 sql express,它们运行正常。我无法在用户的计算机上进行调试。

【问题讨论】:

【参考方案1】:

DEP 以两种模式之一运行:

1) 硬件 DEP 适用于可以将内存页面标记为不可执行的 CPU。这有助于防止某些漏洞,例如缓冲区溢出。

2) 软件 DEP 适用于不支持硬件 DEP 的 CPU。它不会阻止数据页中代码的执行,而是阻止 SEH 覆盖(另一种类型的攻击)。

在带有支持它的 CPU 的 Windows XP 上,默认情况下,硬件 DEP 仅对某些 Windows 系统二进制文件启用,也对选择“选择加入”的程序启用。

在具有支持它的 CPU 的 Vista 上,几乎所有进程都默认启用硬件 DEP。这有时会产生问题,通常对于较旧的程序和驱动程序,以及未进行任何 Vista 测试的 ISV。

所以我怀疑第一步是发现您是在处理软件还是硬件 DEP。另外,您使用的是 C#/VB 还是托管 C++?您是否使用任何本机代码或组件?如果您的应用程序使用原生组件或使用旧 ATL 框架构建的 ActiveX 控件,那么您的应用程序很可能会因硬件 DEP 而失败。

从 .NET Framework 2.0 SP1 开始,我相信 C# 编译器会发出与 DEP 兼容的托管代码。但是,如果您的应用程序正在生成 DEP 异常,那么您可以尝试清除可执行文件的 IMAGE_DLLCHARACTERISTICS_NX_COMPAT 标志。为此,您可以使用 VC 工具集中的 EDITBIN.EXE,如下所示:

editbin.exe /NXCOMPAT:NO <your binary>

如果您使用的是 Visual Studio,则可以将构建后步骤添加到可执行文件的项目中。您需要设置环境,以便可以解决 EDITBIN 的依赖关系。当我将本机代码用作应用程序的一部分时,构建后步骤如下所示:

call $(DevEnvDir)..\tools\vsvars32.bat
editbin.exe /NXCOMPAT:NO $(TargetPath)  

【讨论】:

我遇到了困难并专门使用(editbin.exe 不在工具中,所以我将其复制进去):调用“C:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat” editbin.exe /NXCOMPAT:NO "$(TargetPath)" TY 得到很棒的答案,将在客户结果中回复您。 在路径周围添加了引号,阻止了 VS2010 的执行【参考方案2】:

旧版本的 ATL 不支持 DEP,因此,如果您使用任何使用 ATL 构建的 ActiveX 控件,并且是在该版本的 ATL(我认为是 7.1 及以下版本)上构建的,您将收到 DEP 错误。

作为最后的手段,您实际上可以通过调用 API 函数为进程禁用 DEP:SetProcessDEPPolicy

更多关于SetProcessDEPPolicy的信息

【讨论】:

【参考方案3】:

.NET 2.0 SP1 附带的编译器打开可执行文件头中的 NXCOMPAT 标志。您可以通过运行带有 /NXCOMPAT:NO 选项的 EditBin.exe 在 Post Build 步骤中关闭该标志。

【讨论】:

【参考方案4】:

FWIW,值得明确指出的是,在许多情况下,应用程序并非“与 DEP 不兼容”,而是无论如何都会崩溃,而 DEP 会“介入以挽救局面”。很多时候,一旦你禁用 DEP,你会发现你遇到了一个“普通”的 AV。

如果您的项目仅使用 .NET 3.0 编写,几乎可以肯定是这种情况,因为 .NET 不会执行任何触发 DEP 的“疯狂”事情(例如函数重击等)。

要进行调试,请安装调试器或启用 Watson 生成 .DMP 文件,然后将该 .DMP 文件带到开发人员的机器上并找出问题所在。

【讨论】:

问题在于我必须在我的程序中使用旧的 activex 控件。它控制仪表,应用程序的主要目的是运行仪表。我一直无法让供应商使用更新的 atl 库重建应用程序。该应用程序还必须在所有最终用户机器上运行,我在其中一些机器上遇到了 dep 错误。我无法直接控制或管理用户机器。 啊。好吧,一种选择是使用 SetProcessDEPPolicy 来选择加入 DEP,而不是使用 NXCOMPAT 链接器选项。当您使用 SetProcessDEPPolicy 打开 DEP 时,它会启用 ATL Thunk Emulation,这与链接器选项不同。这就是 IE8 开启 DEP 以保持与古代 ATL 控件兼容的方式。【参考方案5】:

首先尝试找出您的程序在哪里以及如何失败。你能在你的系统上复制这个问题吗?为系统上的应用程序启用 DEP?当您可以复制问题并获得错误(访问冲突)时,您可以考虑修复您的程序。

请参阅MSDN article for information on DEP。

【讨论】:

这是一个完全不透明的情况。我没有从 vista 得到任何细节,我在系统上没有调试器。该程序在我的 dev vista 机器和干净的 vista 虚拟机上运行良好。

以上是关于如何使我的程序与 DEP 兼容?的主要内容,如果未能解决你的问题,请参考以下文章

我怎样才能使我的应用程序 MS EDGE 兼容

如何使我的网站与手机和平板电脑兼容? [关闭]

如何使我的 Web 应用程序与 SPDY、Jetty 一起工作 [关闭]

我如何使我的程序多次成功地追溯命令?

如何使用最佳约定规则使我的 Angular 5 应用程序按预期工作?

当使用 2 层架构将 UseEmbeddedHttpServer 设置为 true 时,如何使我的 RavenDB 应用程序正确执行?