カーネル モードの WFP ドライバーとユーザー モードのアプリケーション間の双方向通信が必要です。ドライバーは、アプリケーションに URL を渡すことによって通信を開始し、アプリケーションはその URL の分類 (エンターテイメント、ニュース、アダルトなど) を行い、そのカテゴリーをドライバーに返します。ドライバーはフィルター機能のカテゴリーを知る必要があります。これは、その情報に基づいて特定の Web ページをブロックする可能性があるためです。ドライバーが URL と GUID を使用して完了する I/O 要求を作成するスレッドがアプリケーションにあり、アプリケーションはその GUID の下のレジストリにカテゴリを書き込み、そこでドライバーがそれを取得しました。残念ながら、ドライバーの検証者が指摘したように、Zw レジストリ機能は PASSIVE_LEVEL で実行する必要があるため、これは不安定です。マップされたメモリバッファで同じことをしようと考えていましたが、そのための割り込み要件が何であるかわかりません。また、レジストリ関数呼び出し前の割り込みレベルを下げることも考えましたが、その副作用についてはわかりません。
3 に答える
2 種類の I/O 要求が必要なだけです。
URL を取得するためにを使用している場合DeviceIoControl
(これが最も適切な方法だと思います)、これは 2 番目の I/O 制御コードを追加するのと同じくらい簡単です。
または同等のものを使用している場合ReadFile
、通常は少し面倒ですが、この特定のケースで発生するように、2種類の操作しかありません.1つは読み取り(ドライバー->アプリケーション)で、もう1つは書き込み (アプリケーション -> ドライバー)。したがってWriteFile
、ドライバーが応答を正しいクエリに一致させることができるように、もちろん GUID を含む応答を送信するために使用できます。
別のアプローチ (元のアプローチに似ています) は、共有メモリ バッファーを使用することです。詳細については、この回答を参照してください。この考え方の問題点は、スピンロックを使用するか (システムのパフォーマンスと電力消費が犠牲になり、もちろんシングルコア システムでは作業できない)、ポーリングする必要があることです (これは非効率的であり、時間に敏感な操作にはあまり適していません)。
PASSIVE_LEVEL については何も不安定ではありません。レジストリへのアクセスは PASSIVE_LEVEL である必要があるため、ドライバーがより高い IRQL で実行されている場合、直接アクセスすることはできません。ただし、ワークアイテムにオフロードすることでそれを行うことができます。IRQL を下げることは、OS の意図と矛盾するため、通常はお勧めしません。
あなたのプロトコルは確かにやや面倒に聞こえますが、アプリドライバーと直接通信する方がおそらく望ましいでしょう。これに関する有用な情報は、http: //msdn.microsoft.com/en-us/library/windows/hardware/ff554436 (v=vs.85).aspx で見つけることができます。
コールアウトは DISPATCH にあるため、処理はワーカー スレッドまたは DPC で行う必要があります。これにより、ZwXXX を使用できるようになります。通信目的で逆コールバックを使用する必要があります。OSR に関する適切なドキュメントがあります。
WFP をいじり始めたばかりですが、彼らが提供するサンプルでも、Microsoft がパケットを再注入しているようです。私はそれを詳しく調べていませんが、パケットがドロップされ、処理されるたびに再注入されるようです。使用モードエンジンが決定を下すには、これで十分です。また、必要のない余分な処理を行わないように、パケット キャプチャを特定のポート (この場合は 80) に制限する必要があります。