Winnyのキャッシュファイルをウィルススキャンする方法を考えて試してみたらダメな感じだった

最近のウィルス作者逮捕騒動で、高木浩光@自宅の日記 - ウイルス駆除のためWinnyのCacheフォルダを仮想ドライブ化してはどうかという話を思い出して、でもドライバを作るのはちょっと面倒だし、2時間くらいでちゃちゃできる方法がないかなーと考えてみて、心当たりがあったので試したところダメでしたという話。
やりたかったことは、

  • Winnyのキャッシュファイルにウィルスが含まれているならそのキャッシュを消したい

で、方法としては

  • キャッシュに対してウィルススキャンを行い、ウィルスが検出されればキャッシュを削除する

というとてもシンプルなもの。
私はFirefox3がダウンロードしたファイルのウィルスチェックを(たぶんインストールされているアンチウィルスソフトに依存せずに)自動で行っているの見ていたので、なにかベンダー共通のウィルススキャンAPIでもあるのかなーと前から思っていて、今日調べてみると、

IOfficeAntiVirus interface (Windows)

でウィルスキャンが行える*1ということが分かったので、これを使って、

  1. 一時フォルダ内でキャッシュから一時ファイルへデコード
  2. IOfficeAntiVirus::Scanでウィルススキャン
  3. ウィルスが検出された場合キャッシュを削除
  4. 一時ファイルを削除
  5. 次のファイルへ……

でいいんじゃないかなと思ったけれど、インストールされているGrisoftのAVG Freeで試したところいくつか問題があって、微妙にダメかなーという感じだった。
内容としては……

IOfficeAntiVirus::Scanの動きが予想と違う

チェック結果を返してくれるだけと思ったのに、ウィルスが検出されると
f:id:ultraist:20080203084246j:image
こんな感じのダイアログがモーダルで出てきて処理が止まるのでうざい。
また選択した操作によってScan()から返り値が変わる。(たとえばIgnoreを選択すると、S_OKが返る)
MSOAVINFO.fReadOnlyRequestを設定しても選択する操作によってファイルが消される。
などなど。

LZHに対応してない

これはAVG自体の問題だけど、日本以外ではあまり使われていないLZHにAVGが対応していないので、アーカイブのままだとウィルスが検出されない。しかもWinnyで蔓延しているウィルスはLZHを使っているものが多い。
LZHは、UNLHA32.DLLに脆弱性があったため、AVGだと解凍しないとウィルスが検出できない上に、解凍すると感染しそうになって怖い状態だったので、ウィルス作者がウィルスのアーカイブ形式にLZHを好んで使う理由には納得。
この問題は、仮想ドライブの実装にしても同様なので、AVGWinny用としては不適切だと思う。

ファイルのクローズイベントかなにかで自動スキャンする設定にしていると変換した時点で検出されるかも?(予想)

変換後に一時ファイルが消えていたらキャッシュも消せばいいけど、検出されるたびにダイアログが出てくるのがうざい。

個人的まとめ

LZHにも対応しているアンチウィルスソフトをインストールして、キャッシュのスキャン中はパソコンの前でダイアログが出てこないか監視して、ウィルスが検出されるたびに削除ボタンをクリックするならOK(でもソフトによって実装が違うかもしれない)。

この方法でスキャナを作るときに参考になる資料



IOfficeAntiVirus interface (Windows)


404 Not Found
mozilla/toolkit/components/downloads/src/nsDownloadScanner.cppで、IOfficeAntiVirusインターフェースを使ったウィルススキャンを行っている。
WinnyCacheinfo Ver.1.02
添付されているソースコードに、Winnyのキャッシュファイルを元ファイルにデコードする関数がある。

がんばって仮想ドライブのドライバを作るなら……

TrueCryptソースコードを使うと楽?

*1:もちろんソフトが対応していれば