9

Windows エラー報告 (WER) ダイアログを表示せずに、Windows-7 で通常のユーザー モード プロセスをクラッシュさせることはできますか? (WER が通常有効で、特定のフラグが適用されていない場合。)

注: WER を無効にすることには興味がありませ。WER が起動されるべきなのに起動されず、Windows がアプリを "サイレントに" 終了するというクラッシュ シナリオに興味があります。

Windows XP では、アクセス違反 (またはその他の未処理の 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 では、アプリケーションのクラッシュ[a]に対して常にエラー ダイアログが表示されるように WER メカニズムが実装されているのか、それとも Windows 7 でもプロセス破損のシナリオが存在するのかということです。 WERダイアログがポップアップしないようにしますか?


私が行った読み上げを少し追加します。

本のWindows via C/C++ (Richter、Nasarre による第 5 版)では、「フォールティング プロセス」(p 711) で何が起こるかを説明しています。

  1. 例外フィルター。
  2. ...
  3. ...
  4. カーネルが未処理の例外を検出
  5. Wer サービスへの ALPC 呼び出しのブロック
  6. WER レポートが開始されます。
  7. ...

ここで彼らは、Win7 が Windows XP とは異なる方法でこれを行うことを指摘しています (この本の p. 710 を引用すると:)

... Windows Vista 以降、このUnhandledExceptionFilter機能は MS のサーバーにエラー レポートを送信しなくなりました。その代わり。カーネルは、例外がユーザーモード スレッドによって処理されていないことを検出します (ステップ 4)...

したがって、これは、プロセスが「クラッシュ」する方法がまったくないことを意味します-Vista以降では、WERの開始を妨げる方法で.私はこれを確認または反論しようとしています.


*exit[a]: 明らかに、さまざまな関数または関数のいずれかを呼び出すことで、プロセスを跡形もなく簡単に「強制終了」できterminate*ます。問題は、そのような終了理由を除外できる場合、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 に答える