3

Windows サービスとして機能する Windows XP のソフトウェアを使用し、ログオン画面から再起動すると、悪名高いエラー メッセージが表示される

「00x...」の命令が「00x...」のメモリを参照しました。メモリを読み取れませんでした。

開発者に問題を報告しましたが、メッセージをもう一度見て、アドレスが同じであることに気付きました。そう

「00xdf3251」の命令が「00xdf3251」のメモリを参照していました。メモリを読み取れませんでした。

これがプログラムのバグであるかどうかにかかわらず、メモリ/アクセス権の状態、または命令が配置されたメモリを読み取るのを妨げる何か他のものは何ですか。それはサービスに固有のものですか?

4

2 に答える 2

2

アドレス 0xdf3251 で命令を実行しようとしたが、その場所は読み取り可能で実行可能なメモリ ページ (おそらく完全にマップされていない) によってバックアップされていなかったと思います。

その場合、例外 (実際にはページ フォールト) はその命令から発生し、例外ハンドラーはスタック上にそのアドレスを持っています (例外が何らかの形で解決され、エラーが発生した命令が再開された場合に戻る場所)。ハンドラが返されます)。そして、それはあなたが見ている最初の住所です。

ページ フォールト ハンドラーが読み取るレジスタ( CR22 番目に表示されているアドレス) にも同じアドレスが含まれています。

  • マッピングの完全な欠如 (マッピングされたページはまったくありません)
  • 書き込み権限の欠如 (ページは読み取り専用です)
  • 実行権限がない (ページに非実行ビットが設定されている) または
  • カーネル特権の欠如 (ページはカーネルでのみアクセス可能としてマークされています)

データアクセス中か命令のフェッチ中かは関係ありません (後者が今回のケースです)。

これが、命令とメモリアクセスアドレスを等しくする方法です。

ほとんどの場合、コードにバグがあり、メモリが破損し、一部のポインタ (またはスタックの戻りアドレス) が、アクセスできないメモリ位置を指す偽の値で上書きされました。そして、何らかの方法で CPU がそこで実行を継続するように指示されました (ほとんどの場合、これらの命令のいずれかを使用します: jmpcallret)。どこかで競合状態になる可能性もあります。

于 2012-05-03T08:59:43.557 に答える
1

この種のクラッシュは、通常、スタックの破損が原因で発生します。非常に一般的な種類は、スタック バッファ オーバーフローです。スタックに格納された配列に大量のデータを書き込むと、関数の戻りアドレスがデータで上書きされます。その後、関数が戻ると、偽の戻りアドレスにジャンプし、アドレスにコードがないため、プログラムは失敗します。破損が発生した場所を見つける簡単な方法がないため、バグを修正するのに苦労するでしょう。

これはかなり悪名高い種類のバグであり、マルウェアの主要な攻撃ベクトルです。プログラムをデータ付きの任意のコードにジャンプするように命令できるからです。これらの開発者と話し合い、これを指摘する必要があります。これは重大なセキュリティ リスクです。治療は簡単です。ツールを更新する必要があります。最近ではコンパイラにバッファオーバーフロー対策が組み込まれています。

于 2012-05-03T10:03:02.013 に答える