(57)【要約】【課題】  インライン展開によるプログラム解析に必要な計算量と記憶領域量を増大させるプログラムを生成するプログラム難読化装置及び難読化プログラムを提供する。【解決手段】プログラム難読化装置は、プログラムに複数のサブルーチンを追加する追加手段２２３と、プログラム中の少なくとも１つの命令文を複数のサブルーチンの１つである第１のサブルーチンを呼び出す呼出命令に変換する変換手段２２４とを有し、複数のサブルーチンの各々は分岐構造を有し、分岐構造の分岐節の少なくとも１つが別の１つのサブルーチンの呼出命令を含み、複数のサブルーチンは第１のサブルーチンから１つずつ順番に実行されるように関連付けられており、最後に実行されるサブルーチンは命令文を実行する。【選択図】  図２
2010072958.tif 000002
【特許請求の範囲】
【請求項１】
プログラムに複数のサブルーチンを追加する追加手段と、
前記プログラム中の少なくとも１つの命令文を前記複数のサブルーチンの１つである第１のサブルーチンを呼び出す呼出命令に変換する変換手段とを有し、
前記複数のサブルーチンの各々は分岐構造を有し、該分岐構造の分岐節の少なくとも１つが別の１つのサブルーチンの呼出命令を含み、前記複数のサブルーチンは前記第１のサブルーチンから１つずつ順番に実行されるように関連付けられており、最後に実行されるサブルーチンは前記命令文を実行することを特徴とするプログラム難読化装置。
【請求項２】
前記分岐構造の分岐節のいずれか一方は、他方とは異なる別の１つのサブルーチンの呼出命令を含むことを特徴とする請求項１に記載のプログラム難読化装置。
【請求項３】
前記分岐構造の分岐節のいずれもが、別の１つのサブルーチンの呼出命令を含むことを特徴とする請求項１または２に記載のプログラム難読化装置。
【請求項４】
前記追加手段は、前記難読化対象のプログラムに複数のダミーのサブルーチンを追加し、
前記複数のサブルーチンの前記分岐構造の少なくとも１つは、前記複数のダミーのサブルーチンの呼出命令を含むことを特徴とする請求項１から３のいずれか一項記載のプログラム難読化装置。
【請求項５】
前記追加手段は、前記難読化対象のプログラムに含まれる変数を可逆的に操作する可逆関数を生成し、
前記分岐構造の分岐節の少なくとも１つは、前記可逆関数に基づいて前記変数を可逆的に操作する命令文を含むことを特徴とする請求項１から４のいずれか一項記載のプログラム難読化装置。
【請求項６】
前記分岐構造の条件式は、常に偽となる条件式であることを特徴とする請求項１から５のいずれか一項記載のプログラム難読化装置。
【請求項７】
コンピュータに、
プログラムに複数のサブルーチンを追加する追加手順と、
前記プログラム中の少なくとも１つの命令文を前記複数のサブルーチンの１つである第１のサブルーチンを呼び出す呼出命令に変換する変換手順とを実行させ、
前記複数のサブルーチンの各々は分岐構造を有し、該分岐構造の分岐節の少なくとも１つが別の１つのサブルーチンの呼出命令を含み、前記複数のサブルーチンは前記第１のサブルーチンから１つずつ順番に実行されるように関連付けられており、最後に実行されるサブルーチンは前記命令文を実行することを実現させるための難読化プログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、プログラム難読化装置及び難読化プログラムに関する。
【背景技術】
【０００２】
プログラムを悪意あるリバースエンジニアリングから守るために、様々なプログラム難読化技術が提案されている。プログラム難読化とは、プログラムの実行時動作を変えない限りにおいて、プログラムを人間にとって理解しづらくなるように変換する技術である。プログラムに難読化を施すことにより、リバースエンジニアリングにかかる費用や時間を大きくすることができる。ここで、リバースエンジニアリングとは、プログラムを解析し、モジュール間の関係の解明やシステムの基本仕様の分析をすることをいう。
【０００３】
特許文献１は、プログラムのソースコードに対して関数へのポインタ変数を新たに複数個導入し、関数ポインタ変数のいずれかに関数のアドレスを代入する命令文を複数個挿入し、プログラムにおける関数の呼出を関数ポインタ変数の値に応じて関数を呼出すように変換する。
【０００４】
特許文献２は、プログラムに含まれる繰り返し制御文を検出し、当該繰り返し制御文のインデックス変数に入力される値の順番を変更するようにプログラムの内容を変換する。
【０００５】
特許文献３は、アセンブリプログラムを構成する複数の命令コードを偽の命令コードＹで偽装するとともに、偽の命令コードＹを元の正しい命令コードｙに戻すルーチンＸと、ルーチンＸが戻した正しい命令コードｙを再度偽の命令コードＹで偽装するルーチンＺとを生成し、生成したルーチンＸ及びＺをアセンブリプログラム上の所定の位置に書き込み、自己書換えプログラムを生成する。
【０００６】
特許文献４は、プログラム中のデータを符号化規則Ｃ（ａ，ｂ）＝ａｘ＋ｂを用いて符号化し、符号化された符号化データを含む演算式の各演算子に演算子変換規則Ｒ（ａ，ｂ）〜Ｒ１０（ａ，ｂ）を適用することにより演算式を符号化演算式に変換し、符号化演算式を復号化規則Ｄ（ａ，ｂ）を用いて復号化演算式とする。さらに同様のプログラムの難読化を行う文献が非特許文献１ないし６に開示されている。
【０００７】
また、特許文献５では、プログラムの中から、複数の命令コードを含む関数を抽出し、抽出された関数に含まれる命令を非定型の関数呼出／復帰命令に変換する。したがって、逆コンパイラの異常終了や誤った出力結果を引き起こすことを可能にする実行形式の生成が可能となる。
【０００８】
【特許文献１】特開２００３−３３７６２９号公報
【特許文献２】特開２００４−１８５０６４号公報
【特許文献３】特開２００４−１９２０６８号公報
【特許文献４】特開２００５−４９９２５号公報
【特許文献５】特開２００７−３０４７２６号公報
【非特許文献１】C. Collberg, C. Thomborson, and D. Low, “Manufacturing Cheap, Resilient, and Stealthy Opaque Constructs”, Proceedings of the 25th ACM Symposium on Principles of Programming Languages, 1998
【非特許文献２】C. Collberg, C. Thomborson, and D. Low, “Breaking Abstractions and Unstructuring Data Structures”, Proceedings of the 1998 IEEE International Conference on Computer Languages, 1998
【非特許文献３】C. Wang and J. Hill and J. Knight and J. Davidson, “Software Tamper Resistance: Obstructing Static Analysis of Programs”, Technical Report CS-2000-12, Department of Computer Science, University of Virginia, 2000
【非特許文献４】門田暁人, 高田義広, 鳥居宏次, “ループを含むプログラムを難読化する方法の提案”, 電子情報通信学会論文誌, Vol. J80-D-I, No. 7, 1997
【非特許文献５】J. Chan and W. Yang, “Advanced Obfuscations on Java(登録商標) Bytecode”,Journal of Systems and Software, vol. 71(1?2), 2004
【非特許文献６】非特許文献6): C. Linn and S. Debry, “Obfuscation of Executable Code to Improve Resistance to Static Disassembly”, Proceedings of the 10th ACM Conference on Computer and Communications Security, 2003
【発明の開示】
【発明が解決しようとする課題】
【０００９】
本発明は、インライン展開を使用したプログラム解析に必要な計算量と記憶領域を増大させるプログラムを生成するプログラム難読化装置及び難読化プログラムを提供することを目的とする。
【課題を解決するための手段】
【００１０】
かかる目的を達成するために本発明の請求項１記載のプログラム難読化装置は、難読化対象のプログラムに、複数のサブルーチンを追加する追加手段と、前記プログラム中のプログラム片を前記複数のサブルーチンの１つである第１のサブルーチンを呼び出す呼出命令に変換する変換手段とを有し、前記複数のサブルーチンの各々は分岐構造を有し、該分岐構造の分岐節の少なくとも１つが別の１つのサブルーチンの呼出命令を含み、前記複数のサブルーチンは前記第１のサブルーチンから１つずつ順番に実行されるように関連付けられており、最後に実行されるサブルーチンは前記プログラム片を実行することを特徴としている。
【００１１】
請求項２記載の発明は、請求項１記載の発明において、前記分岐構造の分岐節のいずれか一方は、他方とは異なる別の１つのサブルーチンの呼出命令を含むことを特徴としている。
【００１２】
請求項３記載の発明は、請求項１または２に記載の発明において、前記分岐構造の分岐節のいずれもが、別の１つのサブルーチンの呼出命令を含むことを特徴としている。
【００１３】
請求項４記載の発明は、請求項１から３のいずれか一項記載の発明において、前記追加手段は、前記難読化対象のプログラムに複数のダミーのサブルーチンを追加し、前記複数のサブルーチンの前記分岐構造の少なくとも１つは、前記複数のダミーのサブルーチンの呼出命令を含むことを特徴としている。
【００１４】
請求項５記載の発明は、請求項１から４のいずれか一項記載の発明において、前記追加手段は、前記難読化対象のプログラムに含まれる変数を可逆的に操作する可逆関数を生成し、前記分岐構造の分岐節の少なくとも１つは、前記可逆関数に基づいて前記変数を可逆的に操作する命令文を含むことを特徴としている。
【００１５】
請求項６記載の発明は、請求項１から５のいずれか一項記載の発明において、前記分岐構造の条件式は、常に偽となる条件式であることを特徴としている。
【００１６】
請求項７記載の発明は、コンピュータに、難読化対象のプログラムに、複数のサブルーチンを追加する追加手順と、前記プログラム中のプログラム片を前記複数のサブルーチンの１つである第１のサブルーチンを呼び出す呼出命令に変換する変換手順とを実行させ、前記複数のサブルーチンの各々は分岐構造を有し、該分岐構造の分岐節の少なくとも１つが別の１つのサブルーチンの呼出命令を含み、前記複数のサブルーチンは前記第１のサブルーチンから１つずつ順番に実行されるように関連付けられており、最後に実行されるサブルーチンは前記プログラム片を実行することを実現させることを特徴としている。
【発明の効果】
【００１７】
請求項１の発明は、インライン展開によるプログラム解析に必要な計算量と記憶領域量を増大させるプログラムを生成する。
【００１８】
請求項２の発明は、サブルーチンに含まれる分岐構造のいずれの分岐節も別のサブルーチン呼出を含み、インライン展開によるプログラム解析に必要な計算量と記憶領域量を増大させるプログラムを生成する。
【００１９】
請求項３の発明は、サブルーチンに含まれる分岐構造のいずれの分岐節も別の同一のサブルーチン呼出を含み、インライン展開によるプログラム解析に必要な計算量と記憶領域量を増大させるプログラムを生成する。
【００２０】
請求項４の発明は、任意の命令文を実行するダミーのサブルーチンを含み、インライン展開によるプログラム解析に必要な計算量と記憶領域量を増大させるプログラムを生成する。
【００２１】
請求項５の発明は、可逆関数に基づいて変数を可逆的に操作するプログラム片を含み、インライン展開によるプログラム解析に必要な計算量と記憶領域量を増大させるプログラムを生成する。
【００２２】
請求項６の発明は、常に偽となる条件式を含み、インライン展開によるプログラム解析に必要な計算量と記憶領域量を増大させるプログラムを生成する。
【００２３】
請求項７の発明は、インライン展開によるプログラム解析に必要な計算量と記憶領域量を増大させるプログラムを生成する。
【発明を実施するための最良の形態】
【００２４】
以下、本発明の最良の実施形態について図面を参照して説明する。
【実施例】
【００２５】
図１は、本発明の実施例に用いられるプログラム難読化装置の構成を示すブロック図である。プログラム難読化装置１０は、入出力装置１４、演算装置１１、ＲＡＭ１２、外部記憶装置１３を含む。入出力装置１４は、難読化装置を使用するユーザから指示を受け付けたり、難読化処理の結果を表示したりする。外部記憶装置１３は、難読化対象プログラムや難読化後のプログラムを格納する。ＲＡＭ１２は、難読化処理中のプログラムを一時的に保存する装置である。演算装置１１は、ＲＡＭ上の難読化対象プログラムに難読化を適用する装置である。
【００２６】
次に、本発明の第１の実施例のプログラム難読化方法について、図２ないし図１６を参照して説明する。図２は任意の実行形式のプログラムを難読化する演算装置１１の機能を示したブロック図である。演算装置１１は、１個以上の難読化前のプログラムを入力する入力部２１、入力されたプログラムの難読化処理を行う難読化処理部２２、及び難読化されたプログラムを出力する出力部２３から構成される。
【００２７】
難読化処理部２２は、入力手段２２１と選択手段２２２により、難読化処理に必要な初期条件を決定する。
【００２８】
まず、入力手段２２１について説明する。
難読化処理部２２は、難読化の度合いを示す難読化指数ｎを入力する入力手段２２１を有する。難読化指数ｎは、予め定められていてもよいし、難読化指数ｎの指定に基づき定めてもよい。また、難読化指数ｎの指定は、演算装置１１がランダムに指定するようにしてもよいし、入出力装置１４を介してユーザが指定するようにしても良い。
【００２９】
次に、選択手段２２２について説明する。
難読化指数ｎが決定すると、難読化処理部２２は、1個以上の難読化前プログラムから、難読化を行うプログラム（以下、難読化対象プログラムという）を選択する。難読化対象プログラムは、予め定められていてもよいし、難読化対象プログラムの指定に基づき定めてもよい。また、難読化対象プログラムの指定は、演算装置１１がランダムに指定してもよいし、入出力装置１４を介してユーザが指定しても良い。
【００３０】
次に、難読化処理部２２は、選択された難読化対象プログラムに含まれるルーチンを選択する。ルーチンは、選択された難読化対象プログラムに含まれる全てのルーチンを選択しても良いし、特定の（１個以上の）ルーチンのみを選択しても良い。選択するルーチンは、予め定められていてもよいし、ルーチンの指定に基づき定めてもよい。また、ルーチンの指定は、演算装置１１がランダムに指定してもよいし、入出力装置１４を介してユーザが指定しても良い。
【００３１】
次に、難読化処理部２２は、選択したルーチンに含まれる１以上の連続する命令文をプログラム片として選択する。選択するプログラム片は、予め定められていてもよいし、プログラム片の指定により選択しても良い。また、プログラム片の指定は、演算装置１１がランダムに指定しても良いし、入出力装置１４を介してユーザが指定しても良い。
【００３２】
難読化処理部２２は、入力手段２２１と選択手段２２２により決定された初期条件と難読化処理規則に従い、追加手段２２３によって難読化対象のプログラムにサブルーチンを追加する。
そして、難読化処理部２２は変換手段２２４によって、選択手段２２２で選択したプログラム片を、追加手段２２４により追加したサブルーチンの呼出しに変換する。
難読化処理部２２は、追加手段２２３と変換手段２２４により、難読化対象プログラムの難読化を終了する。
【００３３】
出力部２３は、難読化処理部２２により難読化の処理が終了したプログラムを受け取る。そのプログラムが難読化装置の全体としての出力となる。難読化されたプログラムは例えば外部記憶装置１３に記憶される。
【００３４】
次に、難読化処理手順について説明する。  
まず、本発明の第１の実施例に係るプログラム難読化装置の操作画面と操作例について、図３を用いて説明する。
【００３５】
図３は、難読化処理装置の操作画面の１例を示したものである。
操作画面３０は、入力部２１に入力された1個以上の難読化前のプログラムを、ソースファイルリスト３１に表示する。
ユーザは、そのソースファイルリスト３１の中から、難読化したいプログラムを選択する。 難読化したいプログラムの選択を行うと、ルーチンリスト３２に、選択したプログラムに含まれるルーチンが表示される。
【００３６】
ユーザが、ルーチンリスト３２から難読化を行うルーチンを選択すると、難読化前ルーチン欄３３に選択したルーチンのソースコードが表示される。
図３では、ｍａｉｎというルーチンのソースコードが表示されている。 以上の操作により、ユーザは、難読化したいプログラムと、難読化対象のルーチンを選択する。
【００３７】
次に、ユーザは、難読化の度合いを決定する難読化指数ｎを指定するため、パラメタ入力３４に、２以上の整数を入力する。 図３では、例として１５が入力されている。この難読化指数ｎにより、難読化処理部２２の追加手段によって、追加されるサブルーチンの個数が決定される。
【００３８】
ユーザは、変換手段によってサブルーチンに変換されるプログラム片を指定するため、難読化前ルーチン欄３３に表示されたサブルーチンに含まれるプログラム片を、マウスカーソル３５で選択する。 図３では、ａ＋＝ｂの演算命令が、プログラム片として選択されている。 
【００３９】
上記処理にて、難読化処理に必要な初期条件の設定が終了したので、ユーザは難読化実行ボタン３６を押す。 すると、難読化処理が実行され、難読化適用後のプログラムが難読化適用後ルーチン欄３７に表示される。 ユーザは、難読化結果を確認した上で難読化後プログラムの保存ボタン３８を押し、難読化後のプログラムを保存することができる。
難読化処理を終了するには、ユーザは終了ボタン３９を押せばよい。
【００４０】
次に、上記操作による難読化処理を実現するために難読化処理部２２が行う難読化処理手順を、図４を用いて説明する。
図４は、難読化処理部２２が、１の難読化処理規則に従って行う難読化処理のフローチャートである。
【００４１】
まず、ユーザまたは演算装置１１は、難読化の度合いを決定する難読化指数ｎ（ｎは２以上）を指定する（ステップＳ６１）。本ステップは、図３に示した操作画面の例では、パラメタ入力３４に２以上の整数を入力することに対応する。
【００４２】
次に、ユーザまたは演算装置１１は、複数ある難読化対象のプログラムの中から、難読化を行うプログラムＰ、プログラムＰに含まれるルーチンＲ及びルーチンＲ中のプログラム片Ｂを選択する（ステップＳ６２）。本ステップは、図３に示した操作画面の例では、プログラムＰの選択は、ソースファイルリスト３１から難読化を行うプログラムを選択することに対応する。また、ルーチンＲの選択は、ルーチンリスト３２からルーチンＲを選択することに対応し、プログラム片Ｂの選択は、難読化前ルーチン欄３３から、マウスカーソル３５で「ａ＋＝ｂ」を選択することに対応する。
【００４３】
プログラム難読化装置１０は、ルーチンＲに含まれるプログラム片Ｂの実行時動作を変えることなく、難読化が終了したプログラムＰをユーザに提供するように、難読化処理を行う。
【００４４】
本実施例では、任意のプログラムＰに含まれる図５のメインルーチンｍａｉｎをルーチンＲとして選択し、ｍａｉｎに含まれる「ａ＋＝ｂ」の演算命令をプログラム片Ｂとして選択した場合の難読化処理について説明する。
【００４５】
難読化処理部２２は、プログラムＰに、前処理（ステップＳ６２）で選択されたプログラム片Ｂのソースコードを含むサブルーチンｓｕｂＢ（図６）と、任意のソースコードを含むダミーのサブルーチンｓｕｂＤｍｍｙ（図７）を追加する（ステップＳ６３）。従って、ｓｕｂＢを呼出すと、選択されたプログラム片Ｂが実行されることになる。
【００４６】
次に、難読化処理部２２は、プログラムＰに、第１サブルーチンｓｕｂ_１をプログラムＰに追加する（ステップＳ６４）。ただし、ｓｕｂ_１は、任意の常に偽となる条件式（以下、恒偽の条件式と略記する）を条件判定とし、かつ、真の条件節からｓｕｂＤｍｍｙを呼出し、偽の条件節からｓｕｂＢを呼出す条件分岐から構成されるとする（図８）。ここで、図８中の「ｋ＊（ｋ−１）％２！＝０」は、常に偽となる条件式である。
本処理によって追加されたｓｕｂ_１を呼出すと、ｓｕｂＢが必ず呼出され、その結果、選択されたプログラム片Ｂが実行されることになる。
【００４７】
難読化処理部２２は、ｉ＝２、・・・、ｎに関して、ｉに対応するサブルーチンｓｕｂ_ｉ（ｉ＝２、・・・、ｎ）をプログラムＰに追加する（ステップＳ６５）。
ただし、ｓｕｂ_ｉは、任意の恒偽の条件式を条件判定とし、かつ、真の条件節はｓｕｂ_ｉ−１の呼出しと、任意に作成した1以上の連続する命令文Ｄｍｍｙ_ｉから成り、偽の条件節はｓｕｂ_ｉ−１の呼出しからなる条件分岐、から構成されるとする（図９）。
【００４８】
本処理の結果、１処理前に追加されたサブルーチンの呼出しを行うサブルーチンが追加されることになる。つまり、ｓｕｂ_２は、前処理で追加されたｓｕｂ_１の呼出しを行い、ｓｕｂ_３はｓｕｂ_２の呼出しを行うことになる。
【００４９】
難読化処理部２２は、プログラム片Ｂを、前処理（ステップＳ６５）の最後に追加されたサブルーチンｓｕｂ_ｎの呼出しに変換する（ステップＳ６６）。
これにより、本実施例では、ユーザがメインルーチンを実行すると、ｓｕｂ_ｎの実行により、ｓｕｂ_ｎ−１が呼出され、ｓｕｂ_ｎ−１によってｓｕｂ_ｎ-２が呼出されることになる。
そして、ｎ回のサブルーチン呼出しを経た後に、サブルーチンｓｕｂＢが呼出され、選択されたプログラム片Ｂが実行されることとなる。
【００５０】
上述の処理により、プログラムＰの難読化が完了する。そこで、難読化処理部２２は、難読化適用済みプログラムＰを出力部２３へ出力する（ステップＳ６７）。
【００５１】
本実施例によれば、図５の難読化前のルーチンｍａｉｎを含むプログラムＰは、図１０のように難読化される。
【００５２】
本実施例によって得られた難読化後のプログラムは、インライン展開に必要な記憶領域及び処理量を増大させるものである。
そこで、難読化後のプログラム図１０に対して、インライン展開を行った場合のプログラムの変化を模式的に示した図１１を用いて、その難読化の効果を説明する。
図１１では、丸はサブルーチンを、丸から丸への矢印はサブルーチンの呼出しを表している。丸１から丸２にｋ本の矢印がある場合、丸１に対応する関数の中に、丸２に対応するサブルーチン呼出しがｋ箇所ある事を示す。
【００５３】
難読化後プログラム４１は、難読化後のプログラム図１０を模式的に表したものである。難読化後プログラム４１のｓｕｂ_ｎをインライン展開すると、第１インライン展開４２のようになる。第１インライン展開４２は、ｍａｉｎの中にｓｕｂ_ｎの中身が１つ展開されたことを模式的に表している。
【００５４】
第１インライン展開４２のｓｕｂ_ｎ−１をさらにインライン展開すると、第２インライン展開４３のようになる。ｍａｉｎの中にｓｕｂ_ｎ−１の呼出が２箇所あったので、第２インライン展開４３では、ｍａｉｎにｓｕｂ_ｎ−１の中身が２つ展開されている。第２インライン展開４３のｓｕｂ_ｎ−２をさらにインライン展開すると、第３インライン展開４４のようになる。
【００５５】
ｍａｉｎの中にｓｕｂ_ｎ−２の呼出が４箇所あったので、第３インライン展開４４では、ｍａｉｎにｓｕｂ_ｎ−２の中身が４つ展開される。
以上に示したように、難読化後のプログラムにインライン展開を順次行っていくと、サブルーチンの展開数はｎに関して指数関数的になる。そのため、難読化後のプログラムにインライン展開を適用すると、ルーチンｍａｉｎのサイズがｎに関して指数関数的に大きくなる。従って、ｎがある程度大きくなる（例えば、ｎ＝５０）と、インライン展開は現実的に実行不可能となる。
【００５６】
次に、図１２を用いて、難読化処理部２２が、上述の難読化処理規則とは別の難読化処理規則に従って行う難読化処理について説明する。
【００５７】
まず、ユーザまたは演算装置１１は、難読化を行うプログラムＰと、難読化の度合いを決定する整数ｎ（ｎは２以上）を指定する（ステップＳ１３１）。本ステップは、図３に示した操作画面の例では、パラメタ入力３４に２以上の整数を入力することに対応する。
【００５８】
次に、ユーザまたは演算装置１１は、複数ある難読化プログラムの中から、難読化を行うプログラムＰ、プログラムＰに含まれるルーチンＲ及びルーチンＲ中のプログラム片Ｂを選択する（ステップＳ１３２）。本ステップは、図３に示した操作画面の例では、プログラムＰの選択は、ソースファイルリスト３１から難読化を行うプログラムを選択することに対応する。また、ルーチンＲの選択は、ルーチンリスト３２からルーチンＲを選択することに対応し、プログラム片Ｂの選択は、難読化前ルーチン欄３３から、マウスカーソル３５で「ａ＋＝ｂ」を選択することに対応する。
【００５９】
プログラム難読化装置１０は、ルーチンＲに含まれるプログラム片Ｂの実行時動作を変えることなく、難読化が終了したプログラムＰをユーザに提供するように、難読化処理を行う。
【００６０】
本実施例では、任意のプログラムＰに含まれる図５のメインルーチンｍａｉｎをルーチンＲとして選択し、ｍａｉｎに含まれる「ａ＋＝ｂ」の演算命令をプログラム片Ｂとして選択した場合の難読化処理について説明する。
【００６１】
難読化処理部２２は、プログラムＰに、前処理（ステップＳ１３２）で選択されたプログラム片Ｂのソースコードを含むサブルーチンｓｕｂＢ（図６）と、任意のソースコードを含むダミーのサブルーチン（図７）を追加する（ステップＳ１３３）。従って、ｓｕｂＢを呼出すと、選択されたプログラム片Ｂが実行されることになる。
【００６２】
次に、難読化処理部２２は、難読化対象のプログラムに、第１サブルーチンｓｕｂ_１をプログラムＰに追加する（ステップＳ１３４）。ただし、ｓｕｂ_１は、任意の恒偽の条件式を条件判定とし、かつ、真の条件節からｓｕｂＤｍｍｙを呼出し、偽の条件節からｓｕｂＢを呼出す条件分岐から構成されるとする（図８）。ここで、図８中の「ｋ＊ｋ−１％２！＝０」は、常に偽となる条件式である。
本処理によって追加されたｓｕｂ_１を呼出すと、ｓｕｂＢが必ず呼出され、その結果、選択されたプログラム片Ｂが実行されることになる。
【００６３】
次に、ユーザまたは演算装置１１は、プログラムＰから任意の整数変数ｘを選択し、難読化処理部２２は選択された整数ｘを入出力とする可逆関数ｇを生成する（ステップＳ１３５）。本実施例では、可逆関数ｇとしてｇ（ｘ）＝２＊ｘ＋３を生成したとする。
可逆関数ｇは、後述する処理で追加されるサブルーチン内で利用される。
【００６４】
難読化処理部２２は、ｉ＝２、・・・、２ｎ＋１に関して、ｉに対応するサブルーチンｓｕｂ_ｉ（ｉ＝２、・・・、２ｎ＋１）をプログラムＰに追加する（ステップＳ１３６）。ただし、ｉ＝３，５、・・・、２ｎ＋１に関して、ｓｕｂ_ｉは、任意の条件式を条件判定とし、かつ、真／偽の条件節ともにｘ＝ｇ（ｘ）と同一の結果を返すプログラム片とｓｕｂ_ｉ−１との呼出しから成る（図１３）。
また、ｉ＝２、４、・・・、２ｎに関して、ｓｕｂ_ｉは、任意の条件式を条件判定とし、かつ、真／偽の条件節とともにｘ＝ｇ〜（ｘ）と同じ結果を返すプログラム片と、ｓｕｂ_ｉ−１との呼出しから成る（図１４）。ここで、ｇ〜とは、ｇの逆関数である。つまり、ｇ〜（ｘ）＝（ｘ−３）／２である。
【００６５】
難読化処理部２２は、プログラム片Ｂを、前処理（ステップＳ１３６）の最後に追加されたサブルーチンｓｕｂ_２ｎ＋１の呼出しに変換する（ステップＳ１３７）。
これにより、本実施例では、ユーザがメインルーチンを実行すると、ｓｕｂ_２ｎ＋１の実行により、ｓｕｂ_２ｎが呼出され、ｓｕｂ_２ｎによって、ｓｕｂ_２（ｎ−１）＋１が呼出されることになる。
そして、２ｎ＋１回のサブルーチン呼出しを経た後に、サブルーチンｓｕｂＢが呼出され、選択されたプログラム片Ｂが実行されることとなる。
【００６６】
上述した処理により、プログラムＰの難読化処理は終了するため、難読化処理部２２は、難読化適用済みプログラムＰを出力部２３へ出力する（ステップＳ１３８）
【００６７】
本実施例によれば、図５の難読化前のルーチンｍａｉｎを含むプログラムＰは、図１５のように難読化される。
【００６８】
本実施例によって得られた難読化後のプログラムは、インライン展開に必要な記憶領域及び処理量を増大させるものである。
そこで、難読化後のプログラム図１５に対して、インライン展開を行った場合のプログラムの変化を模式的に示した図１６を用いて、その難読化の効果を説明する。
図１６では、丸はサブルーチンを、丸から丸への矢印はサブルーチンの呼出しを表している。丸１から丸２にｋ本の矢印がある場合、丸１に対応する関数の中に、丸２に対応するサブルーチン呼出しがｋ箇所ある事を示す。
【００６９】
難読化後プログラム５１は、難読化後のプログラム図１５を模式的に表したものである。難読化後プログラム５１のｓｕｂ_２ｎ＋１をインライン展開すると、第１インライン展開５２のようになる。第１インライン展開４２は、ｍａｉｎの中にｓｕｂ_２ｎ＋１の中身が１つ展開されたことを模式的に表している。
【００７０】
第１インライン展開５２のｓｕｂ_２ｎ＋１をさらにインライン展開すると、第２インライン展開５３のようになる。ｍａｉｎの中にｓｕｂ_２ｎの呼出が２箇所あったので、第２インライン展開５３では、ｍａｉｎにｓｕｂ_２ｎの中身が２つ展開されている。第２インライン展開５３のｓｕｂ_２ｎをさらにインライン展開すると、第３インライン展開４４のようになる。
【００７１】
ｍａｉｎの中にｓｕｂ_２（ｎ−１）＋１の呼出が４箇所あったので、第３インライン展開４４では、ｍａｉｎにｓｕｂ_２（ｎ−１）＋１の中身が４つ展開される。
以上に示したように、難読化後のプログラムにインライン展開を順次行っていくと、サブルーチンの展開数はｎに関して指数関数的になる。そのため、難読化後のプログラムにインライン展開を適用すると、ルーチンｍａｉｎのサイズがｎに関して指数関数的に大きくなる。従って、ｎがある程度大きくなる（例えば、ｎ＝５０）と、インライン展開は現実的に実行不可能となる。
【００７２】
以上、本発明の好ましい実施の形態について詳述したが、本発明に係る特定の実施形態に限定されるものではなく、特許請求の範囲に記載された本発明の要旨の範囲内において、種々の変形・変更が可能である。
【図面の簡単な説明】
【００７３】
【図１】プログラム難読化装置の構成の一例を示すブロック図である。
【図２】演算装置の機能ブロック図の一例である。
【図３】難読化処理装置の操作画面の例である。
【図４】難読化処理の一例を示すフローチャートである。
【図５】難読化前のルーチン例である。
【図６】プログラム片を含むサブルーチン例である。
【図７】ダミーのサブルーチン例である。
【図８】第１サブルーチンの例である。
【図９】番号ｉに対応するサブルーチンｉの例である。
【図１０】難読化後のプログラム例である。
【図１１】インライン展開の模式図である。
【図１２】難読化処理の一例を示すフローチャートである。
【図１３】ｉが偶数の場合の、番号ｉに対応するサブルーチンｉの例である。
【図１４】ｉが奇数の場合の、番号ｉに対応するサブルーチンｉの例である。
【図１５】難読化後のプログラム例である。
【図１６】インライン展開の模式図である。
【符号の説明】
【００７４】
１０…プログラム難読化装置
１１…演算装置
１２…ＲＡＭ
１３…外部記憶装置
１４…入出力装置
２１…入力部
２２…難読化処理部
２３…出力部
３０…操作画面
３１…ソースファイルリスト
３２…ルーチンリスト
３３…難読化前ルーチン欄
３４…パラメタ入力欄
３５…難読化実行ボタン
３７…難読化後ルーチン欄
３８…難読化後プログラムの保存
３９…終了ボタン
４１…難読化後プログラム
４２…第１インライン展開
４３…第２インライン展開
４４…第３インライン展開
５１…難読化後プログラム
５２…第１インライン展開
５３…第２インライン展開
５４…第３インライン展開
２２１…入力手段
２２２…選択手段
２２３…追加手段
２２４…変換手段
【図１】
2010072958.tif 000003
【図２】
2010072958.tif 000004
【図３】
2010072958.tif 000005
【図４】
2010072958.tif 000006
【図５】
2010072958.tif 000007
【図６】
2010072958.tif 000008
【図７】
2010072958.tif 000009
【図８】
2010072958.tif 000010
【図９】
2010072958.tif 000011
【図１０】
2010072958.tif 000012
【図１１】
2010072958.tif 000013
【図１２】
2010072958.tif 000014
【図１３】
2010072958.tif 000015
【図１４】
2010072958.tif 000016
【図１５】
2010072958.tif 000017
【図１６】
2010072958.tif 000018