(57)【要約】【課題】メディアチェックを行うアプリケーションのメディアチェックを回避する技術を提供する。【解決手段】メディアチェック回避システムは、メディアチェックを行うアプリケーション（例えば1405）に対してインジェクションを行う起動用バッチファイル（例えば1400）と、インジェクションアプリケーション（202）と、フック用動的リンクライブラリー（例えば1403）と、を有する。起動用バッチファイルは、メディアチェックを行うアプリケーションに対してインジェクションアプリケーションを介してフック用動的リンクライブラリーをロードさせる機能を備える。起動用バッチファイルを実行することによって、メディアを正しい状態でマウントしていない状態で、メディアチェックを行うアプリケーションにメディアチェックを行わせる。【選択図】図１４
2011013955.tif 000002
【特許請求の範囲】
【請求項１】
メディアチェックを行うアプリケーションに対してインジェクションを行う起動用バッチファイルと、インジェクションアプリケーションと、フック用動的リンクライブラリーと、を有するメディアチェック回避システムであって、
前記メディアチェックを行うアプリケーションは、指定したメディアが正しい状態でマウントされているかどうかをチェックする機能と、前記指定したメディアが正しくマウントされていない、または前記指定したメディアが不正と判断した場合にプログラムの続行を中断する機能を備え、
前記インジェクションアプリケーションは、前記メディアチェックを行うアプリケーションに対して前記フック用動的リンクライブラリーをロードし、前記メディアチェックを行うアプリケーションがメディアチェックを行うためにOS標準APIを呼び出した時に前記フック用動的リンクライブラリーが呼び出されるようにする機能を備え、
前記フック用動的リンクライブラリーは、前記メディアチェックを行うアプリケーションがメディアチェックを行うためにOS標準APIを呼び出した時に前記メディアチェックを行うアプリケーションがメディアが正しい状態でマウントされていると判断する結果を返す機能を備え、
前記起動用バッチファイルは、前記メディアチェックを行うアプリケーションに対して前記インジェクションアプリケーションを介して前記フック用動的リンクライブラリーをロードさせる機能を備え、
前記起動用バッチファイルを実行することによって、メディアを正しい状態でマウントしていない状態で、前記メディアチェックを行うアプリケーションにメディアチェックを行わせることを特徴とするメディアチェック回避システム。
【請求項２】
請求項１に記載のメディアチェック回避システムであって、
前記フック用動的リンクライブラリーは、フックが必要な状況かどうかを判断する機能と、フックが必要な状況であると判断した場合に前記メディアチェックを行うアプリケーションがメディアが正しい状態でマウントされていると判断する結果を返す機能と、フックが必要な状況でないと判断した場合にOS標準APIを呼び出す機能と、を備えることを特徴とするメディアチェック回避システム。
【請求項３】
請求項１または２に記載のメディアチェック回避システムであって、
前記フック用動的リンクライブラリーは、前記メディアチェックを行うアプリケーションがGetDriveType APIを呼び出した時に、DRIVE_CDROMを返すことを特徴とするメディアチェック回避システム。
【請求項４】
請求項１ないし３のうちいずれか１項に記載のメディアチェック回避システムであって、
前記フック用動的リンクライブラリーは、前記メディアチェックを行うアプリケーションがGetVolumeInformation APIを呼び出した時に、前記メディアチェックを行うアプリケーションが指定したメディアのボリュームラベルを返すことを特徴とするメディアチェック回避システム。
【請求項５】
請求項１ないし４のうちいずれか１項に記載のメディアチェック回避システムであって、
前記フック用動的リンクライブラリーは、前記メディアチェックを行うアプリケーションがGetFileAttributes APIを呼び出した時に、対象ファイルが前記メディアチェックを行うアプリケーションがチェックに用いるメディアチェック用のファイルかどうかを判断し、メディアチェック用のファイルである場合はFILE_ATTRIBUTE_NORMALを返し、メディアチェック用のファイルでない場合はOS標準のGetFileAttributes APIを呼び出すことを特徴とするメディアチェック回避システム。
【請求項６】
請求項１ないし５のうちいずれか１項に記載のメディアチェック回避システムであって、
前記フック用動的リンクライブラリーは、前記メディアチェックを行うアプリケーションがCreateFile APIを呼び出した時に、対象ファイルが前記メディアチェックを行うアプリケーションがチェックに用いるメディアチェック用のファイルかどうかを判断し、メディアチェック用のファイルである場合はあらかじめ用意したダミーファイルを対象としてOS標準のCreateFile APIを呼び出しその結果であるファイルハンドルをコンテナに登録し、メディアチェック用のファイルでない場合はOS標準のCreateFile APIを呼び出すことを特徴とするメディアチェック回避システム。
【請求項７】
請求項１ないし６のうちいずれか１項に記載のメディアチェック回避システムであって、
前記フック用動的リンクライブラリーは、前記メディアチェックを行うアプリケーションがGetFileSize APIを呼び出した時に、対象ファイルハンドルが前記コンテナに存在するかどうかを判断し、存在する場合は前記メディアチェックを行うアプリケーションがチェックに用いるメディアチェック用のファイルのファイルサイズを返し、存在しない場合はOS標準のGetFileSize API呼び出すことを特徴とするメディアチェック回避システム。
【請求項８】
請求項１ないし７のうちいずれか１項に記載のメディアチェック回避システムであって、
前記フック用動的リンクライブラリーは、前記メディアチェックを行うアプリケーションがCloseHandle APIを呼び出した時に、対象ファイルハンドルが前記コンテナに存在するかどうかを判断し、存在する場合は前記コンテナの当該ファイルハンドルを削除し、OS標準のCloseHandle API呼び出すことを特徴とするメディアチェック回避システム。
【請求項９】
請求項１ないし８のうちいずれか１項に記載のメディアチェック回避システムであって、
前記インジェクションアプリケーションは、createRemoteThread APIを用いて前記フック用動的リンクライブラリーをロードするとともに、インポートアドレステーブルの書き換えまたはGetProcAddress APIのフックを行い、前記フック用動的リンクライブラリーが呼び出されるようにすることを特徴とするメディアチェック回避システム。
【請求項１０】
請求項１ないし９のうちいずれか１項に記載のメディアチェック回避システムであって、
前記起動用バッチファイルは、前記インジェクションアプリケーションに、前記メディアチェックを行うアプリケーションおよび前記フック用動的リンクライブラリーを引数で渡すことを特徴とするメディアチェック回避システム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、一部アプリケーションに見られる起動時のCD/DVD等のメディアのチェックを回避するメディアチェック回避システムに関し、CD/DVD等のメディアを挿入することなくアプリケーションを実行することを可能とする技術に関するものである。
【背景技術】
【０００２】
従来のCD/DVDメディアチェックの回避策としては、仮想CD/DVDソフトを使用する方法では、CD/DVDイメージをマウントすることにより回避を行う方法が知られている（特許文献１参照）。
【０００３】
またファイルを書き換える方法では、実行モジュールのチェックロジック部分に対応するマシン語を書き換えることにより回避を行う方法が知られている（特許文献２参照）。
【先行技術文献】
【特許文献】
【０００４】
【特許文献１】特開２００６−２０９３６７号公報
【特許文献２】特開２００３−３１６６０５号公報
【発明の概要】
【発明が解決しようとする課題】
【０００５】
上述した仮想CD/DVDソフトを使用する方法では、仮想CD/DVDイメージをHDDに保存しておく必要があり、HDD容量を大きく浪費する（一般的にCD/DVDメディアは大容量であるため）。また、起動ソフトを切り替える度に仮想CD/DVDイメージをマウント/アンマウントするという手間が発生する。
【０００６】
上述した実行ファイルを書き換える方法では、実行ファイル（マシン語）の解析および修正（任意のマシン語に書き換え）には高度なマシン語知識およびデバッグ技術が必要となった。更に、実行ファイルが改竄されていないかチェックしているソフトには対応できなかった。改竄チェック自体を潰すことも不可能ではないが、それはCD/DVDメディアチェックを潰すことよりも難易度が高いことが多い。パッカー等の技術を利用してマシン語にスクランブル（圧縮および暗号化）を施しているソフトも存在する。この場合は実行ファイル内のマシン語書き換え自体が非常に困難となる。また、対象バイナリーが少しでも異なると、書き換え方法も異なる。つまり、修正パッチ等により細かい差分バージョンが存在する場合、それぞれのバージョンに対して異なる書き換え方法が必要となる。実行ファイルを書き換えてしまうので、後日公式に修正パッチ等が公開された場合、そのままでは適用できなくなった。
【０００７】
本発明は上記問題を解決し、HDD容量を大きく浪費することなく、手軽に、バイナリーバージョンに依存しない形で、実行ファイルを書き換えることなく、高度なマシン語知識およびデバッグ技術を必要とせずに、メディアチェック回避を提供することを目的とするものである。
【課題を解決するための手段】
【０００８】
上記目的を達成するために、本発明のメディアチェック回避システムは、メディアチェックを行うアプリケーションに対してインジェクションを行う起動用バッチファイルと、インジェクションアプリケーションと、フック用動的リンクライブラリーと、を有するメディアチェック回避システムであって、前記メディアチェックを行うアプリケーションは、指定したメディアが正しい状態でマウントされているかどうかをチェックする機能と、前記指定したメディアが正しくマウントされていない、または前記指定したメディアが不正と判断した場合にプログラムの続行を中断する機能を備え、前記インジェクションアプリケーションは、前記メディアチェックを行うアプリケーションに対して前記フック用動的リンクライブラリーをロードし、前記メディアチェックを行うアプリケーションがメディアチェックを行うためにOS標準APIを呼び出した時に前記フック用動的リンクライブラリーが呼び出されるようにする機能を備え、前記フック用動的リンクライブラリーは、前記メディアチェックを行うアプリケーションがメディアチェックを行うためにOS標準APIを呼び出した時に前記メディアチェックを行うアプリケーションがメディアが正しい状態でマウントされていると判断する結果を返す機能を備え、前記起動用バッチファイルは、前記メディアチェックを行うアプリケーションに対して前記インジェクションアプリケーションを介して前記フック用動的リンクライブラリーをロードさせる機能を備え、前記起動用バッチファイルを実行することによって、メディアを正しい状態でマウントしていない状態で、前記メディアチェックを行うアプリケーションにメディアチェックを行わせることを特徴とする。
【発明の効果】
【０００９】
本発明によれば、HDD容量を大きく浪費することなく、手軽に、バイナリーバージョンに依存しない形で、実行ファイルを書き換えることなく、高度なマシン語知識およびデバッグ技術を必要とせずに、メディアチェックを回避することが可能となる。
【図面の簡単な説明】
【００１０】
【図１】本発明の実施の形態においてターゲットとなる一般的な起動時CD/DVDメディアチェックを実施するアプリケーションの、起動時CD/DVDメディアチェックのフローチャート図である。
【図２】本発明の実施の形態で採用するDLLインジェクションのイメージ図である。
【図３】Windows標準関数の呼び出し方法を示すイメージ図である。
【図４】DLLインジェクションによるWindows標準関数呼び出しフックのイメージ図である。
【図５】条件付フックのフローチャート図である。
【図６】ドライブ種別チェックのフローチャート図である。
【図７】フック用GetDriveType()のフローチャート図である。
【図８】ボリュームラベルチェックのフローチャート図である。
【図９】フック用GetVolumeInformation()のフローチャート図である。
【図１０】ファイル存在チェックのフローチャート図である。
【図１１】フック用GetAttributes()のフローチャート図である。
【図１２】ファイルサイズチェックのフローチャート図である。
【図１３】ファイルサイズチェックのフック方法のフローチャート図である。
【図１４】本発明の実施形態のメディアチェック回避システムの実際の運用方法のイメージ図である。
【発明を実施するための形態】
【００１１】
以下、本発明の実施の形態を図面に基づいて説明する。なお、全図において、同一機能を有するものは同一符号を付け、その繰り返しの説明は省略する。
【００１２】
図１は、一般的な起動時CD/DVDメディアチェックのフローチャートである。図1において、100は実行モジュールが不正でないかどうか調べるファイル改竄チェックステップ、101はCD/DVDドライブを検索するドライブ種別チェックステップ、102はCD/DVDメディアのボリューム名が正しいかどうか調べるボリュームラベルチェックステップ、103はメディア上に想定したファイルが存在するかどうか調べるファイル存在チェックステップ、104はメディア上に想定したファイルが正しい状態で存在するかどうか調べるファイルサイズチェックステップ、105は現在CD/DVDメディアが挿入されていないのでユーザーにCD/DVDメディアの挿入を促すメッセージボックスを表示する警告ステップである。本発明の目的を達成するためには、100〜104のチェックを全てクリアする必要がある。
【００１３】
次に、図１を用いて起動時CD/DVDメディアチェックを行う方法について説明する。図１においてまずはファイル改竄チェックステップ[100]を行う。ファイルが改竄されていない場合(「Yes」の場合)はドライブ種別チェックステップ[101]を行う。ファイルが改竄されていた場合(「No」の場合)は異常終了する。次にドライブ種別チェックステップ[101]を行う。ドライブ種別がCD/DVDドライブの場合(「Yes」の場合)はボリュームラベルチェックステップ[102]を行う。ドライブ種別がCD/DVDドライブ以外の場合(「No」の場合)はループの先頭に戻る。全てのドライブを検索しても[101]〜[104]のチェックをクリアできなかった場合は警告ステップ[105]を行う。次にボリュームラベルチェックステップ[102]を行う。ボリュームラベルが正しい場合(「Yes」の場合)はファイル存在チェックステップ[103]を行う。ボリュームラベルが正しくない場合(「No」の場合)はループの先頭に戻る。次にファイル存在チェックステップ[103]を行う。ファイルが存在する場合(「Yes」の場合)はファイルサイズチェックステップ[104]を行う。ファイルが存在しない場合(「No」の場合)はループの先頭に戻る。最後にファイルサイズチェックステップ[104]を行う。ファイルサイズが正しい場合(「Yes」の場合)は起動時チェック終了となる。ファイルサイズが正しくない場合(「No」の場合)はループの先頭に戻る。
【００１４】
ファイル改竄チェックステップ[100]は、本発明の手法では実行ファイルの書き換えは行わないので、自動的に正常扱いとなる。以下で、残りの[101]〜[104]のチェックステップをクリアする方法を説明する。
【００１５】
図２は、本発明の実施の形態のDLLインジェクションのイメージ図である。図２において、200はCD/DVDメディアチェックをクリアした場合のみ使用できるターゲットアプリケーション（メディアチェックを行うアプリケーション）、201はOSのカーネル機能を提供するダイナミックリンクライブラリであるWindows標準DLL（OS標準動的リンクライブラリー）、202はターゲットアプリケーション200に対してDLLインジェクションを行うインジェクションアプリケーション、203はターゲットアプリケーション200にロードさせるフック用DLL（フック用動的リンクライブラリー）、204はターゲットアプリケーション200に対してフック用DLLをロードさせるアタッチ操作、205はターゲットアプリケーション200からフック用DLLをアンロードさせるデタッチ操作である。
【００１６】
次に、図２を用いてDLLインジェクションを行う方法について説明する。Windowsアプリケーションはダイナミックリンクライブラリの機能を使用して動作する。今回ターゲットとなるターゲットアプリケーション[200]も、Windows標準DLL（Windows標準API）[201]の機能を使用して動作する。DLLインジェクションとは、任意のターゲットに任意のダイナミックリンクライブラリを強制的にロードさせる手法である。インジェクションアプリケーション[202]は、createRemoteThread()関数を使用して、ターゲットアプリケーション[200]に強制的にフック用DLL[203]をアタッチする[204]。これにより、ターゲットアプリケーション[200]の仮想アドレス空間にフック用DLL[203]の機能が強制的に作成されることになる。ただし、単にフック用DLL[203]をロードさせただけではターゲットアプリケーション[200]の挙動は変化しない。今回の目的はWindows標準DLL[201]の機能をフックすることである。そのためにロード時にIAT(インポートアドレステーブル)を書き換えることになる。IATとは、実行モジュールがロードしたダイナミックリンクライブラリを使用する際に、目的の関数が仮想アドレス空間のどこに存在するかという情報を保持するテーブルである。このテーブルを書き換えることにより、任意の外部関数呼び出しをフックすることが可能となる。尚、IATを介さないでGetProcAddress()関数から関数アドレスを取得しているケースも存在する。その場合は、GetProcAddress()関数自体をフックして、目的関数のアドレスを返却するようにする。起動時CD/DVDメディアチェックを回避し終えたら、IATを元の状態に戻してアタッチしたフック用DLL203をデタッチする[205]。
【００１７】
図３は、Windows標準関数の呼び出し方法を示すイメージ図である。図３において、300はWindows標準DLLの関数funcA()の呼び出し、301は外部関数のアドレス情報を保持するIAT、302はIAT301が保持しているfuncA()のアドレス、303はWindows標準DLL201に存在する関数のfuncA()である。
【００１８】
次に、図３を用いてWindows標準関数の呼び出し方法について説明する。ターゲットアプリケーション[200]がWindows標準DLLの関数funcA()を呼び出すと[300]、IAT[301]を検索してfuncA()のアドレス[302]を取得し、最終的にはそのアドレスに存在する関数funcA()[303]が呼び出される。
【００１９】
図４は、DLLインジェクションによるWindows標準関数呼び出しフックのイメージ図である。図４において、400は外部関数のアドレス情報を保持する書き換え後IAT 、401は書き換え後IATが保持しているfuncA()のアドレス、402はフック用DLL203に存在する関数のhook_funcA()である。
【００２０】
次に、図４を用いてDLLインジェクションによるWindows標準関数呼び出しフックについて説明する。ターゲットアプリケーション[200]がWindows標準DLLの関数funcA()を呼び出すと[300]、書き換え後IAT[400]を検索してfuncA()のアドレス[401]を取得し、最終的にはそのアドレスに存在する関数hook_funcA()[402]が呼び出される。
【００２１】
このように、DLLインジェクションの技術を利用することによって、Windows標準DLL関数の呼び出しをユーザーが独自に用意した任意の関数でフックすることが可能となる。本実施の形態では、[101]〜[104]のチェックステップをフックした関数が強制的に正しい場合（正式なCD/DVDメディアがドライブに挿入されている場合）と同じ動作をさせることによって、CD/DVDメディアを挿入することなくクリアさせる。以下で個別のチェックステップおよびクリア方法を示す。
【００２２】
図５は、条件付フックのフローチャート図である。図５において、500はフックを実行するべきかどうか判定するフックチェックを行うステップ、501はフック用関数の実行ステップ、502はWindows標準関数の実行ステップである。
【００２３】
次に、図５を用いて条件付フックについて説明する。Windows標準DLLの関数をフックする際に、無条件で標準関数の呼び出しをフック用関数で置き換えた場合、目的以外の場所から同じ関数が呼ばれた場合に、動作が不定となってしまう。従って、フック対象となる関数が呼ばれた場合、フック用関数を実行する[501]のかWindows標準関数を実行する[502]のか状況に応じて切り替える必要がある[500]。フック条件としては以下のようなものが考えられる。
【００２４】
１．引数による判定
２．コールスタックによる判定
引数による判定では、関数の引数情報を元にフックしたい状態なのかどうかを判定する。例えば引数で指定するファイル名がCD/DVDメディアチェックにおいて使われるファイルであった場合はフックする、それ以外のファイルが指定された場合はフックしない、といった判断を行う。
【００２５】
コールスタックによる判定では、コールスタック（関数の呼び出し履歴のこと。呼び出し元アドレス情報がスタックに記載されている。）を調べてその情報を元にフックしたい状態なのかどうかを判定する。例えば、コールスタックに「0x4000」「0x4100」が積まれていた場合はフックする、それ以外の場合はフックしない、といった判断を行う。
【００２６】
コールスタックによる判定を用いた場合は実行モジュールのアドレス依存になるので、バイナリーに依存しないという目的は達成できなくなる。従って、極力引数による判定で解決を図ることが望ましい。以下の説明でも引数による判定を採用している。
【００２７】
図６はドライブ種別チェックのフローチャート図である。図６において、600はドライブ種別の判定を行うGetDriveType()の実行、601は戻り値がDRIVE_CDROMかどうか判定するGetDriveType()実行結果のチェックステップである。
【００２８】
図７はフック用GetDriveType()のフローチャート図である。図７において、700はフック用GetDriveType()の実行ステップ、701は強制的にDRIVE_CDROM を返す戻り値ステップである。
【００２９】
次に、図６、７を用いてドライブ種別チェックついて説明する。ドライブ種別チェック[101]において、A〜Zドライブを全て検索して、CD/DVDドライブを検索している。各ドライブの種別はGetDirveType()の実行[600]で行う。その戻り値がDRIVE_CDROMだった場合はCD/DVDドライブと判定する[601]。CD/DVDドライブを搭載しているマシンで実行する場合はGetDirveType()をフックする必要はない。ノートパソコン等、CD/DVDドライブを搭載していないマシンで実行したい場合は、GetDriveType()[600]をフック用関数[700]でフックして戻り値を強制的にDRIVE_CDROMにする[701]。これにより[601]の判定が常にyesとなる。CD/DVDメディアチェックからユーザー入力を受け付けるまでの間にGetDriveType()を他の場所から呼ぶことはほとんどないと考えられるので、大半の場合は無条件でフックしても良い。
【００３０】
図８はボリュームラベルチェックのフローチャート図である。図７において、800はボリュームラベルを取得するGetVolumeInformation()の実行ステップ、801は戻り値がCD/DVDメディアのボリュームラベルかどうか判定するGetVolumeInformation()実行結果のチェックステップである。
【００３１】
図９はフック用GetVolumeInformation()のフローチャート図である。図９において、900はフック用GetVolumeInformation()の実行ステップ、901は強制的にCD/DVDメディアのボリュームラベルを返す戻り値ステップである。
【００３２】
次に、図８、９を用いてボリュームラベルチェックついて説明する。ボリュームラベルチェック[102]において、対象ドライブのボリュームラベルが、ターゲットアプリケーション[200]が要求しているCD/DVDメディアのボリュームラベルと同じかどうか調べている。ボリュームラベルの取得はGetVolumeInformation()[800]で行う。取得値を調べて[801]CD/DVDメディアのボリュームラベルだった場合はボリュームラベルチェック[102]はクリアとなる。このチェックをクリアするためにGetVolumeInformation()[800]をフック用関数[900]でフックして取得値を強制的にCD/DVDメディアのボリュームラベルにする[901]。これにより[801]の判定が常にyesとなる。CD/DVDメディアチェックからユーザー入力を受け付けるまでの間にGetVolumeInformation()を他の場所から呼ぶことはほとんどないと考えられるので、大半の場合は無条件でフックしても良い。
【００３３】
図１０はファイル存在チェックのフローチャート図である。図１０において、1000はファイルの存在および属性を取得するGetFileAttributes()の実行ステップ、1001は関数呼び出しが成功したかどうか判定するGetFileAttributes()実行結果のチェックステップ、1002は取得した属性がディレクトリ属性を持っていないかどうか判定するディレクトリ属性チェックステップである。
【００３４】
図１１はフック用GetFileAttributes()のフローチャート図である。図１１において1100はフック用GetFileAttributes()の実行ステップ、1101はフック用の処理を行うべきかどうか判定する対象ファイルのチェックステップ、1102は強制的にFILE_ATTRIBUTE_NORMALを返す戻り値ステップ、1103はWindows標準GetFileAttributes()の実行ステッである。
【００３５】
次に、図１０、１１を用いてファイル存在チェックついて説明する。ファイル存在チェック[103]において、対象ドライブ上にターゲットアプリケーション[200]が想定しているファイルが存在するかどうか調べている。ファイル属性の取得はGetFileAttributes()[1000]で行い、失敗したら異常終了させる[1001]。次に取得した属性がディレクトリ属性を持つかどうか調べてファイルなのかディレクトリなのか判定する[1002]。その結果がファイルであれば、ファイル存在チェック[103]はクリアとなる。このチェックをクリアするために、GetFileAttributes ()[1000]をフック用関数[1100]でフックして取得値を強制的にFILE_ATTRIBUTE_NORMALにする[1102]。CD/DVDメディアチェックからユーザー入力を受け付けるまでの間にGetFileAttributes()を他の場所から呼ぶことも十分考えられるので、引数のファイル名が?:\<対象ファイル>である場合のみフックして[1101]、それ以外の場合はWindows標準GetFileAttributes()を実行する[1103]。
【００３６】
図１２はファイルサイズチェックのフローチャート図である。図１２において、1200はファイルハンドルの取得を行うCreateFile()の実行ステップ、1201はファイルハンドルの取得が成功したかどうかを判定するCreateFile()実行結果のチェックステップ、1202はファイルサイズを取得するGetFileSize()の実行ステップ、1203はファイルサイズの取得が成功したのかどうかを判定するGetFileSize()実行結果のチェックステップ、1204はファイルハンドルを閉じるCloseHandle()の実行ステップ、1205は正しいファイルサイズかどうかを判定するファイルサイズチェックステップである。
【００３７】
次に、図１２を用いてファイルサイズチェックついて説明する。ファイルサイズチェック[104]において、対象ドライブ上にターゲットアプリケーション[200]が想定しているファイルのサイズが正しいかどうか調べている。ファイルサイズの取得を行うGetFileSize()[1202]の実行にはファイルハンドルが必要となる。そのため事前にファイルハンドルをCreateFile()[1200]により取得し、CloseHandle()[1204]で閉じる必要がある。最初にCreateFile()[1200]を実行し、失敗したら異常終了させる[1201]。次にGetFileSize ()[1202]を実行し、失敗したら異常終了させる[1203]。最後にCloseHandle()[1204]を実行して後始末をする。そしてGetFileSize()[1202]で取得した値が正しいファイルサイズだった場合はファイルサイズチェック[104]はクリアとなる。CD/DVDメディアチェックからユーザー入力を受け付けるまでの間にCreateFile()、GetFileSize()、CloseHandle()を他の場所から呼ぶことも十分考えられるので、ファイルサイズチェック[104]におけるフックでは特殊な操作が必要となる。
【００３８】
図１３はファイルサイズチェックのフック方法のフローチャート図である。図１３において、1300はフック用CreateFile()の対象とさせるためのダミーファイル、1301はフック用CreateFile()で作成したハンドル一覧を保持するファイルハンドルのコンテナ、1302はフック用CreateFile()の実行ステップ、1303はフック用の処理を行うべきかどうか判定する対象ファイルのチェックステップ、1304はWindows標準CreateFile()の実行ステップ、1305はダミーファイルのファイルハンドルを作成するダミーファイルに対するCreateFile()の実行ステップ、1306はファイルハンドルのコンテナへの登録ステップ、1307はフック用GetFileSize()の実行ステップ、1308はフック用の処理を行うべきかどうか判定するファイルハンドルのコンテナ存在チェックステップ、1309はWindows標準GetFileSize()の実行ステップ、1310は強制的に正しいファイルサイズを返す正しいファイルサイズの返却ステップ、1311はフック用CloseHandle()の実行ステップ、1312はフック用の処理を行うべきかどうか判定するファイルハンドルのコンテナ存在チェックステップ、1313はファイルハンドルの削除ステップ、1314はWindows標準CloseHandle()の実行ステップである。
【００３９】
次に、図１３を用いてファイルサイズチェックのフック方法ついて説明する。最初にフック用CreateFile()[1302]を実行する。対象ファイルからフックすべきかどうか判定し[1303]、チェック用のファイルを対象としている時には、予め用意しておいたダミーファイル[1300]を対象にしてCreateFile()を実行して[1305]、更にCreateFile()の結果（ファイルハンドル）をファイルハンドルのコンテナ[1301]に登録する[1306]。それ以外の場合はWindows標準CreateFile()を実行する[1304]。次にフック用GetFileSize()を実行する[1307]。対象のファイルハンドルがファイルハンドルのコンテナ[1301]に登録されているかどうか判定し[1308]、登録されていた場合は正しい値を強制的に返す[1310]。それ以外の場合はWindows標準GetFileSize()を実行する[1309]。最後にフック用CloseHandle()を実行する[1311]。対象のファイルハンドルがファイルハンドルのコンテナ[1301]に登録されているかどうか判定し[1312]、登録されていた場合はファイルハンドルのコンテナ[1301]からファイルハンドルを削除する[1313]。そしてWindows標準CloseHandle()を実行する[1314]。以上のフックにより[1201][1203][1205]のチェックが全てyesとなりファイルサイズチェック[104]をクリアすることができる。
【００４０】
図１４は実際の運用方法のイメージ図である。図１４において、1400はアプリケーションA ver1.00用バッチファイル、1401はアプリケーションA ver1.20用バッチファイル、1402はアプリケーションB ver1.00用バッチファイル、1403はアプリケーションA用フックDLL、1404はアプリケーションB用フックDLL、1405はアプリケーションA ver1.00、1406はアプリケーションA ver1.20、1407はアプリケーションB ver1.00である。
【００４１】
次に、図１４を用いて本発明の実施の形態のメディアチェック回避システムの実際の運用方法ついて説明する。Windows標準関数の呼び出しをフックする手法では、バイナリーの細かい差異には依存しない。つまり、修正バージョンが発生してもCD/DVDメディアチェック方法自体に変更がなければ、同じフック用DLL[203]によって回避が可能である。例えば、アプリケーションA ver1.00[1405]を起動したい場合およびアプリケーションA ver1.20[1406]を起動したい場合の双方で同じフックDLL[1403]を使用可能である。
【００４２】
ターゲットアプリケーション[200]毎にフック用DLL[203]を用意することによって、インジェクションアプリケーション[202]経由で様々なアプリケーションにフックすることが可能となる。例えば、アプリケーションA （[1405]および[1406]）を起動したい場合はアプリケーションA用フックDLL [1403]、アプリケーションB[1407]を起動したい場合はアプリケーションB用フックDLL [1404]をそれぞれ使用する。
【００４３】
アプリケーションA ver1.00用バッチファイル[1400]、アプリケーションA ver1.20用バッチファイル[1401]、アプリケーションB ver1.00用バッチファイル[1402]が、インジェクションアプリケーション[202]にターゲットアプリケーションおよび使用するフック用DLLを引数で渡すことによって、ワンクリックでターゲットアプリケーションの起動・アタッチ・デタッチが可能となる。例えば、アプリケーションA ver1.20を起動したい場合はアプリケーションA ver1.20用バッチファイル[1401]を実行する。
【００４４】
本実施の形態による回避でフック用DLL[203]の作成に必要となる情報は、ターゲットアプリケーションが指定する正しいボリュームラベル、ターゲットアプリケーションがチェックに用いるファイル名およびファイルサイズである。正しいボリュームラベルは実際にCD/DVDメディアをマウントすることによって容易に取得可能である。チェックに用いるファイル名については、フック用CreateFile()[1302]で対象となったファイル名を調べることにより推測可能となる。ファイル名が判れば正しいファイルサイズは容易に取得可能である。従って、一般的な起動時CD/DVDメディアチェックに対応するDLLの作成には高度なマシン語知識およびデバッグ技術は必要ない。
【００４５】
以上により、DLLインジェクションを用いてフック用DLL[203]をロードさせWidows標準関数の呼び出しをフックすることによって、HDD容量を大きく浪費することなく、バイナリーバージョンに依存しない形で、実行ファイルを書き換えることなく、高度なマシン語知識およびデバッグ技術を必要とせずに、CD/DVDメディアチェックを回避することが可能となる。
【００４６】
以上、本発明の実施の形態を詳細に説明したが、本発明の実施の形態のメディアチェック回避システムは、メディアチェックを行うアプリケーション（図１４の例えば1405に対応する。）に対してインジェクションを行う起動用バッチファイル（図１４の例えば1400に対応する。）と、インジェクションアプリケーション（図１４の202に対応する。）と、フック用動的リンクライブラリー（図１４の例えば1403に対応する。）と、を有するメディアチェック回避システムであって、前記メディアチェックを行うアプリケーションは、指定したメディアが正しい状態でマウントされているかどうかをチェックする機能と、前記指定したメディアが正しくマウントされていない、または前記指定したメディアが不正と判断した場合にプログラムの続行を中断する機能を備え、前記インジェクションアプリケーションは、前記メディアチェックを行うアプリケーションに対して前記フック用動的リンクライブラリーをロードし、前記メディアチェックを行うアプリケーションがメディアチェックを行うためにOS標準APIを呼び出した時に前記フック用動的リンクライブラリーが呼び出されるようにする機能を備え、前記フック用動的リンクライブラリーは、前記メディアチェックを行うアプリケーションがメディアチェックを行うためにOS標準APIを呼び出した時に前記メディアチェックを行うアプリケーションがメディアが正しい状態でマウントされていると判断する結果を返す機能を備え、前記起動用バッチファイルは、前記メディアチェックを行うアプリケーションに対して前記インジェクションアプリケーションを介して前記フック用動的リンクライブラリーをロードさせる機能を備え、前記起動用バッチファイルを実行することによって、メディアを正しい状態でマウントしていない状態で、前記メディアチェックを行うアプリケーションにメディアチェックを行わせるものであればよい。
【００４７】
前記フック用動的リンクライブラリーは、フックが必要な状況かどうかを判断する機能と、フックが必要な状況であると判断した場合に前記メディアチェックを行うアプリケーションがメディアが正しい状態でマウントされていると判断する結果を返す機能と、フックが必要な状況でないと判断した場合にOS標準APIを呼び出す機能と、を備えるものであってもよい。
【００４８】
前記フック用動的リンクライブラリーは、前記メディアチェックを行うアプリケーションがGetDriveType APIを呼び出した時に、DRIVE_CDROMを返すものであってもよい。
【００４９】
前記フック用動的リンクライブラリーは、前記メディアチェックを行うアプリケーションがGetVolumeInformation APIを呼び出した時に、前記メディアチェックを行うアプリケーションが指定したメディアのボリュームラベルを返すものであってもよい。
【００５０】
前記フック用動的リンクライブラリーは、前記メディアチェックを行うアプリケーションがGetFileAttributes APIを呼び出した時に、対象ファイルが前記メディアチェックを行うアプリケーションがチェックに用いるメディアチェック用のファイルかどうかを判断し、メディアチェック用のファイルである場合はFILE_ATTRIBUTE_NORMALを返し、メディアチェック用のファイルでない場合はOS標準のGetFileAttributes APIを呼び出すものであってもよい。
【００５１】
前記フック用動的リンクライブラリーは、前記メディアチェックを行うアプリケーションがCreateFile APIを呼び出した時に、対象ファイルが前記メディアチェックを行うアプリケーションがチェックに用いるメディアチェック用のファイルかどうかを判断し、メディアチェック用のファイルである場合はあらかじめ用意したダミーファイルを対象としてOS標準のCreateFile APIを呼び出しその結果であるファイルハンドルをコンテナに登録し、メディアチェック用のファイルでない場合はOS標準のCreateFile APIを呼び出すものであってもよい。
【００５２】
前記フック用動的リンクライブラリーは、前記メディアチェックを行うアプリケーションがGetFileSize APIを呼び出した時に、対象ファイルハンドルが前記コンテナに存在するかどうかを判断し、存在する場合は前記メディアチェックを行うアプリケーションがチェックに用いるメディアチェック用のファイルのファイルサイズを返し、存在しない場合はOS標準のGetFileSize API呼び出すものであってもよい。
【００５３】
前記フック用動的リンクライブラリーは、前記メディアチェックを行うアプリケーションがCloseHandle APIを呼び出した時に、対象ファイルハンドルが前記コンテナに存在するかどうかを判断し、存在する場合は前記コンテナの当該ファイルハンドルを削除し、OS標準のCloseHandle API呼び出すものであってもよい。
【００５４】
前記インジェクションアプリケーションは、createRemoteThread APIを用いて前記フック用動的リンクライブラリーをロードするとともに、インポートアドレステーブルの書き換えまたはGetProcAddress APIのフックを行い、前記フック用動的リンクライブラリーが呼び出されるようにするものであってもよい。
【００５５】
前記起動用バッチファイルは、前記インジェクションアプリケーションに、前記メディアチェックを行うアプリケーションおよび前記フック用動的リンクライブラリーを引数で渡すものであってもよい。
【符号の説明】
【００５６】
100：ファイル改竄チェックステップ
101：ドライブ種別チェックステップ
102：ボリュームラベルチェックステップ
103：ファイル存在チェックステップ
104：ファイルサイズチェックステップ
105：警告ステップ
200：ターゲットアプリケーション
201：Windows標準DLL（Windows標準API）
202：インジェクションアプリケーション
203：フック用DLL
204：フック用DLLのアタッチ操作
205：フック用DLLのデタッチ操作
300：Windows標準DLLの関数funcA()の呼び出し
301：IAT
302：IAT上のfuncA()のアドレス
303：funcA()
400：書き換え後IAT
401：書き換え後IAT上のfuncA()のアドレス
402：hook_funcA()
500：フックチェックを行うステップ
501：フック用関数の実行ステップ
502：Windows標準関数の実行ステップ
600：GetDriveType()の実行ステップ
601：GetDriveType()実行結果のチェックステップ
700：フック用GetDriveType()の実行ステップ
701：戻り値ステップ
800：GetVolumeInformation()の実行ステップ
801：GetVolumeInformation()実行結果のチェックステップ
900：フック用GetVolumeInformation()の実行ステップ
901：戻り値ステップ
1000：GetFileAttributes()の実行ステップ
1001：GetFileAttributes()実行結果のチェックステップ
1002：ディレクトリ属性チェックステップ
1100：フック用GetFileAttributes()の実行ステップ
1101：対象ファイルのチェックステップ
1102：戻り値ステップ
1103：Windows標準GetFileAttributes()の実行ステップ
1200：CreateFile()の実行ステップ
1201：CreateFile()実行結果のチェックステップ
1202：GetFileSize()の実行ステップ
1203：GetFileSize()実行結果のチェックステップ
1204：CloseHandle()の実行ステップ
1205：ファイルサイズチェックステップ
1300：ダミーファイル
1301：ファイルハンドルのコンテナ
1302：フック用CreateFile()の実行ステップ
1303：対象ファイルのチェックステップ
1304：Windows標準CreateFile()の実行ステップ
1305：ダミーファイルに対するCreateFile()の実行ステップ
1306：ファイルハンドルのコンテナへの登録ステップ
1307：フック用GetFileSize()の実行ステップ
1308：ファイルハンドルのコンテナ存在チェックステップ
1309：Windows標準GetFileSize()の実行ステップ
1310：正しいファイルサイズの返却ステップ
1311：フック用CloseHandle()の実行ステップ
1312：ファイルハンドルのコンテナ存在チェックステップ
1313：ファイルハンドルの削除ステップ
1314：Windows標準CloseHandle()の実行ステップ
1400：アプリケーションA ver1.00用バッチファイル
1401：アプリケーションA ver1.20用バッチファイル
1402：アプリケーションB ver1.00用バッチファイル
1403：アプリケーションA用フックDLL
1404：アプリケーションB用フックDLL
1405：アプリケーションA ver1.00
1406：アプリケーションA ver1.20
1407：アプリケーションB ver1.00
【図１】
2011013955.tif 000003
【図２】
2011013955.tif 000004
【図３】
2011013955.tif 000005
【図４】
2011013955.tif 000006
【図５】
2011013955.tif 000007
【図６】
2011013955.tif 000008
【図７】
2011013955.tif 000009
【図８】
2011013955.tif 000010
【図９】
2011013955.tif 000011
【図１０】
2011013955.tif 000012
【図１１】
2011013955.tif 000013
【図１２】
2011013955.tif 000014
【図１３】
2011013955.tif 000015
【図１４】
2011013955.tif 000016