Windowsのヘルプファイル

WindowsのWinHlp32.exeにバッファオーバーフローが見つかった話に関していろいろ。

Windowsのヘルプファイルが表示される手順には、いくつかの種類があります。

  1. ヘルプファイル(*.hlp)をダブルクリックする
  2. http://www.example.com/help.hlp のようなリンクをクリックする
  3. ヘルプ(WinHlp32.exe)を起動しておいて、「ファイル」「開く」でヘルプファイルを開く
  4. アプリケーション内でF1を押す等、ヘルプを呼び出す

1の方法では、レジストリにて *.hlp と関連付けされているアプリケーション(通常は WinHlp32.exe)が起動され、その結果、ヘルプファイルが表示されます。
2の方法では、ブラウザに依存するものの、「保存」や「開く」などの選択肢がユーザに求められ、「開く」を選択した場合には、1と同様に関連付けされている WinHlp32.exe によってヘルプファイルが開かれます。
これら2つの場合、ユーザ自身が不審なヘルプファイルを開かないように自衛すると同時に、レジストリ上の *.hlp の関連付けを削除しておくことにより、ヘルプファイルの表示を防ぐことができます。
3の方法では、レジストリの関連付けは利用されませんが、このような操作をすること自体極めて稀でしょうし、ユーザ自身が明確に意思を持ってファイルを開かない限り、問題は発生しませんので、影響は極めて低いでしょう。
さて本題。
4のアプリケーション内からのヘルプファイルの呼び出しは、通常 WinHelp というAPIを、ヘルプファイルのファイル名を引数として呼び出すことにより実現されています。このとき、レジストリの関連付けは使用されません
また、ドキュメントには記載されていませんが、ヘルプファイルのファイル名にパス名が含まれていない場合、以下のような順序でヘルプファイルが検索されます*1

驚くことに、カレントディレクトリの優先順位が一番高いのです。意外なことに、アプリケーションのexeがあるディレクトリは利用されません。

以上のように、アプリケーションから開かれるヘルプファイルは、ユーザにとってはどのファイルが開かれるのか非常に見極めにくくなっています。不審なヘルプファイルは、「開かない」だけでなく手元に置かないようにしましょう。

ちなみに、WinHelp に渡すファイル名として、"http://example.com/help.hlp" のような URL 文字列を渡した場合、ファイル名の basename すなわち help.hlp のみが使用され、結果として上記に書いたとおりカレントディレクトリにあるヘルプファイルが優先的に使用されます。

*1:Windows XPでのテスト結果