Skip to content

Instantly share code, notes, and snippets.

@nus
Last active July 23, 2019 14:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nus/2a2e7a0b7ea6058e27d97650623005aa to your computer and use it in GitHub Desktop.
Save nus/2a2e7a0b7ea6058e27d97650623005aa to your computer and use it in GitHub Desktop.
Windows のパケットキャプチャ方法
  1. WinSock2 の RawSocket でキャプチャ
  2. NDIS ドライバでのキャプチャ
  3. Windows Filtering Platform でのキャプチャ

WinSock2 の RawSocket でキャプチャ

NDIS ドライバでのキャプチャ

Windows Filtering Platform でのキャプチャ

Win10Pcap コードリーディング

Win10Pcap は、 WinPcap ライブラリの API を Windows 10 向けに提供するドライバ・ライブラリ。ライセンスは、 GPL 。

Win10Pcap の構成。

Windows<--Driver Inteface-->NdisDriver<--Event-->NdisDriverUser<--Function Call-->Packet32
  • NdisDriver
    • フィルタードライバーとして実装されている。
    • NdisDriver/NdisDriver.cDriverEntry 関数がドライバとしての処理の始まり。
    • NdisDriver/NdisDriverCommon.h には、ドライバ自体のパラメータのほかに、ドライバ以外のモジュールと通信ためのパラメータが記載されている
  • NdisDriverUser
    • ドライバ側の NdisDriver に対して、アプリ側のコードが直接通信するためのコード。 NdisDriver と NdisDriverUser の通信には、 OpenEvent 関数が作ったハンドラを利用している。
    • Packet_dll/NdisDriverUser.c が、
  • Packet32
    • WinPcap の API 実装部分
    • NdisDriverUser で作ったイベントのハンドラを経由して、ドライバからパケットデータを受信する

NdisDriver 側のイベント生成処理

NdisDriver.c の SlNewEvent の処理で、イベントハンドラ生成処理がなされている。 KeInitializeEvent API でイベントハンドラが生成されている。 CreateEvent API ではなかった。KeInitializeEvent API は、カーネルランドのコードで使用されるため。

イベント生成は、 KeSetEvent API でイベントを生成している。 SetEvent API ではなかった。

ユーザーランドのコードがパケットを受信準備の処理

  1. CreateFile API を使ってデバイスをオープンする。ファイル名には、 \\.\<DeviceName> を利用する。
  2. 開いたデバイスに対して、DeviceIoControl して、パケット受信用イベント名を取得。コントロールコードには、 SL_IOCTL_GET_EVENT_NAME (定数: 0x80000007) を指定する。
  3. OpenEvent API を使ってパケット受信用イベントハンドラを取得。イベント名には、パケット受信用イベント名を指定。

対象環境

Visual Studio 2019 Windows 10

調査目的

NDIS ドライバを作りにあたって、 Windows ドライバの作り方を学ぶことが目的。 Windows ドライバを作る過程のメモを記載しておく。

開発環境

Windows 10 上の Visula Studio 2019 を使う。

Windows ドライバ

参考 https://docs.microsoft.com/ja-jp/windows-hardware/drivers/install/components-of-a-driver-package

典型的なドライバパッケージには、次のファイルが含まれている。

  • ドライバファイル
  • インストールファイル
  • その他のファイル

ドライバファイル

ドライバとは、デバイスの I/O インタフェースを提供するパッケージの一部である。 典型的なドライバファイルは、拡張子に .sys が付く DLL ファイル。 デバイスがインストールされると、 sys ファイルは、 %SystemRoot%\system32\drivers にコピーされる。

マイクロソフトは、たくさんの共通なデバイスドライバを OS に同梱している。これらの同梱されたドライバを利用したい場合は、minidriver を書くだけでよい。 minidriver は、システム提供のドライバに沿ったデバイス仕様を取り扱う。(COM ポートのドライバとか該当するかも。) minidriver でさえ必要がないデバイスがいくつかある。例えば、モデムなど。

インストールファイル

  • デイバスセットアップ情報(INF)ファイル

INF ファイルは、デバイスのインストールサポートに使われる system-provided device installation components という情報を含んでいる。 INF ファイルは、デバイスインストール中に %SystemRoot%\inf ディレクトリへ Windows によってコピーされる。 デバイスは、INFファイルを持っていないといけない(must)。

  • ドライバカタログ(.cat)ファイル

ドライバカタログファイルは、ドライバパッケージの各ファイルのハッシュを含んだファイルのこと。 Windows は、そのハッシュを認証するために利用するので、出荷後は、変更できない。 カタログファイルが変更されていないことをかくにんするために、デジタル署名を用いるべき(should)。

その他のファイル

デバイスインストールアプリケーション、デバイスアイコン、デバイスプロパティページといったファイル。

ドライバサンプルを試す

https://github.com/microsoft/Windows-driver-samples/ をクローンする network/ndis/filter/filter.sln を Visual Studio 2019 で開く。

開いたときに以下のエラーが出るときは、 Windows Driver Kit (WDK) をインストールすることで解決する。

条件 "$(_NT_TARGET_VERSION)<$(_NT_TARGET_VERSION_WIN7)" で、数字ではなく "" と評価された "$(_NT_TARGET_VERSION)" に対して、数値比較を実行しようとしました。

以下のエラーが出るときは、 プロジェクトの 構成プロパティ -> Inf2Cat -> General -> Use Local TImeはい (/uselocaltime) を入れる。 参考 http://blog.livedoor.jp/cielo_cielo/archives/65844807.html

1>Signability test failed.
1>
1>Errors:
1>22.9.7: DriverVer set to a date in the future (postdated DriverVer not allowed) in ndislwf\netlwf.inf.
1>
1>Warnings:
1>None
1>Debug\inf2catOutput.log : Inf2Cat error -2: "Inf2Cat, signability test failed." Double click to see the tool output.

簡単なドライバコードの説明

とっつきやすい。 http://yamatyuu.net/computer/program/driver/beeptest32/index.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment