MS Windowsのカーネル空間でのプログラミングを伴う、小さいながらも非常に陰湿な待ち伏せ

数日前、私はドライバーをデバッグしていました。どのカオスを使用し、一見すると、ある種の魔法のBSoDが登場しました。 すべての関数呼び出しは正しく、ヌルポインターやその他の一般的なhemoによるエラーは観察されませんでした。 このドライバーに何が起こるか理解していないので、経験豊富な同僚に何が間違っているのかを尋ねました。 数時間後、彼はバグの理由を理解したと言った。 結果は私たちの両方を落胆させた。



クラッシュの理由は単純であることが判明しました:ドライバーロジックでスタックがアクティブに使用され、多くの場合、関数はさまざまなバッファーとアレイのスタックで10〜20 kbのメモリを使用しました。 MSDNによると、カーネルスタックは3ページのメモリ(32ビットアーキテクチャの場合は約12kb)に制限されているため、複数の関数呼び出しと再帰の使用は控えた方が良いとされています。

カーネルスタックオーバーフローエラーが発生すると、いわゆる二重障害が発生します。 プロセッサはスタックオーバーフローを報告し、このエラーに関する情報を含む構造体を既にオーバーフローしたスタックに配置しようとするため、別のエラーが発生し、カーネルは「苦しみに死ぬ」以外に選択肢はありません(これに関する情報はここから取得されます )。

また、IoGetRemainingStackSize関数を使用して、スタック上のメモリの5〜6 kbのみがフィルタードライバーに到達するため、1つのフィルタードライバーがシステムにロードされず、複数の場合、障害およびBSoDの確率が大幅に増加することがわかりました。

そのため、ドライバーに奇妙なBSoDがある場合は、これがスタックのメモリ不足によるものかどうかを確認し、間違いを繰り返さないでください。




All Articles