Windowsでパケットキャプチャをするなら、WiresharkとWinPcapの組み合わせが最も一般的だと思います。しかし、Windowsにもパケットキャプチャの機能が標準搭載されています。それはnetsh trace startコマンドです。
Windows 7以降のnetsh traceコマンドでパケットをキャプチャする方法 – Eiji James Yoshidaの記録
ならば、自分のアプリからも使えないものかと思い、netsh trace startがやっていることを調べてみました。同じようにAPIを呼び出せば、同じようにパケットキャプチャできるはずという、至極単純な発想です。
というわけで作ったプログラムがこちらです。
gist: “netsh trace start caputre=yes traceFile=D:\packet.etl”の再現
Windows 8.1とServer 2012 R2、ともにx64で動作を見ました。これを実行すると、netsh trace start capture=yes traceFile=D:\capture.etlを実行したかのように、パケットキャプチャが始まります。停止するには、netsh trace stopを実行します。
出力ファイルの拡張子が.ETLなので、ETW APIを使っていることは、即座に分かりました。しかし、それだけでは足りず、最終的に以下の処理が必要でした。
- ndiscapサービス(デバイスドライバ)を起動する。
- ndiscap関係のレジストリを書き換える。
- INetCfgでms_ndiscapを有効化する
- ETWのStartTrace, EnableTraceEx2関数を呼び出し、以下2つのトレースを開始する。
{83ED54F0-4D48-4E45-B16E-726FFD1FA4AF}: Microsoft-Windows-Networking-Correlation
{2ED6006E-4729-4609-B423-3EE7BCD678EF}: Microsoft-Windows-NDIS-PacketCapture
- netsh関係のレジストリを書き換える。
さて、これはまだnetshと同様にファイルに書き出すだけです。次は、これをファイルに書き出さず、パケットの中身を取れるようにしたいと考えるのが自然な発想でしょう。
実は、ETWのStartTraceでリアルタイムモードを指定してもパケットを取れることは確認しました。というわけで、次は、WinPcapのnpf.sys抜きでwpcap.dllを動かせないか、試しているところです。2016年6月27日追記:やった結果をWiresharkをWinPcap抜きで動かすに書きました。
スポンサード リンク |