9

是否有可能在没有获得 Windows 错误报告 (WER) 对话框的情况下使 Windows-7 上的常规用户模式进程崩溃?(何时以及是否正常启用 WER 并且未应用特定标志。)

注意:我对禁用 WER感兴趣,我对未启动 WER 的崩溃场景感兴趣,尽管它应该启动并且 Windows“静默”终止应用程序。

在 Windows XP 上,编写一个 C 或 C++ 应用程序(在用户模式下)以这样的方式弄乱自己的地址空间是非常简单的,当最终引发访问冲突(或其他未处理的 Win32 异常)时,Windows XP 将只是默默地终止进程而不通知用户:

...
void stackbreaker() {
    printf("%s\n", __FUNCTION__);
    // global/static buffer
    static char buf[128] = "In a hole in the ground there lived a hobbit. And it burrowed through your stack. It even built a round door into you function.";
    // Get address on the stack
    char local;
    char* stack = &local;
    // nuke the stack:
    memcpy(stack - 64, buf, sizeof(buf));
    // Kaboom. No user defined unhandled exception filter will be called. Stack nuked.
    // Process will terminate silently on Windows XP.
    // But on Windows-7 you still get the WER dialog.
}
...

在一个简单的 C++ 项目中调用上述函数(在发布模式下——在测试时注意那些编译器优化——而不是在调试器下运行)将:

  • 在 XP 下静默终止进程。
  • 在 Windows-7 下显示 WER 崩溃对话框。
  • 旁白:在任何情况下,它都不会调用您自己的未处理异常过滤器,即使您设置了一个通过SetUnhandledExceptionFilter

我现在想知道的是 - 在 Windows 7 下 - WER 机制是否已经以一种方式实现,即我的应用程序中总是会出现崩溃[a]的错误对话框,或者即使在 Windows 7 中是否存在进程损坏情况,这将阻止 WER 对话框弹出?


我将添加一些我所做的阅读:

Windows via C/C++(Richter, Nasarre 第 5 版)一书中,他们描述了“故障过程”中发生的情况(第 711 页):

  1. 异常过滤器。
  2. ...
  3. ...
  4. 内核检测到未处理的异常
  5. 阻止对 Wer 服务的 ALPC 调用
  6. WER 报告开始。
  7. ...

现在,他们指出,Win7 的做法与 Windows XP 不同(引用本书第 710 页:)

... 从 Windows Vista 开始,该UnhandledExceptionFilter功能不再向 MS 的服务器发送错误报告。反而。内核检测到用户模式线程未处理异常(步骤 4)...

所以这意味着,根本没有办法让进程“崩溃”——在 Vista 及更高版本中——以一种阻止 WER 启动的方式。我试图确认或反驳这一点。


[a]:显然,通过调用各种*exitterminate*函数之一,可以轻松地“杀死”进程而不会留下任何痕迹。问题是,如果您可以排除这种终止原因,(如何)可能以阻止显示 WER 对话框的方式在 Win7 上“崩溃”用户模式进程。

4

2 回答 2

6

我查看了我的 Windows Internals 版本,但在这个主题上并没有太多要说的。在早期版本中,Windows 错误报告例程发生在崩溃线程的上下文中。这意味着如果堆栈被丢弃(如您的示例中所示),它可能无法运行。

在 Vista 及更高版本中,它在崩溃线程的外部运行。此外,内核本身负责在进程崩溃时通知 WER(通过高级本地过程调用)。

根据 Windows Internals 的说法,这些更改修复了消失的进程问题。我只能相信他们的话。显然,如果 WER 服务本身损坏(或停止),您仍然会遇到静默崩溃。

编辑

来自 Windows Internals,第 5 版,第 122 页:

在 Windows Vista 之前,我们描述的所有 [WER] 操作都必须发生在崩溃线程的上下文中……在某些类型的崩溃中……未处理的异常过滤器本身就崩溃了。这种“静默进程死亡”没有记录在任何地方。...如果未处理的异常过滤器本身崩溃,Windows Vista 和更高版本通过从崩溃的线程外部执行这项工作来改进 WER 机制。

第 124 页:

...所有 Windows 进程现在都有一个错误端口,该端口实际上是 WER 服务注册的 ALPC 端口对象。内核...将使用此端口向 WER 服务发送消息,然后该服务将分析崩溃过程。...这解决了静默进程死亡的所有问题...

于 2013-01-11T23:28:38.603 回答
3

您已经知道如何使进程崩溃,所以我回答有关隐藏 WER 对话框的问题。
自 Windows XP 以来隐藏 WER 对话框的方法:

UINT WINAPI SetErrorMode(_In_  UINT uMode);

SEM_NOGPFAULTERRORBOX 0x0002 系统不显示 Windows 错误报告对话框。

请注意,错误对话框还有其他原因,也可以使用此功能禁用它们,请查看文档以获取更多信息。

此外,从 Windows 7 开始:

BOOL SetThreadErrorMode(
  _In_   DWORD dwNewMode,
  _Out_  LPDWORD lpOldMode
);

一些程序和 dll-s 使用这些功能向用户隐藏错误。

于 2014-05-20T04:09:46.030 回答