2018年10月13日土曜日

C# : FiddlerCoreを使ってブラウザで見た画像ファイルを保存する

2019年5月追記) DecryptSSLの機能を使うにはFiddler用のルート認証が必要になります。 (最初この記事を書いたときはFiddler本体も入っていたので気付きませんでした)

一番手っ取り早くルート認証をインストールする方法はFiddler本体をインストールしてメインメニューの「Tools」-「Options」から「HTTPS」タブを選択、「Capture HTTPS CONNECTs」と「Decrypt HTTPS traffic」をチェックします。 ダイアログが表示されるので、中身をよく読んでルート認証をインストールしましょう。

追記終わり//


FiddlerはProxy型のhttp通信のデバッグツールです。 http通信を見張るだけではなく、リクエストやレスポンスを差し替えるなどかなり深い部分を触れるツールになっています。 サーバー側の変更をせずにレスポンスを書き換えることでウェブページのjavascriptをデバッグしたりとか、色んな用途に使われています。

強力なツールなだけに取っ付きにくい部分があります。 「あれがやりたいだけなのに……」ってときに重すぎるんですよね。 で、そのコア機能だけを提供するFiddlerCoreというライブラリが公開されています。 これを使って簡単なコードを書いた方が目的を気軽に達成できるケースも多い事でしょう。 そんなわけで今回はFiddlerCoreに触ってみました。 試しに通信中の画像ファイルを保存するサンプルコードを書いたので、そのメモを残しておきます。

※ FiddlerCoreを使う注意点として、ライセンスの問題があります。 詳しく調べていないのでよく分かりませんが、アプリに組み込んで配布するにはお金を払わないといけないのかな? (2015年あたりからそうなったっぽいです。) って事で多分フリーソフトに組み込むのは現実的ではありません。 趣味で使う場合は自分用ツールで、公開するならソース配布という事になりそうですね。

ちなみにリファレンスとかチュートリアルとかのドキュメントは一切読んでません。 適当です、適当。 その辺踏まえてお読みください。

試した環境

  • Windows10 64bit home
  • Visual Studio 2017 Community
  • .NET Framework 4.7 (WPF)
  • C# 7.1

FiddlerCoreの準備

まずはオフィシャルサイトからFiddlerCoreを貰ってきましょう。 聞かれた事を答えるだけでダウンロードできます。 会員登録などは必要ないようです。

解凍したら「FiddlerCoreAPIFreeSetup.exe」が出てくるので実行してインストールしましょう。 インストール先に「FiddlerCore45.dll」などのファイルが展開されます。 Visual StudioでC#のプロジェクトを作り、参照の追加で「FiddlerCore45.dll」を指定したらFiddlerCoreの機能が使えるようになります。

簡単な説明

基本機能はFiddlerApplicationというクラスの静的メンバーに触れば扱えるようです。 まずはアプリが起動したらすぐにコイツにイベントのリスナーを登録しましょう。 サンプルコードではhttpサーバーから画像を受け取るセッションが終わった時だけ処理すればいいのでFiddlerApplication.AfterSessionCompleteにリスナーを登録します。

CONFIG.IgnoreServerCertErrorsなるものも設定してますが、これについては調べてません。 色んなサンプルコードに書いてあったので丸パクリしました。 CONFIGとかって書いてあるのだから何かの設定なのでしょう。 その他にもFiddlerCoreを使うにはいくつかの設定が必要になります。 それにはFiddlerCoreStartupSettingsなるクラスを使います。

見ての通り、直接FiddlerCoreStartupSettingsクラスのインスタンスをnewするのではありません。 まずはFiddlerCoreStartupSettingsBuilderのインスタンスを作り、それにポート番号やオプションの情報を登録していきます。 有効にしたい機能のメソッドだけ呼び出せばいいようです。 最後にFiddlerCoreStartupSettingsBuilder.Buildで設定情報が詰まったFiddlerCoreStartupSettingsのインスタンスを作ります。

※ 間違っても不用意にAllowRemoteClientsは有効にしないように。 ファイアウォールの設定次第では悪い人達の踏み台にされる可能性があります。 これを有効にしたせいで悪いことをしていないのに怪しいツール認定されたモノもあるとか。

※ DecryptSSLはhttpsの通信を無理やり見張るために使います。 本来暗号化されているはずのデータが丸見えになります。 セキュリティ的な問題はあるのでそれなりに注意。 配布する場合はその点明記しなければなりません。

FiddlerApplication.Startupを呼べばFiddlerCoreの動作開始です。 引数は先ほど作ったFiddlerCoreStartupSettingsクラスのインスタンスです。 FiddlerCoreStartupSettingsではなく個別の設定項目を使ったStartupメソッドもありますが、そちらは古いやり方で非推奨だそうです。

FiddlerCoreがProxyとして動作し、それを通してhttpの通信セッションが完了するとFiddlerApplication.AfterSessionCompleteのイベントが発生します。 リスナーはこんな感じ。 (色々端折ってます。)

引数のoSessionにリクエスト/レスポンスの色んなデータが納められています。 中身はだいたい名前の通りなのでカンで扱えそうです。

注目すべきはFiddler.Session.utilDecodeResponseメソッドですね。 レスポンスが複数チャンクで返ってきた場合やgzip圧縮されていた場合、生データのままで扱うのは大変です。 それをメソッド1つでデコードしてくれるのがコレ。 単純にレスポンスのコンテンツを引っこ抜きたいだけの場合は忘れずに実行しましょう。 このサンプルは画像データを保存するだけのものなので、あとはデコードされたFiddler.Session.ResponseBody保存してメソッド終了です。

一通り通信を見張って情報収集が終わったらFiddlerCoreを閉めなければなりません。

FiddlerApplication.IsStartedでFiddlerCoreがProxyとして動作中か確かめることができます。 FiddlerApplication.Shutdownで終了……ですが即終わるわけではありません。 ある程度時間がかかります。 その待ち時間は厳密に測る必要はないでしょうからDispatcherTimerで定期的に調べてみました。 DispatcherTimer、なんか懐かしいですね。

終了処理中かどうかを調べるにはFiddlerApplication.isClosingをチェックします。 終了処理が終わったらDispatcherTimerを止めて、なんか特別にやる事があったら引数のActionを実行。

これでFiddlerCoreの開始から終了までの説明は終わりです。 説明した範囲だけなら簡単ですね。 Fiddlerがアレなので深みは本当にすごそうですが、この投稿で説明するのはここまで。

サンプルコード

説明したサンプルコードの全体を載せておきます。 WPFアプリケーションです。 ブラウザで見るのもアレでしょうから、テキストエディタなどにコピペしてお読みください。

ファイルは2つ。 まずはMainWindow.xaml.csです。 (ちなみにMainWindow.xamlの方はボタンを1つ付けてそのクリックイベントとWindow.Closingイベントを登録しただけなので割愛します。)

2つ目のソースはユーティリティメソッドを2つ書いただけのU.csです。

以上、何かのお役に立てば幸いです。