以下、本発明に係る命令生成装置および命令生成方法について図面を参照して説明する。なお、以下の各実施の形態および各変形例では、本発明に係る命令生成装置を改竄防止処理生成装置として説明する。
(実施の形態1)
本発明に関わる実施の形態1における処理システムについて説明する。
図3は、実施の形態1における処理システムの構成を示す図である。
本実施の形態における処理システム100は、改竄防止処理生成装置(命令生成装置)110と、実行処理装置130とを備える。
改竄防止処理生成装置110は、保護対象コードを確実に保護し得るプログラムを生成する装置であって、保護対象コードである第一処理命令群140と第二処理命令群150とを取得して、出力処理命令群160を生成する。なお、改竄防止処理生成装置110は、第二処理命令群150を難読化して出力処理命令群160を生成する難読化装置として構成されている。なお、特に断らない限り、本明細書および本発明における命令群とは、複数の命令が含まれるものに限らず、命令が1つだけのものも含むものとする。
また、改竄防止処理生成装置110は、その生成された出力処理命令群160と第一処理命令群140とを記録媒体120に書き込む。
実行処理装置130は、記録媒体120に記録されている第一処理命令群140および出力処理命令群160を読み出して実行する。
なお、改竄防止処理生成装置110は、第一処理命令群140および出力処理命令群160を記録媒体120に書き込むことなく、通信媒体を介して実行処理装置130に送信してもよい。
以下、それぞれの構成要素について説明を行う。
第一処理命令群140は、実行処理装置130で実行される処理命令群であって、出力処理命令群160の処理の一部として実行される場合もあれば、それとは別に実行される場合もある。
第二処理命令群150は、実行処理装置130に所定の処理を指示する命令を含んだ処理命令群である。
以下、本実施の形態では、第一処理命令群140は、コンテンツの暗号化された再生可能回数を入力とし、これを復号し、平文の再生可能回数を出力する処理を指示する命令群であるものとして説明を行う。また、本実施の形態では、第二処理命令群150は圧縮されたコンテンツを入力とし、これを解凍し、出力する処理を指示する命令群であるものとして説明を行う。
出力処理命令群160は、第二処理命令群150を難読化した命令群であり、処理の途中で第一処理命令群140を呼び出して使用する構成となっている。すなわち、実行処理装置130で出力処理命令群160が実行される場合、最初は出力処理命令群160に含まれる命令群が実行され、途中で第一処理命令群140が呼び出されて実行され、次にまた出力処理命令群160の続きの処理命令群が実行される。
以下、出力処理命令群160の詳細を説明する。
(1)出力処理命令群160の構成
図4は、出力処理命令群160の構成を示す図である。
出力処理命令群160は、第一処理命令群140を呼び出して実行する際に必要となる各種パラメータに値を設定する被参照変数値代入処理命令群310と、第一処理命令群140を呼び出す分岐処理命令群320と、第一処理命令群140を呼び出した後に実行される依存処理命令群330とからなる。実行処理装置130で出力処理命令群160が実行される場合、被参照変数値代入処理命令群310、分岐処理命令群320、第一処理命令群140、依存処理命令群330の順に各処理命令群が実行される。
以下、それぞれを説明する。
(1.1)被参照変数値代入処理命令群310
被参照変数値代入処理命令群310は、第一処理命令群140を呼び出して実行する際に必要となる各種パラメータに値を設定する処理である。具体的には、例えば、第一処理命令群140が関数である場合には、被参照変数値代入処理命令群310は、関数の引数に値を代入する命令群である。また、例えば、第一処理命令群140が外部変数を参照する命令群であれば、被参照変数値代入処理命令群310は、外部変数に値を代入する命令群である。また、例えば、第一処理命令群140がスタックの値を参照する命令群であれば、被参照変数値代入処理命令群310は、スタックに値を格納する命令群である。また、例えば、第一処理命令群140がアドレス変数で指定した位置に格納された値を参照する命令群であれば、被参照変数値代入処理命令群310は、その参照されるアドレス変数に値を格納する命令群である。
これらの第一処理命令群140を実行する際に必要となる各種パラメータのことを以降の説明では総称して、被参照変数と呼ぶものとする。
(1.2)分岐処理命令群320
分岐処理命令群320は第一処理命令群140に分岐する処理命令群である。具体的には、例えば、第一処理命令群140が関数であるならば、分岐処理命令群320は関数コール命令であり、第一処理命令群140がサブルーチンであるならば、分岐処理命令群320はサブルーチンコール命令である。また、第一処理命令群140が処理命令群の集まりであるならば、分岐処理命令群320は分岐命令であり、第一処理命令群140が例外処理ならば、分岐処理命令群320は例外を発生させる処理命令である。より具体的には、分岐処理命令群320は、例えばアセンブリ言語の命令では、「CALL、RET」のような関数コールや「JA、JMP、LOOP」などのジャンプ命令、「INT」などの割り込み命令である。
(1.3)依存処理命令群330
依存処理命令群330は、第一処理命令群140を呼び出した後に実行される処理命令群であり、第二処理命令群150と同等の処理を行うプログラム命令群である。第二処理命令群150そのものと異なる点は、第二処理命令群150の一部の処理が、第一処理命令群140の処理結果を使用した処理に置き換えられている点である。置き換えの詳細は改竄防止処理生成装置110の説明の際に述べるものとし、ここでは置き換えの概要を説明する。
まず、第一処理命令群140の処理結果とは、具体的には、例えば、第一処理命令群140が関数である場合には、関数の戻り値である。また、例えば、第一処理命令群140が外部変数に値を設定する処理であるならば、第一処理命令群140の処理結果とは、外部変数に代入された値である。また、例えば、第一処理命令群140がスタックに値を格納する処理であれば、第一処理命令群140の処理結果とは、スタックに格納された値である。また、例えば、第一処理命令群140がアドレス変数で指定した位置に値を格納する処理であれば、第一処理命令群140の処理結果とは、その格納された値である。これらの第一処理命令群140の処理結果が格納される格納先のことを、以降の説明では被代入変数と呼ぶものとする。
第一処理命令群140の処理結果を予め知ることは一般には出来ないが、第一処理命令群140を実行する際に必要となる各種パラメータの値が被参照変数値代入処理命令群310で設定される時に限っては、処理結果の値を予め知ることができる。具体的には、例えば、被参照変数値代入処理命令群310が設定する値を実際に被参照変数に設定した上で、第一処理命令群140を実行すれば、処理結果の値を知ることができる。以降の説明では、この値を想定値と呼ぶものとする。
依存処理命令群330は、被代入変数の値が想定値である場合には、前記第二処理命令群と同じ処理を行う命令群である。また、望ましくは、被代入変数の値が想定値でない場合には、前記第二処理命令群とは異なる処理をする命令群であるとよい。具体的には、例えば、第二処理命令群が「a=a*5;」で、被代入変数「b」の想定値が「5」である場合に、第二処理命令群を「a=a*b;」に置き換えたものが依存処理命令群となる。
(1.4)処理命令群の具体例
図5Aは、C言語で記述された第一処理命令群140の具体例を示す図である。また、図5Bは、C言語で記述された第二処理命令群150の具体例を示す図である。また、図5Cは、C言語で記述された出力処理命令群160の具体例を示す図である。なお、以降の説明では、「*」、「〜」、「|」、「^」、「<<」、「>>」等の演算子を用いるが、処理命令群の説明で用いるこれらの演算子は特に断りのない場合、C言語における演算子を示す。また、以下の説明では、各処理命令群には、関数宣言や変数宣言がC言語の言語形式にしたがって追加されているが、この言語形式については公知であるので説明を省略する。
第一処理命令群140は、図5Aに示すように、暗号化されたコンテンツの再生回数「encryptedData」(被参照変数)を入力して復号化することにより、コンテンツの再生回数「plainData」(被代入変数)を出力する処理を含む命令群である。ここでは、簡単のために、暗号化されたコンテンツの再生回数と、秘密情報「0x00FF」との排他論理和を取る処理「plainData=encryptedData^0x00FF」を、復号化の処理としている。なお、「0x00FF」における頭の「0x」は「00FF」が16進数であることを示している。
ここで、「plainData」および「encryptedData」はそれぞれ「0x0000〜0xFFFF」までの値を取る16ビットの値とする。また、plainDataは2進数表記したときに最上位ビットが1である場合は負の値を示すものとする。すなわち「0x8000〜0xFFFF」までの値は負数を示す。
第二処理命令群150は、図5Bに示すように、圧縮されたコンテンツデータ「compressedData」を入力して解凍することにより、コンテンツデータ「decompressedData」を出力する処理を含む命令群である。ここでは、簡単のために、圧縮されたコンテンツデータ「compressedData」の値の数だけ1が連続する2進数を出力する処理を、解凍の処理とする。この処理は、図5Bに示すように、命令群「for(counter=0;counter<compressedData;counter++){(decompressedData=decompressedData<<1)|0x0001;}」として表される。
ここで、「compressedData」は0〜31までの値を取るものとし、「decompressedData」は32ビットの値とする。「decompressedData」は、「compressedData」が「0」の時は、「0x00000000」となり、「compressedData」が「1」の時は、「0x00000001」となり、「compressedData」が「31」の時は、「0xFFFFFFFF」となる。
出力処理命令群160は、図5Cに示すように、第二処理命令群150と同じ解凍処理を行う処理命令群である。この出力処理命令群160は、第二処理命令群150が改竄防止処理生成装置110によって難読化された後の命令群である。改竄防止処理生成装置110の詳細については後述する。
被参照変数値代入処理命令群310である「encryptedData=0xF022;」は、第一処理命令群140を呼び出す際の引数に値を代入する処理であり、被参照変数「encryptedData」に値「0xF022」を代入する処理を示している。
分岐処理命令群320である「plainData=decrypt(encryptedData);」は、引数を被参照変数「encryptedData」として第一処理命令群140を呼び出す処理を示し、第一処理命令群140の処理結果を被代入変数「plainData」に格納する。実行処理装置130において、分岐処理命令群320が正常に実行された場合の戻り値の想定値は、被参照変数「encryptedData」を値「0xF022」として第一処理命令群140の処理を行った際の結果である「0xF022^0x00FF=0xF0DD」となる。
依存処理命令群330は、第二処理命令群150と同等の処理を行う処理を示す。ただし、この処理では、第二処理命令群150とは異なり、第一処理命令群140の処理結果である「plainData」を用いた処理が含まれる。
具体的に、依存処理命令群330は、「for(counter=0;counter<compressedData;counter++){decompressedData=(decompressedData<<1)|(plainData−0xF0DC);}」として表される。
上記の処理において、「plainData」の値が、先述の想定値「0xF0DD」である場合、「(plainData−0xF0DC)」は値「0x001」となる。これは、第二処理命令群150の対応箇所と同一の値であるので、「plainData」が想定値になっていれば、依存処理命令群330は第二処理命令群150と同等の処理を行う。また、「plainData」の値が想定値と異なっていた時には、「(plainData−0xF0DC)」の値は「0x001」とは異なる値となるため、第二処理命令群150と同等の処理が行われなくなる。
(1.5)出力処理命令群160の効果
実施の形態1の出力処理命令群160は、第一処理命令群140を実行する際に必要となる各種パラメータに値を設定する被参照変数値代入処理命令群310と、第一処理命令群140を呼び出す分岐処理命令群320と、第一処理命令群140を呼び出した後に実行される依存処理命令群330とからなる。ここで、改竄防止処理生成装置110による変換が行われていない第二処理命令群150では第一処理命令群140を呼び出さないにも関わらず、変換後の命令群である出力処理命令群160では第一処理命令群140を呼び出すための処理が追加されている。
このような構成を用いれば、実行処理装置130で出力処理命令群160を実行する際に、出力処理命令群160が目的としている処理(上記の実施の形態では解凍処理)には本来不要なはずの第一処理命令群140(上記の実施の形態では復号処理)も実行されることになる。よって、第一処理命令群140は複数の処理に必要な機能であるのか、単数の処理に必要な機能であるかの解析が困難になる。具体的には、上記の例では、第一処理命令群は、復号に必要な処理であり、本来は解凍には不要な処理であった。しかし、出力処理命令群160では、第一処理命令群140は復号と解凍との両方に必要な処理となる。よって、復号のみに必要な処理を解析することで復号処理に含まれる秘密情報を解析しようとする不正解析者の解析作業を困難にすることが出来る。
さらに、実行処理装置130では、出力処理命令群160を実行する際に、第一処理命令群140も実行されることとなる。よって、出力処理命令群160を解析しようとする不正解析者が解析しないといけない処理が、第二処理命令群150と比べて増加する。従来からも、元々の処理に他の処理を追加して、不正解析者が解析しなければならない処理を増加させる難読化は行われていたが、その際には追加する処理のプログラムサイズが増大するという問題があった。しかし、出力処理命令群160は、実行処理装置130において他の用途で使用される第一処理命令群140を呼び出すための命令群を追加しているのみであるので、プログラムサイズをほとんど増大させずに、不正解析者が解析しなければならない処理を増大させることができる。
なお、発明の本質ではないので特に詳細に説明していないが、実施の形態1の復号処理を行う第一処理命令群140は、解凍処理を行う第二処理命令群150以外の命令群からも呼ばれる処理である(むしろ、本来は第二処理命令群150以外から呼ばれるべき処理である)ことは言うまでもない。ここで、第一処理命令群140を本来呼び出すべき命令群は、第一処理命令群140と同一のプログラムに含まれる命令群であってもよいし、第一処理命令群140がライブラリ等である場合は、異なるプログラムから呼び出されてもよい。また、第一処理命令群140と第二処理命令群150が同一のプログラムに含まれていてもよいし、上述のように第一処理命令群140がライブラリ等である場合は異なるプログラムに含まれていてもよい。ここで、同一のプログラムに含まれる場合、上述したようにプログラムサイズを増大させないためには、そのプログラムは第一処理命令群140を用いて何らかの処理を行うプログラムであることが望ましい。
また、第一処理命令群140と第二処理命令群150とが同一のプログラムに含まれる場合は、そのプログラムを入力として与えることで、両方の処理命令群を入力することができる。さらにこの場合、プログラム中の第二処理命令群150を出力処理命令群160に置き換えて出力するプログラム出力手段等をさらに設けることで、入力されたプログラムを上述した特徴を有したプログラムへと難読化することができる。
さらに、出力処理命令群160の依存処理命令群330は、第一処理命令群140の処理結果に依存する処理を行う命令群となっている。よって、不正解析者が、第一処理命令群140を不正改竄した場合、出力処理命令群160の処理が本来の結果と異なる結果となる。具体的には、例えば、不正解析者が図5Aのコンテンツの再生可能回数を出力する第一処理命令群140を、「int decrypt( int encryptedData){return 100;}」に改竄した場合、依存処理命令群330における「plainData」の値は100となり、「0xF0DD」とは異なる値になる。よって、出力処理命令群160が実行されても、本来の解凍処理とは異なる値が出力されることとなる。よって、第一処理命令群140を改竄した不正解析者は、さらに出力処理命令群160をも不正改竄しなければ、コンテンツを正しく実行することが出来なくなる。このように、第一処理命令群140と第二処理命令群150がコンテンツの再生等の大きな機能の構成要素である場合に、その一部の構成要素が改竄されると、他の一部の構成要素の挙動がおかしくなる。よって、不正解析者が望む通りに機能を改竄することが困難になる。
(2)改竄防止処理生成装置110の構成
続いて、改竄防止処理生成装置110の説明を行う。改竄防止処理生成装置110は、第二処理命令群150を上記の出力処理命令群160に変換する装置である。
図6は、改竄防止処理生成装置110の構成を示す図である。
改竄防止処理生成装置110は、入力処理命令群保持部210、被参照変数解析部220、被参照変数情報保持部230、被参照変数値代入処理命令群生成部240、被参照変数値代入処理命令群保持部250、被参照変数値保持部260、被代入変数解析部270、被代入変数情報保持部280、想定値情報保持部295、想定値算出部290、依存処理命令群生成部201、依存処理命令群保持部202、分岐処理命令群生成部203、分岐処理命令群保持部204、出力処理命令群生成部205、および出力処理命令群保持部206を備えている。
入力処理命令群保持部210は、第一処理命令群140と第二処理命令群150を取得し、取得された各命令群を保持する。
被参照変数解析部220は、第一処理命令群140を実行する際に値を設定しておく必要のある引数等の変数(被参照変数)が何であるかを解析する。
被参照変数情報保持部230は、被参照変数解析部220による解析によって得られた被参照変数の変数名等の情報を保持する。
被参照変数値代入処理命令群生成部240は、被参照変数に値を代入する被参照変数値代入処理命令群310を生成する。
被参照変数値代入処理命令群保持部250は、被参照変数値代入処理命令群生成部240が生成した被参照変数値代入処理命令群310を保持する。
被参照変数値保持部260は、被参照変数値代入処理命令群310が被参照変数に代入する値を保持する。
被代入変数解析部270は、第一処理命令群140の処理結果が代入される変数(被代入変数)が何であるかを解析する。
被代入変数情報保持部280は、被代入変数解析部270による解析によって得られた被代入変数の変数名等の情報を保持する。
想定値算出部290は、被参照変数の値を被参照変数値保持部260が保持する値とし、第一処理命令群140を実行した際に得られる被代入変数の想定値を算出する。
想定値情報保持部295は、想定値算出部290が算出した想定値を保持する。
依存処理命令群生成部201は、第二処理命令群150と想定値に基づき依存処理命令群330を生成する。
依存処理命令群保持部202は、依存処理命令群生成部201が生成した依存処理命令群330を保持する。
分岐処理命令群生成部203は、入力処理命令群保持部210が保持する第一処理命令群140を呼び出す分岐処理命令群320を生成する。
分岐処理命令群保持部204は、分岐処理命令群生成部203が生成した分岐処理命令群320を保持する。
出力処理命令群生成部205は、被参照変数値代入処理命令群保持部250が保持する被参照変数値代入処理命令群310と、分岐処理命令群保持部204が保持する分岐処理命令群320と、依存処理命令群保持部202が保持する依存処理命令群330とからなる出力処理命令群160を生成する。
出力処理命令群保持部206は、出力処理命令群が生成した出力処理命令群160を保持する。
以下、上述の各構成要素について詳細に説明する。なお、以下の説明においては各構成要素の機能説明に加え、図5Aの第一処理命令群140が入力された場合の具体的な動作例も説明する。
(2.1)入力処理命令群保持部210
入力処理命令群保持部210は、外部から第一処理命令群140と第二処理命令群150の入力を受け付ける。つまり、入力処理命令群保持部210は、第一処理命令群140と第二処理命令群150とを取得する。また、入力処理命令群保持部210は、1以上の処理命令群を記憶する領域を備えている。入力処理命令群保持部210は、改竄防止処理生成装置110に入力された第一処理命令群140と第二処理命令群150を保持する。なお、入力を受け付ける部位と入力された命令群を保持する部位とを別々に構成してもよいことは言うまでもない。
(2.2)被参照変数解析部220
被参照変数解析部220は、入力処理命令群保持部210が保持する第一処理命令群140を実行する際に必要となるパラメータを解析(特定)し、解析(特定)した情報を被参照変数情報保持部230に格納する。
具体的には、例えば、第一処理命令群140が関数であれば、被参照変数解析部220は、その関数の引数の型や名前、個数を特定する。また、例えば、第一処理命令群140が外部変数を参照する処理を含む命令群であれば、被参照変数解析部220は、その外部変数の変数名や型を特定する。また、例えば、第一処理命令群140がスタックの値を参照する処理を含む命令群であれば、被参照変数解析部220は、参照されるスタックのサイズを特定する。また、例えば、第一処理命令群140がアドレス変数で指定した位置に格納された値を参照する処理を含む命令群であれば、被参照変数解析部220は、そのアドレス変数や格納する値の型を特定する。以下の説明では、このように特定された情報(解析された情報)、すなわち、第一処理命令群140を実行する際に必要なパラメータに関する情報を総称して、被参照変数情報と呼ぶ。
具体的な例としては、被参照変数解析部220は、図5Aの第一処理命令群140が入力された場合、関数の引数名とその引数の型「int encryptedData」を特定(解析)し、これを被参照変数情報保持部230に格納する。ここでは、引数名は「encryptedData」であり、型は「int」である。
(2.3)被参照変数情報保持部230
被参照変数情報保持部230は、被参照変数情報を記憶する領域を備えている。
被参照変数情報保持部230は、被参照変数解析部220によって特定された第一処理命令群140の被参照変数情報を記憶する。
具体的には、被参照変数情報保持部230は、被参照変数解析部220が図5Aの第一処理命令群140を解析した場合、関数の引数名と型「int encryptedData」を記憶する。
(2.4)被参照変数値代入処理命令群生成部240
被参照変数値代入処理命令群生成部240は、第一処理命令群140を実行する際に必要なパラメータに値を設定する処理命令群である被参照変数値代入処理命令群310を生成し、生成した処理命令群を被参照変数値代入処理命令群保持部250に書き込む。また、被参照変数値代入処理命令群生成部240は、パラメータに設定する値を被参照変数値保持部260に書き込む。
具体的には、例えば、被参照変数値代入処理命令群生成部240は、被参照変数情報保持部230が保持する変数名を取得する。次に、被参照変数値代入処理命令群生成部240は、取得した取得した変数名が示す変数に代入する値を決定する。そして、被参照変数値代入処理命令群生成部240は、取得した変数名と、決定した値との組を被参照変数値保持部260に書き込む。さらに、被参照変数値代入処理命令群生成部240は、変数に対して、先に決定した値を代入する処理(被参照変数値代入処理命令群310)を生成し、その処理を被参照変数値代入処理命令群保持部250に書き込む。
より具体的には、被参照変数情報保持部230が(2.3)の具体例に示した処理を行っている場合、被参照変数値代入処理命令群生成部240は、被参照変数情報保持部230が保持する被参照変数情報「int encryptedData」を取得する。次に、被参照変数値代入処理命令群生成部240は、「encryptedData」に代入するint型の定数値をランダムに決定する。ここでは、被参照変数値代入処理命令群生成部240は、定数値を「0xF022」と決定するものとする。次に、被参照変数値代入処理命令群生成部240は、決定した変数名と値との組「int encryptedData=0xF022」を被参照変数値保持部260に書き込む。また、被参照変数値代入処理命令群生成部240は、「encryptedData=0xF022」を被参照変数値代入処理命令群310として被参照変数値代入処理命令群保持部250に書き込む。
(2.5)被参照変数値代入処理命令群保持部250
被参照変数値代入処理命令群保持部250は、1以上の処理命令を記憶する領域を備える。被参照変数値代入処理命令群保持部250は、被参照変数値代入処理命令群生成部240が生成した被参照変数値代入処理命令群310を記憶領域に記憶する。被参照変数値代入処理命令群生成部240が生成した処理命令が複数ある場合には、複数の処理命令を記憶する。
具体的には、被参照変数値代入処理命令群生成部240が(2.4)の具体例に示した処理を行っている場合、「encryptedData=0xF022;」を記憶する。
(2.6)被参照変数値保持部260
被参照変数値保持部260は、第一処理命令群140を実行する際に必要なパラメータ(被参照変数)に設定する値を記憶する領域を備える。
具体的には、例えば、被参照変数値保持部260は、変数名と値との組を複数記憶する領域を備え、被参照変数値代入処理命令群生成部240が決定した変数名と、その変数名に対応する変数に代入する値との組を記憶する。
より具体的には、被参照変数値代入処理命令群生成部240が(2.4)の具体例に示した処理を行っている場合、被参照変数値保持部260は、変数「encyrptedData」と値「0xF022」との組を記憶する。
(2.7)被代入変数解析部270
被代入変数解析部270は、入力処理命令群保持部210が保持する第一処理命令群140の処理結果が格納される格納先を解析(特定)する。
具体的には、例えば、第一処理命令群140が関数である場合には、被代入変数解析部270は、その関数の戻り値の変数名や型を特定する。また、例えば、第一処理命令群140が外部変数に値を決定する処理であるならば、被代入変数解析部270は、その外部変数の変数名や型を特定する。また、例えば、第一処理命令群140がスタックに値を格納する処理を含む命令群であれば、被代入変数解析部270は、そのスタックのサイズやスタック上の位置(スタックポインタ)を特定する。また、例えば、第一処理命令群140がアドレス変数で指定した位置に値を格納する処理を含む命令群であれば、被代入変数解析部270は、その格納されるアドレスを特定する。以降の説明では、このように特定された情報、すなわち、第一処理命令群140の処理結果が格納される格納先の情報を総称して、被代入変数情報と呼ぶ。なお、スタック等がOS(Operating System)の機能として実現されている場合、スタックポインタやスタックのサイズはプログラム中には明示的には表れないことがあるが、このような値も被代入変数情報である。
次に、被代入変数解析部270は、解析(特定)した被代入変数情報を被代入変数情報保持部280に格納する。
より具体的には、図5Aの第一処理命令群140を解析の対象とする場合、被代入変数解析部270は、関数の戻り値が格納される変数名と型「int plainData」を特定し、「int plainData」を被代入変数情報保持部280に格納する。
(2.8)被代入変数情報保持部280
被代入変数情報保持部280は、被代入変数解析部270によって特定された第一処理命令群140の被代入変数情報を記憶する。
第一処理命令群140で値が決定される変数(被代入変数)が複数ある場合には、そのうちの1つ以上の変数名等(被代入変数情報)を記憶する。なお、本発明は被代入変数が最低1つ分かれば実現できるので、複数の被代入変数が特定されたとしてもその全てを記憶する必要はない。どの被代入変数についての被代入変数情報を記憶するかは、被代入変数情報保持部280が決定してもよいし、被代入変数解析部270が決定してもよい。また、被代入変数情報を記憶する被代入変数をどれにするかの決定の仕方は特に問わないが、例えば、最初に見つかった被代入変数としたり、見つかった被代入変数からランダムに決定するとしてもよい。
具体的には、図5Aの第一処理命令群140に対して被代入変数解析部270による解析が行われた場合、被代入変数情報保持部280は、関数の戻り値が格納される変数名と型「int plainData」を記憶する。
(2.9)想定値算出部290
想定値算出部290は、被参照変数値保持部260が保持する被参照変数の値を用いて第一処理命令群140を実行した場合に、被代入変数に代入される想定値を算出する。
具体的には、想定値算出部290は、以下のA)〜E)に示す処理を行う。
A)想定値算出部290は、被代入変数情報保持部280から被代入変数情報を読み込む。
B)想定値算出部290は、被参照変数値保持部260から被参照変数名および値を読み込む。
C)想定値算出部290は、被参照変数に、読み込んだ値を代入し、入力処理命令群保持部210が保持する第一処理命令群140を実行する。
D)想定値算出部290は、第一処理命令群140の実行後の被代入変数の値を参照する。
E)想定値算出部290は、被代入変数の変数名と、参照した被代入変数の値との組を想定値情報保持部295に書き込む。
なお、被代入変数情報保持部280が保持する被代入変数情報が複数ある場合には、想定値算出部290は、それぞれの被代入変数情報の変数名とその値との組を想定値情報保持部295に書き込む。
より具体的には、被参照変数値保持部260が(2.6)の具体例に示す処理を行っている場合、想定値算出部290は、以下に示すA)〜E)の処理を行う。
A)想定値算出部290は、被代入変数情報保持部280が保持する被代入変数情報「int plainData」を読み込む。
B)想定値算出部290は、被参照変数値保持部260から「int encryptedData=0xF022」を読み込む。ここで、被参照変数名は「encryptedData」であり、値は「0xF022」である。
C)想定値算出部290は、「decrypt(0xF022);」を実行する。すなわち、「decrypt(encryptedData);」の「encryptedData」に値「0xF022」を代入して計算を行う。
D)想定値算出部290は、「decrypt(0xF022);」を実行した結果得られる被代入変数「plainData」の値を算出する。ここでは、想定値算出部290は、「0xF022^0x00FF=0xF0DD」を算出する。
E)想定値算出部290は、「int plainData=0xF0DD」を想定値情報保持部295に格納する。ここで、被代入変数の変数名は「plainData」であり、値は「0xF0DD」である。
(2.10)想定値情報保持部295
想定値情報保持部295は、想定値情報を記憶する領域を備える。ここで、想定値情報とは想定値を保持すべき変数名やその想定値などの情報である。
具体的には、想定値情報保持部295は、想定値算出部290が算出した想定値とその変数名とを上述の想定値情報として保持する。
より具体的には、想定値算出部290が(2.9)の具体例に示した処理を行っている場合、「int plainData=0xF0DD」を保持する。ここで、想定値は「0xF0DD」であり、変数名は「plainData」である。
(2.11)依存処理命令群生成部201
依存処理命令群生成部201は、想定値情報保持部295が保持する想定値および入力処理命令群保持部210が保持する第二処理命令群150に基づき依存処理命令群330を生成する。
依存処理命令群330は、第二処理命令群150と同等の処理を行う処理命令群であって、第一処理命令群140の処理結果を参照する処理を含み、一部の処理がその参照した値を用いた処理となっている処理命令群である。
依存処理命令群生成部201は、具体的には、例えば、以下に示すA)〜F)の処理を行う。
A)依存処理命令群生成部201は、第二処理命令群150に含まれる処理命令に含まれる定数を見つける。以下、この定数を含む処理命令をOr1、その定数の値をVa1とする。
B)依存処理命令群生成部201は、想定値情報保持部295が保持する想定値情報を読み込む。以下、その想定値を保持すべき変数をVr1、その想定値をVa2とする。
C)依存処理命令群生成部201は、Va3=Va2−Va1を算出する。この時、Va1=Va2−Va3となる。
D)依存処理命令群生成部201は、処理命令Or1に含まれる値Va1を、変数Vr1(値Va2を保持すべき変数)から値Va3を引き算することで算出する処理命令Or2を生成する。すなわち、Or2は「(Vr1−Va3)」となる。
E)依存処理命令群生成部201は、第二処理命令群150の処理命令Or1を処理命令Or2に置き換えた命令群である依存処理命令群330を生成する。
このような置き換えを行えば、変数Vr1の値が想定値Va2であれば、「Vr1−Va3」の値は「Va2−Va3=Va1」となる。すなわち、処理命令Or1に含まれる値Va1に対して上記の置き換えを行ったとしても、処理命令Or2は、Vr1に正しい値が代入される限り、置き換えを行う前と同じ結果をもたらすことが出来る。
具体的には、想定値情報保持部295が(2.10)の処理を行った場合、依存処理命令群生成部201は、以下に示すA)〜E)の処理を行う。
A)依存処理命令群生成部201は、処理命令Or1を「decompressedData=(decompressedData<<1)|0x0001;」とし、値Va1を「0x0001」とする。
B)依存処理命令群生成部201は、想定値情報保持部295から「int plainData=0xF0DD」を読み込む。ここで、依存処理命令群生成部201は、変数Vr1を「plainData」、値Va2を「0xF0DD」とする。
C)依存処理命令群生成部201は、値Va3、すなわち「0xF0DD−0x0001=0xF0DC」を算出する。
D)依存処理命令群生成部201は、処理命令Or2「decompressedData=(decompressedData<<1)|(plainData−0xF0DC);」を生成する。
E)依存処理命令群生成部201は、第二処理命令群150の処理命令Or1を処理命令Or2に置き換えた命令群である依存処理命令群330を生成する。なお、本実施の形態はC言語によるプログラムであるとしているので、上述した処理の他に、依存処理命令群330がC言語プログラムとして適切に動作するよう、関数宣言や変数宣言を追加する必要がある。
以上により、図5Cに図示する依存処理命令群330と同じ命令群が生成される。
なお、ここでは、上述のC)で「Va3=Va2−Va1」の演算を行ったが、他の算出式による演算または処理を行っても構わない。具体的には、排他的論理和や加算などの演算を行ってもよいし、より複雑な変換を行う関数等の演算を行ってもよい。その場合、算出式または処理を変形し、Va2を求める算出式または処理を生成し、それをVa2と置き変えればよい。すなわち、Va1とVa2とを用いた演算または処理を行うことでVa3を算出し、得られたVa3とVa1とからVa2を逆算する演算または処理を行う命令群を生成し、それをVa2と置き換えればよい。
(2.12)依存処理命令群保持部202
依存処理命令群保持部202は、1以上の処理命令を記憶する領域を備える。依存処理命令群保持部202は、依存処理命令群生成部201が生成した依存処理命令群330を記憶領域に記憶する。
具体的には、依存処理命令群生成部201が(2.11)の処理を行った場合、依存処理命令群保持部202は、図5Cに示す依存処理命令群330を記憶する。
(2.13)分岐処理命令群生成部203
分岐処理命令群生成部203は、入力処理命令群保持部210が保持する第一処理命令群140を呼び出す分岐処理命令群320を生成する。
具体的には、例えば、第一処理命令群140が関数であるならば、分岐処理命令群生成部203は、関数コール命令を生成する。また、第一処理命令群140がサブルーチンであるならば、分岐処理命令群生成部203は、サブルーチンコール命令を生成する。また、第一処理命令群140が例外処理ならば、分岐処理命令群生成部203は、例外を発生させる処理命令を生成する。
より具体的には、入力処理命令群保持部210が(2.1)の処理を行った場合、分岐処理命令群生成部203は、関数コール命令である「plainData=decrypt(encryptedData);」を分岐処理命令群320として生成する。
(2.14)分岐処理命令群保持部204
分岐処理命令群保持部204は、1以上の処理命令を記憶する領域を備える。分岐処理命令群保持部204は、分岐処理命令群生成部203が生成した分岐処理命令群320を記憶領域に記憶する。
具体的には、分岐処理命令群生成部203が(2.13)の処理を行った場合、分岐処理命令群保持部204は「plainData=decrypt(encryptedData);」を記憶する。
(2.15)出力処理命令群生成部205
出力処理命令群生成部205は、被参照変数値代入処理命令群保持部250が保持する被参照変数値代入処理命令群310と、分岐処理命令群保持部204が保持する分岐処理命令群320と、依存処理命令群保持部202が保持する依存処理命令群330とからなる出力処理命令群160を生成する。
具体的には、上記の(2.14)までの処理が行われた場合、出力処理命令群生成部205は、図5Cの出力処理命令群160を生成する。
(2.16)出力処理命令群保持部206
出力処理命令群保持部206は、1以上の処理命令群を記憶する領域を備えている。出力処理命令群保持部206は、出力処理命令群生成部205が生成した出力処理命令群160を記憶する。
具体的には、出力処理命令群生成部205が(2.15)の処理を行った場合、出力処理命令群保持部206は、図5Cの出力処理命令群160を記憶する。
(2.17)改竄防止処理生成装置110の動作
改竄防止処理生成装置110の動作について、図7を用いて説明する。
図7は、改竄防止処理生成装置110の動作を示すフローチャートである。
被参照変数解析部220は、入力処理命令群保持部210が保持する第一処理命令群140を実行する際に必要となるパラメータの格納先である被参照変数に関する情報である被参照変数情報を解析(特定)する(ステップS100)。
被参照変数解析部220は、特定(解析)された被参照変数情報を被参照変数情報保持部230に格納する(ステップS102)。
被参照変数値代入処理命令群生成部240は、ステップS100で特定(解析)された被参照変数に格納する値を決定する(ステップS104)。
被参照変数値代入処理命令群生成部240は、ステップS104で決定した、被参照変数に格納する値、および被参照変数名を被参照変数値保持部260に格納する(ステップS106)。
被参照変数値代入処理命令群生成部240は、ステップS104で決定した値を被参照変数に格納する処理命令群である被参照変数値代入処理命令群310を生成する(ステップS108)。
被参照変数値代入処理命令群生成部240は、ステップS108で生成した被参照変数値代入処理命令群310を被参照変数値代入処理命令群保持部250に格納する(ステップS110)。
想定値算出部290は、被参照変数値保持部260が保持する被参照変数の値を用いて第一処理命令群140を実行した場合の被代入変数が取る想定値を算出する(ステップS112)。ここで、被代入変数解析部270は、このステップS112が行われるよりも前に被代入変数の解析を行い、その結果を被代入変数情報保持部280に格納しているものとする。したがって、ステップS112では、想定値算出部290は、被代入変数情報保持部280から被代入変数に関する情報を得て、想定値を算出している。
想定値算出部290は、算出した想定値および、被代入変数名を想定値情報保持部に格納する(ステップS114)。
依存処理命令群生成部201は、想定値情報保持部295が保持する想定値および入力処理命令群保持部210が保持する第二処理命令群150に基づき依存処理命令群330を生成する(ステップS116)。
依存処理命令群生成部201は、生成した依存処理命令群330を依存処理命令群保持部202に格納する(ステップS118)。
分岐処理命令群生成部203は、入力処理命令群保持部210が保持する第一処理命令群140を呼び出す分岐処理命令群320を生成する(ステップS120)。
分岐処理命令群生成部203は、生成した分岐処理命令群320を分岐処理命令群保持部204に格納する(ステップS122)。
出力処理命令群生成部205は、被参照変数値代入処理命令群保持部250が保持する被参照変数値代入処理命令群310と、分岐処理命令群保持部204が保持する分岐処理命令群320と、依存処理命令群保持部202が保持する依存処理命令群330とからなる出力処理命令群160を生成する(ステップS124)。
出力処理命令群生成部205は、生成した出力処理命令群160を出力処理命令群保持部206に格納する(ステップS126)。
(2.18)改竄防止処理生成装置110の効果
改竄防止処理生成装置110は、入力として与えられた第一処理命令群140および第二処理命令群150から(1.5)で述べた効果を有する出力処理命令群160を生成することが出来る。
図8は、改竄防止処理生成装置110の効果を説明するための説明図である。
改竄防止処理生成装置110は、例えば、第一処理命令群140と第二処理命令群150とを含む入力プログラム(オリジナルプログラム)101を取得して、その入力プログラム101を改竄防止プログラム102に変換して出力する。このとき、改竄防止処理生成装置110は、上述のように、入力プログラム101の第二処理命令群150を出力処理命令群160に変換している。
つまり、改竄防止処理生成装置110は、第二処理命令群150に対して、保護対象コードである第一処理命令群140の呼出処理を追加するとともに、第二処理命令群150の解凍処理を、保護対象コードである第一処理命令群140の処理結果に依存させること(依存処理)により、改竄防止処理を生成している。
保護対象コード(第一処理命令群140)の呼出処理では、被参照変数値代入処理命令群310において、保護対象コードの被参照変数「encryptedData」に値「0x0022」が代入された状態で、保護対象コードが呼び出される。
その結果、改竄防止プログラム102では、従来のように保護対象コードがデータとして読み込まれることがないため、不正解析者によって改竄防止処理が見つけられるのを困難にすることができる。
さらに、依存処理では、依存処理命令群330の解凍処理「decompressedData=(decompressedData<<1)|(plainData−0xF0DC」が、上述の呼出処理によって保護対象コードが呼び出されて実行された結果(第一処理命令群140の処理結果)である「plainData」の値に依存している。つまり、保護対象コードが改竄されていなければ、「plainData」の値は想定値「0xF0DD」となるため、改竄防止プログラム102の出力処理命令群160が実行されると、第二処理命令群150の解凍処理「decompressedData=(decompressedData<<1)|0x0001」が正しく実行される。
一方、保護対象コードが改竄されていれば、「plainData」の値は想定値「0xF0DD」と異なるため、改竄防止プログラム102の出力処理命令群160が実行されると、第二処理命令群150の解凍処理とは異なる処理が実行される。つまり、改竄防止プログラム102に含まれる入力プログラム101の処理が正しく実行されないこととなる。
その結果、改竄防止プログラム102では、従来のように判定/終了処理がないため、不正解析者によって改竄防止処理が見つけられるのをさらに困難にすることができる。もしも、プログラムに判定/終了処理があれば、不正解析者は、プログラムを複数回実行して各回におけるログを収集することにより、各回におけるログの違いに基づいて、判定/終了処理、すなわち判定/終了処理を伴う改竄防止処理を容易に見つけることができる。
しかし、改竄防止プログラム102では、上述のように、判定/終了処理がないため、改竄防止処理を見つけることが困難になるのである。
さらに、不正解析者に対して、出力処理命令群160から呼び出される保護対象コード(第一処理命令群140)を出力処理命令群160の処理の一部に見せかけることができ、第二処理命令群150を難読化することができる。
このように、本実施の形態における改竄防止処理生成装置110は、第二処理命令群150に対して保護対象コードの呼出処理を追加するとともに依存処理を生成することにより、保護対象コードに対する改竄を確実に防止する出力処理命令群160(改竄防止プログラム102)を生成することができる。また、本実施の形態における改竄防止処理生成装置110は、実行中にメモリ上にあるコードをデータとして読み込むことができないJava(登録商標)等の言語で記述されたプログラムに対しても、そのプログラムの保護対象コードに対する改竄を確実に防止することができる。
(変形例1)
上述した実施の形態では、第一処理命令群140の引数であった変数をそのまま被参照変数値代入処理命令群310で値を代入する変数としていたが、これに限られるものではない。被参照変数値代入処理命令群生成部240は、第二処理命令群150で使用されている変数名を特定し、被参照変数情報保持部230に保持されている変数名のうち、第二処理命令群150で使用されていない変数名の変数にランダムな値を代入する処理を行う命令群を被参照変数値代入処理命令群310としてもよい。このような構成を用いれば、第一処理命令群で戻り値を格納する変数名が、第二処理命令群150で他の用途に使用されている場合でも第二処理命令群150の難読化を行うことができる。
上述した実施の形態では、第一処理命令群140と第二処理命令群150とは、本来、情報をやりとりする必要のない命令群であったため、第一処理命令群140の処理結果を格納する変数をそのまま難読化に用いたとしても、そのことにより正しい処理結果が書き換えられることはなかった。しかし、第二処理命令群150が、第一処理命令群140を呼び出す命令をもともと含んでおり、その処理結果を利用する命令群である場合、単純に上述した難読化を施すと、被参照変数値代入処理命令群310によってその処理結果が書き換えられてしまうことにより、正常な動作が保証できなくなる。ここで、上述のように第二処理命令群150に含まれない変数を用いることにより、難読化に用いる変数と第二処理命令群150にもともと含まれていた第一処理命令群140の処理結果を格納する変数とが異なる変数となるため、処理結果に影響を与えることなく難読化を行うことができる。すなわち、第二処理命令群150が第一処理命令群140を呼び出すような処理を含む場合であっても、上述と同様の難読化を行うことができる。
なお、この場合であっても、(1.5)で述べたものと同様の効果が得られることは言うまでもない。
(変形例2)
被参照変数値代入処理命令群生成部240では、被参照変数に代入する値をランダムに決定するとしたが、代入する値によって、不正解析者の解析行為の困難さに差が出る場合がある。したがって、改竄防止処理生成装置110の構成は、代入する値または想定値がユーザにより指定されるような構成であっても構わない。
以下、図5Cに示すように、被参照変数「encryptedData」に代入する値を「0xF022」とした場合と、「0XF0001」とした場合とで、不正解析者の解析行為の困難さの差を具体的に説明する。
図5Cに示すように、被参照変数「encryptedData」に代入する値を「0xF022」とすると、想定値算出部290が算出する想定値は「0xF0DD」であった。よって、第一処理命令群140が処理「int decrypt(int encryptedData){return 0xF0DD;}」に改竄された場合でも、出力処理命令群160は正常に動作することとなる。
上記の処理は、第一処理命令群140の戻り値を常に想定値となるようにした処理である。
この時、改竄後の第一処理命令群140が出力する再生可能回数は、「0xF0DD」である。ここで、「0xF0DD」は、2進標記した場合の最上位ビットが1であるので、負の値である。すなわち、第一処理命令群140が出力する再生可能回数は常に負の値となるので、仮に上記のような改竄に成功しても再生はできない。したがって、改竄に成功しても失敗しても再生ができないことから、不正解析者は改竄が成功したか否かの判断ができなくなる。また、仮に改竄に成功したと不正解析者が認識していたとしても、再生可能回数が常に負の値であるので、改竄が成功したことによる利益は薄い。
一方、被参照変数に代入する値がランダムに「0x0001」と決まった場合、想定値算出部290が算出する想定値は「0x00FE」である。よって、第一処理命令群140が処理「int decrypt( int encryptedData){return 0x00FE;}」に改竄された場合、出力処理命令群160は正常に動作することとなる。
この時、改竄後の第一処理命令群140が出力する再生可能回数0x00FEは、最上位ビットが0であるので常に正の値となる。この場合、常に再生が可能となってしまうので、これは、不正解析者にとって望ましい改竄である。
このように、被参照変数に代入する値によって不正解析者の解析行為が困難さに差が出る場合がある。そこで、改竄防止処理生成装置110を、代入する値または想定値がユーザにより指定されるような構成としてもよい。
(変形例3)
実施の形態1では、被参照変数の値をランダムに決定し、その値に対応する想定値を想定値算出部290により算出したが、改竄防止処理生成装置110を、予め被参照変数の値や想定値が与えられるような構成としても構わない。
例えば、第一処理命令群140を開発した後に行うテストの際のテストデータに含まれる、被参照変数情報や、被参照変数値、想定値などの情報を用いる構成としても構わない。
その場合、改竄防止処理生成装置110は、被参照変数解析部220、被代入変数解析部270、想定値算出部290を含まなくてよい。
このような構成は、同一の第一処理命令群140を用いる複数の異なるプログラムのそれぞれに対して難読化を行うような場合や、難読化強度の調節を行う他の手法と組み合わせて適切な実行速度と強度を兼ね備えた出力処理命令群160が得られるまで何度も難読化を試みる場合等に有効である。
すなわち、想定値の算出に時間がかかる場合、同じ想定値を得られるのみであるにも関わらず、難読化が行われるたびに想定値の算出処理が行われるので、それぞれの難読化に余分な時間がかかってしまう。上記のような構成を用いることで、一度想定値を算出すれば、その値を使い回すことができるので、想定値の算出にかかる時間の分、難読化処理にかかる時間を短くすることができる。
(変形例4)
被参照変数を一つも含まないような第一処理命令群140を対象とする場合には、改竄防止処理生成装置110を、被参照変数解析部220および被参照変数情報保持部230を含まない構成としてもよい。
(変形例5)
実施の形態1の改竄防止処理生成装置110では、C言語を対象としているため、中間プログラムを保持する被参照変数値代入処理命令群保持部250、分岐処理命令群保持部204、および依存処理命令群保持部202と、出力処理命令群生成部205とを備えて、中間プログラムから、変数宣言および関数宣言等を有するC言語のプログラム(出力処理命令群160)を出力した。しかし、アセンブリ言語のような、順に処理命令を並べることでプログラムを生成できる言語を対象とする場合には、改竄防止処理生成装置110は、これらの要素を備えずに、出力処理命令群保持部に206に順に中間プログラムを追記して出力処理命令群160を出力してもよい。
(変形例6)
改竄防止処理生成装置110の変形例である改竄防止処理生成装置110aについて図9および図10を用いて説明する。なお、以降の説明で、実施の形態1の構成要素(装置、部、および処理命令群など)の符号の語尾に「a」を付けたものはその構成要素の変形例である。例えば、改竄防止処理生成装置110aは、実施の形態1の構成要素である改竄防止処理生成装置110の変形例である。また、本変形例における構成要素のうち、実施の形態1の構成要素の名称および符号と同じ名称および符号を用いて示される構成要素は、実施の形態1にて説明した構成要素と同一である。
改竄防止処理生成装置110aは改竄防止処理生成装置110と同じく処理システム100において用いられる装置である。改竄防止処理生成装置110aは、第一処理命令群140および第二処理命令群150を入力とし、出力処理命令群160aを出力する。以下、出力処理命令群160aおよび改竄防止処理生成装置110aを説明する。
(3)出力処理命令群160aの構成
図9は、改竄防止処理生成装置110aによって生成された出力処理命令群160aの具体例を示す図である。
出力処理命令群160aは、第一処理命令群140を実行する際に必要となる各種パラメータに値を設定する被参照変数値代入処理命令群310aと、第一処理命令群140を呼び出す分岐処理命令群320aと、第一処理命令群140を呼び出した後に実行される依存処理命令群330aとからなる。以下、この具体例を用いながら各部を説明する。
(3.1)被参照変数値代入処理命令群310a
被参照変数値代入処理命令群310aは、第一処理命令群140を呼び出して実行する際に必要となる各種パラメータに値を設定する処理である。図5Cの被参照変数値代入処理命令群310では、被参照変数「encryptedData」に格納される値は常に1つの値「0xF022」と固定されていたのに対し、被参照変数値代入処理命令群310aでは、格納される値は1つの固定された値とはならない。
具体的には、図9の被参照変数値代入処理命令群310a「encryptedData=compressedData<<8;」では、被参照変数「encryptedData」に格納される値は「compressedData」の値に依存する。「compressedData」は、0〜31の値(16進数表記で0x00〜0x1F)を取るので、被参照変数値代入処理命令群「encryptedData=compressedData<<8;」によって被参照変数「encryptedData」に代入される値は「0x0000、0x0100、…、0x1F00」のいずれかとなる。以降の説明では、被参照変数が取る値を集合の表現を用いて{encryptedData|encryptedData=0x0000、0x0100、…、0x1F00}と表す。あるいは、被参照変数が取る値を、「compressedData」も使った集合の表現として{encryptedData|encryptedData=compressedData<<8、compressedData=0x00、0x01、…、0x1F}と表す。
(3.2)分岐処理命令群320a
分岐処理命令群320aは第一処理命令群140に分岐する処理命令群である。
実施の形態1の場合、実行処理装置130により出力処理命令群160を実行した場合、第一処理命令群140を呼び出した後の被代入変数「plainData」が取る値は常に1つの固定された値である。なぜならば、第一処理命令群140の処理結果に影響を与える変数は被参照変数であり、実施の形態1では、その被参照変数に常に同じ値を代入しているからである。
一方、本変形例では、被参照変数「encryptedData」に代入される値は1つの固定された値ではないので、被代入変数「plainData」に代入される値も1つの固定された値とはならない。被参照変数「encryptedData」が取る値は「0x0000、0x0100、…、0x1F00」のいずれかであるので、被代入変数「plainData」の取る値は、これらの値を第一処理命令群140によって処理した結果である「0x00FF、0x01FF、…、0x1FFF」のいずれかとなる。被代入変数が取る値を集合で表現した場合、{plainData|plainData=0x00FF、0x01FF、…、0x1FFF}あるいは、{plainData|plainData=(compressedData<<8)^0x00FF、compressedData=0x00、0x01、…、0x1F}となる。
(3.3)依存処理命令群330a
依存処理命令群330aは、第一処理命令群140を呼び出した後に実行される処理命令群であり、第二処理命令群150と同等の処理を行う処理命令群である。具体的には、被代入変数の値が、(3.2)で述べた取り得る値のいずれであっても第二処理命令群150と同等の処理を行う処理命令群である。
より具体的には、依存処理命令群330aは、処理命令群「 for(counter=0;counter<compressedData;counter++){decompressedData=(decompressedData<<1)|((compressedData<<8)^plainData^0x00FE);}」である。
上記の処理命令群で、着目すべきは「(compressedData<<8)^plainData^0x00FE」の処理命令群の部分である。
{plainData|plainData=(compressedData<<8)^0x00FF、compressedData=0x00、0x01、…、0x1F}の時、上記の処理命令群は「(compressedData<<8)^(compressedData<<8^0x00FF)^0x00FE」を算出する処理となり、出力値は常に1となる。すなわち、(compressedData<<8)とplainDataとは上位の8ビットが同一の値compressedDataであるので、排他的論理和演算の結果は常に値「0x00FF」となる。上記の処理命令群では、この値に対して、さらに、0xFEという最下位ビットのみ「0x00FF」と異なる値との排他的論理和を取ることにより、最下位ビットのみが1の値、すなわち、「0x0001」が得られる。よって、依存処理命令群330aは、被代入変数の値が、(3.2)で述べた取り得る値のいずれであっても第二処理命令群150と同等の処理となる。
(3.4)出力処理命令群160aの効果
出力処理命令群160aを用いれば、被代入変数に格納される値は変数「compressedData」に依存して変化する値となるので、不正解析者の解析が困難になる。以下、この詳細を説明する。
実施の形態1の場合、不正解析者が、被参照変数「compressedData」に「0〜31」の何れかの値を順に代入して出力処理命令群160を実行すると、分岐処理命令群320「plainData=decrypt(encryptedData)」の処理結果である被代入変数「plainData」の値は常に1つの固定された値「0xF0DD」となる。そこで、不正解析者は、「plainData」の値は常に「0xF0DD」になると推測して、分岐処理命令群320を「plainData=0xF0DD;」に置き換える改竄を行うことができる。このような手順で不正解析者が解析を行った場合、不正解析者は、第一処理命令群140の中身を解析せずに出力処理命令群160を効率的に解析することが出来る。一方、出力処理命令群160aの場合には、被代入変数の値は「compressedData」の値に応じて変化するため、このような解析を行うことは出来ない。
(4)改竄防止処理生成装置110aの構成
図10は、改竄防止処理生成装置110aの構成を示す図である。
改竄防止処理生成装置110aは、図6の改竄防止処理生成装置110の、被参照変数値代入処理命令群生成部240、被参照変数値保持部260、想定値算出部290、想定値情報保持部295、および依存処理命令群生成部201がそれぞれ、被参照変数値代入処理命令群生成部240a、被参照変数値保持部260a、想定値算出部290a、想定値情報保持部295a、および依存処理命令群生成部201aに置換わったものである。
以下、置き換わった構成要素のそれぞれについて説明する。なお、以下の例で挙げる具体例は、図9に示す出力処理命令群160aとは異なる出力処理命令群を得るための処理であることに注意されたい。
(4.1)被参照変数値代入処理命令群生成部240a
被参照変数値代入処理命令群生成部240aは、第一処理命令群140を実行する際に必要なパラメータに値を設定する処理命令群である被参照変数値代入処理命令群310aを生成し、生成した処理命令群を被参照変数値代入処理命令群保持部250に書き込む。また、パラメータに設定する値を被参照変数値保持部260aに書き込む。
具体的には、例えば、被参照変数値代入処理命令群生成部240aは、被参照変数情報保持部230が保持する変数名を取得し、取得したそれぞれの変数に対し以下のA)〜D)の処理を行う。
A)被参照変数値代入処理命令群生成部240aは、被参照変数値代入処理命令群310aを決定する。被参照変数値代入処理命令群310aは、第二処理命令群150の被依存変数を用いてランダムに生成されるとしてもよいし、あらかじめ定められた命令群のテンプレートに被依存変数を当てはめる等としてもよい。
B)被参照変数値代入処理命令群生成部240aは、決定した被参照変数値代入処理命令群310aを被参照変数値代入処理命令群保持部250に書き込む。
C)被参照変数値代入処理命令群生成部240aは、被参照変数値代入処理命令群310aによる、被参照変数が取りうる値の集合を求める。
D)被参照変数値代入処理命令群生成部240aは、求めた集合を被参照変数値保持部260aに書き込む。
より具体的には、図5Aの第一処理命令群140に対しては、以下の処理が行われる。
A)被参照変数値代入処理命令群生成部240aは、被参照変数値代入処理命令群310aを「encryptedData=compressedData<<8」とする。この処理命令群は、第二処理命令群150の被依存変数を用いてランダムに生成した式である。
B)被参照変数値代入処理命令群生成部240aは、被参照変数値代入処理命令群310a「encryptedData=compressedData<<8」を被参照変数値代入処理命令群保持部250に書き込む。
C)被参照変数値代入処理命令群生成部240aは、被参照変数値代入処理命令群310aによる、被参照変数が取りうる値の集合を求める。この集合は、{encryptedData|encryptedData=compressedData<<8、compressedData=0x00、0x01、…、0x1F}となる。
D)被参照変数値代入処理命令群生成部240aは、求めた集合を被参照変数値保持部260aに書き込む。ここでは、集合{encryptedData|encryptedData=compressedData <<8、compressedData=0x00、0x01、、、0x1F}を書き込む。
(4.2)被参照変数値保持部260a
被参照変数値保持部260aは、第一処理命令群140を実行する際に必要なパラメータに設定する値を記憶する領域を備える。
具体的には、例えば、被参照変数値保持部260aは、変数名と、その変数名の変数が取りうる値の集合の情報とを記憶する領域を備える。
より具体的には、図5Aの第一処理命令群140に対しては、被参照変数値保持部260aは、集合{encryptedData|encryptedData=compressedData<<8、compressedData=0x00、0x01、…、0x1F}を保持する。ここで、変数名は「encryptedData」であり、その値の集合は、{encryptedData=compressedData<<8、compressedData=0x00、0x01、…、0x1F}である。なお、保持する内容は、具体的に値を列挙したものであっても、集合の表現であっても構わない。
(4.3)想定値算出部290a
想定値算出部290aは、被参照変数値保持部260aが保持する被参照変数の値を用いて第一処理命令群140を実行した場合に、被代入変数に代入される想定値の値を算出する。ここで、被参照変数の値が1つの値だけではなく、値の集合に含まれる何れかの値であるので、想定値算出部290aは、想定値を集合として求める。
具体的には、想定値算出部290aは、例えば以下のA)〜C)の処理を行う。
A)想定値算出部290aは、被代入変数情報保持部280から被代入変数情報を読み込む。
B)想定値算出部290aは、被参照変数値保持部260aから被参照変数名、および値の集合を読み込み、値の集合の要素について以下の(α)および(β)の処理を繰り返す。
(α)想定値算出部290aは、被参照変数に、読み込んだ値を代入し、入力処理命令群保持部210が保持する第一処理命令群140を実行する。
(β)想定値算出部290aは、第一処理命令群140の実行後の被代入変数の値を参照する。
C)想定値算出部290aは、B)で参照した値の集合および、A)で読み込んだ被代入変数の変数名を想定値情報保持部295に格納する。
より具体的には、(4.1)および(4.2)の具体例に示した処理が行われている場合、想定値算出部290aは、以下の処理を行う。
A)想定値算出部290aは被代入変数情報「int plainData」を読み込む。
B)想定値算出部290aは集合{encryptedData|encryptedData=compressedData<<8、compressedData=0x00、0x01、…、0x1F}を読み込む。
想定値算出部290aは「compressedData」が「0x00、0x01、…、0x1F」の各場合について、以下の(α)および(β)の処理を繰り返す。
(α)想定値算出部290aは「compressedData」が各値の場合の「encryptedData」の値を算出し、さらに第一処理命令群140による処理の結果である「encryptedData^0x00FF」を算出する。
(β)想定値算出部290aは、算出した値を参照する。なお、compressedDataが「0x00、0x01、…、0x1F」の各場合について被代入変数「plainData」の値は「0x00FF、0x01FF、…、0x1FFF」となる。
C)想定値算出部290aは、{plainData|plainData=0x00FF、0x01FF、…、0x1FFF}を想定値情報保持部295に格納する。
なお、上述した処理は、「plainData」の値の集合を、列挙により表現する場合の処理である。「plainData」の値を集合の表現として記録する場合には、想定値算出部290aは、(α)および(β)の処理を繰り返す代わりに、第一処理命令群140の処理「encrypedData^0x00FF」を用いて、{plainData|plainData=(compressedData<<8)^0x00FF、compressedData=0x00、0x01、…、0x1F}を格納しても構わない。
(4.4)想定値情報保持部295a
想定値情報保持部295aは、想定値情報を記憶する領域を備える。
具体的には、想定値情報保持部295aは、想定値算出部290aが算出した想定値の集合とその変数名を上述の想定値情報として保持する。
より具体的には、想定値情報保持部295aは、想定値算出部290aが(4.3)に示した具体例の処理を行っている場合、{plainData|plainData=0x00FF、0x01FF、…、0x1FFF}を記憶する。ここで、変数名は「plainData」であり、その値の集合は、{plainData=0x00FF、0x01FF、…、0x1FFF}である。なお、上述のような値を列挙する形式で想定値を保持するのではなく、集合を示す形で想定値を保持してもよいことは言うまでもない。この場合、想定値情報保持部295aは、{plainData|plainData=(compressedData<<8)^0x00FF、compressedData=0x00、0x01、…、0x1F}を記憶する。
(4.5)依存処理命令群生成部201a
依存処理命令群生成部201aは、想定値情報保持部295aが保持する想定値および入力処理命令群保持部210が保持する第二処理命令群150に基づき依存処理命令群330aを生成する。
依存処理命令群330aは、第二処理命令群150と同等の処理を行う処理命令群であって、第一処理命令群140の処理結果を参照する処理を含み、一部の処理がその参照した値を用いた処理となっている処理命令群である。
具体的には、例えば、依存処理命令群330aは、以下のA)〜F)の処理を行う。
A)依存処理命令群生成部201aは、第二処理命令群150に含まれる処理命令に含まれる定数を見つける。この定数を含む処理命令をOr1、その定数の値をVa1とする。
B)依存処理命令群生成部201aは、想定値情報保持部295aが保持する想定値情報を読み込む。
C)依存処理命令群生成部201aは、想定値の集合の全ての要素を1つの値Va2に対応させる写像Fを生成する。例えば、被参照変数がxであり、想定値の集合が{x|x=x_0、x_1、…、x_n}の時、依存処理命令群生成部201aは、写像Fを(x^x_0)*(x^x_1)*…*(x^x_n)とする。ここで、「*」は乗算を示す。x=x_t(t=0、1、…、nの何れか)であるので、写像Fを示す式の第t項(x^x_t)の値は0となり、第t項以外の項は値が何であっても値0(第t項)との積となるので写像Fは0となる。つまり、この例では、Va2=(x^x_0)*(x^x_1)*…*(x^x_n)=0の関係が成り立つ。
D)依存処理命令群生成部201aは、Va3=Va2−Va1を算出する。先述の例では、Va1=Va2−Va3=(x^x_0)*(x^x_1)*…*(x^x_n)−Va3の関係が成り立つ。
E)依存処理命令群生成部201aは、処理命令Or1に含まれる値Va1を「写像Fの処理−Va3」に置き換えた処理命令Or2を生成する。
F)依存処理命令群生成部201aは、第二処理命令群150の処理命令Or1を処理命令Or2に置き換えた命令群である依存処理命令群330を生成する。
より具体的には、想定値情報保持部295aが(4.4)の具体例に示した処理を行っている場合、依存処理命令群生成部201aは、以下のA)〜F)の処理を行う。
A)依存処理命令群生成部201aは、第二処理命令群150に含まれる処理命令に含まれる定数を見つける。つまり、依存処理命令群生成部201aは、この定数を含む処理命令Or1を「decompressedData=(decompressedData<<1)|0x0001;」とし、その定数の値Va1を「0x0001」とする。
B)依存処理命令群生成部201は、想定値情報保持部295から想定値情報{plainData|plainData=0x00FF、0x01FF、…、0x1FFF}を読み込む。
C)依存処理命令群生成部201aは、想定値の集合の全ての要素を1つの値Va2「0」に対応させる写像F「(plainData^0x00FF)*(plainData^0x01FF)*…*(plainData^0x11FF)」を生成する。
D)依存処理命令群生成部201aは、Va3=Va2−Va1を算出する。すなわち「Va3=0−0x0001=−1=0xFFFF」を算出する。
E)依存処理命令群生成部201aは、処理命令Or1に含まれる値Va1「0x0001」を、「写像Fの処理−Va3」すなわち「(plainData^0x00FF)*(plainData^0x01FF)*…*(plainData^0x11FF)−0xFFFF」に置き換えた処理命令Or2を生成する。
すなわち、処理命令Or2「decompressedData=(decompressedData<<1)|((plainData^0x00FF)*(plainData^0x01FF)*…*(plainData^0x11FF))−0xFFFF);」を生成する。
F)依存処理命令群生成部201は、第二処理命令群150の処理命令Or1を処理命令Or2に置き換えた命令群である依存処理命令群330aを生成する。
すなわち、「 for(counter=0;counter<compressedData;counter){decompressedData=(decompressedData<<1)|((plainData^0x00FF)*(plainData^0x01FF)*…*(plainData^0x11FF))−0xFFFF);}」が生成される。
ここでは、更に、C言語の言語形式にしたがって関数宣言や変数宣言を追加する。
なお、C)では想定値の集合の全ての要素を1つの値に対応させる写像Fの一例を示したが、他の写像であっても構わない。また、写像Fを予めいくつか登録できるようにして、その中から選択する構成であっても構わない。また、写像Fをユーザが指定する構成であっても構わない。この場合も、実施の形態1と同様、同じ写像を使って何度も難読化が行われる場合に有用である。
また、上記で説明した写像Fとは異なる他の写像の具体例としては、例えば図9の依存処理命令群330a中の「(compressedData<<8)^plainData^0x00FE」がある。このような写像であっても正しい値「0x0001」が得られることは、上述したとおりである。
(変形例7)
改竄防止処理生成装置110は、複数の処理命令群の入力を受け付け、その中から第一処理命令群140と第二処理命令群150を選択してもよい。例えば、改竄防止処理生成装置110は、処理命令群A1、処理命令群A2、…、処理命令群Anを取得し、その中からランダムに第一処理命令群140と第二処理命令群150の組を選択し難読化を行っても構わない。さらに、処理を行う対象は1組だけに限るものではなく、選択と難読化を繰り返しても構わない。
また、例えば、改竄防止処理生成装置110は、第一処理命令群140を処理命令群A1とし、第二処理命令群150を処理命令群A1以外の処理命令群からランダムに選択して難読化を行い、以下、処理命令群A2、…、Anについてもそれぞれを第一処理命令群140とし、その第一処理命令群140とされた処理命令群以外の処理命令群から第二処理命令群150を選択して難読化してもよい。
以上のような構成を用いれば、処理命令群A1〜Anは複雑に絡みあうので、さらに改竄を困難にすることが出来る。
また、本発明の応用例として、改竄防止処理生成装置110と同等の構成を一部として含み、プログラムの実行時に改竄防止処理生成装置110による変換を行った上でプログラムを実行する実行処理装置を実装することも考えられる。この場合、その実行処理装置に本変形例と同様の構成を持たせると、どの処理命令群が第一処理命令群および第二処理命令群であるのかを特定することが困難になるため、より解析を困難にすることができる。
(変形例8)
ここでは、第一処理命令140に含まれる命令を保護対象とし、その命令に対する改竄を防止する場合について説明した。しかし、改竄を防止すべき対象は命令に限るものではなく、データであってもよい。実施の形態1のように、命令群を保護する場合は、その命令群へ分岐する処理を追加していたが、保護対象がデータである場合には、そのデータを所定の変数等に読み込む処理を追加する。例えば、第一処理命令群140が使用するデータを保護対象とする場合であれば、分岐処理命令群320の替わりに、保護対象データを読み込む処理を追加し、依存処理命令群330は、その変数に依存し、変数に格納されている値が想定値(ここでは、改竄のないデータ)である場合に正しく動作する構成とすることが考えられる。
このような構成を用いれば、分岐処理命令群320によって第一処理命令群140が実行される替わりに、保護対象データが変数に読み込まれる。そして、保護対象データに改竄があれば、変数に読み込まれる値が変化することにより、依存処理命令群330が第二処理命令群150と異なる動作をするようになる。したがって、実施の形態1における第一処理命令群140に対する保護と同様にして、保護対象データを保護することができる。なお、保護対象データは、例えば、携帯電話における電話番号等の機器固有番号である。
(実施の形態2)
本発明に関わる実施の形態2としての処理システム100bについて説明する。
図11は、実施の形態2における処理システム100bの構成を示す図である。
本実施の形態における処理システム100bは、第一処理命令群140bの入力を受け付けて、第一処理命令群140bの改竄チェックを目的とした出力処理命令群160bを生成するシステムであって、改竄防止処理生成装置110b(命令生成装置)と、実行処理装置130bとを備える。
改竄防止処理生成装置110bは、保護対象コードを確実に保護し得るプログラムを生成する装置である。つまり、改竄防止処理生成装置110bは、保護対象コードである第一処理命令群140bを取得して、その保護対象コードの改竄チェック処理を行う出力処理命令群160bを生成する。また、改竄防止処理生成装置110bは、その生成された出力処理命令群160bと第一処理命令群140bとを記録媒体120bに書き込む。
実行処理装置130bは、記録媒体120bに記録されている第一処理命令群140bおよび出力処理命令群160bを読み出して実行する。
なお、改竄防止処理生成装置110bは、第一処理命令群140bおよび出力処理命令群160bを記録媒体120bに書き込むことなく、通信媒体を介して実行処理装置130bに送信してもよい。
出力処理命令群160bは、処理の途中で第一処理命令群140bを呼び出す構成となっている。すなわち、実行処理装置130bで出力処理命令群160bが実行される場合、最初は出力処理命令群160bに含まれる命令群が実行され、途中で第一処理命令群140bが呼び出されて実行され、次にまた出力処理命令群160bの続きの処理命令群が実行される。
第一処理命令群140bは、実行処理装置130bで実行される処理命令群であって、出力処理命令群160bの処理の途中に実行される場合もあれば、それとは別に実行される場合もある。
具体的には、例えば、第一処理命令群140bは、コンテンツの暗号化された再生可能回数を入力とし、これを復号し、平文の再生可能回数を出力する処理である。出力処理命令群160bは第一処理命令群140bが改竄されていないかをチェックし、改竄されていない場合、0を返し、改竄されていた場合、実行処理装置130bで実行中の処理を停止する処理命令群である。
以下、それぞれについて詳細な説明を行う。
(1)出力処理命令群160bの構成
図12は、出力処理命令群160bの構成を示す図である。
出力処理命令群160bは、第一処理命令群140bを実行する際に必要となる各種パラメータに値を設定する被参照変数値代入処理命令群310bと、第一処理命令群140bを呼び出す分岐処理命令群320bと、第一処理命令群140bを呼び出した後に実行される依存処理命令群330bとからなる。実行処理装置130bで出力処理命令群160bが実行される場合、被参照変数値代入処理命令群310b、分岐処理命令群320b、第一処理命令群140b、依存処理命令群330bの順に各処理命令群の処理が実行される。
以下、それぞれを説明する。
(1.1)被参照変数値代入処理命令群310b
実施の形態1における被参照変数値代入処理命令群310と同様である。
(1.2)分岐処理命令群320b
実施の形態1における分岐処理命令群320と同様である。
(1.3)依存処理命令群330b
依存処理命令群330bは、第一処理命令群140bを呼び出した後に実行される処理命令群であり、第一処理命令群140bの処理結果に基づき改竄をチェックする処理を行う。
第一処理命令群140bの処理結果とは、具体的には、例えば、第一処理命令群140bが関数である場合には関数の戻り値である。また、例えば、第一処理命令群140bが外部変数に値を決定する命令群であるならば、第一処理命令群140bの処理結果とは、外部変数に代入された値である。また、例えば、第一処理命令群140bがスタックに値を格納する命令群であれば、第一処理命令群140bの処理結果とは、スタックに格納された値である。また、例えば、第一処理命令群140bがアドレス変数で指定した位置に値を格納する命令群であれば、第一処理命令群140bの処理結果とは、その格納された値である。これらの第一処理命令群140bの処理結果が格納される格納先のことを、実施の形態1と同様に、被代入変数と呼ぶものとする。
第一処理命令群140bの処理結果を予め知ることは一般には出来ないが、第一処理命令群140bを実行する際に必要となる各種パラメータの値が被参照変数値代入処理命令群310bで設定した値である時に限っては、処理結果の値を予め知ることができる。具体的には、例えば、被参照変数値代入処理命令群310bが設定する値を実際に被参照変数に設定した上で、第一処理命令群140bを実行すれば、処理結果の値を知ることができる。以降の説明では、実施の形態1と同様に、この値を想定値と呼ぶものとする。
(1.4)出力処理命令群160bの一例
図13は、C言語で記述された出力処理命令群160bの具体例を示す図である。
出力処理命令群160bは、図5Aの第一処理命令群140と同等の処理命令群を第一処理命令群140bとした時の出力処理命令群であり、第一処理命令群140bの改竄チェックを行う処理命令群である。
被参照変数値代入処理命令群310b「encryptedData=0xF022;」は、第一処理命令群140bを呼び出す際の引数に値を代入する処理を示す命令群である。すなわち、被参照変数値代入処理命令群310bは変数「encryptedData」に値「0xF022」を代入する。
分岐処理命令群320b「plainData=decrypt(encryptedData);」は、引数を変数「encryptedData」として第一処理命令群140bを呼び出す処理を示す命令群であり、処理結果を変数「plainData」に格納する。実行処理装置130bにおいて、分岐処理命令群320bが正常に実行された場合の戻り値の想定値は、変数「encryptedData」を値「0xF022」とし、第一処理命令群140bの処理を行った際の結果である「0xF022^0x00FF=0xF0DD」となる。
依存処理命令群330bは、第一処理命令群140bの処理結果が、想定値と等しいかを判定し、等しい場合は0を返し、等しくない場合は実行処理装置130bで実行中の処理を停止する処理命令群であって、「 if(plainData!=0xF0DD){exit(1);}return0;」により表される。
上記の処理において、第一処理命令群140bが改竄されている場合、第一処理命令群140bの処理結果は想定値と異なる値となる。
(1.5)出力処理命令群160bの効果
実施の形態2の出力処理命令群160bは、第一処理命令群140bを実行する際に必要となる各種パラメータに値を設定する被参照変数値代入処理命令群310bと、第一処理命令群140bを呼び出す分岐処理命令群320bと、第一処理命令群140bを呼び出した後に実行される依存処理命令群330bとからなる。
このような構成を用いれば、第一処理命令群140bの処理命令が改竄されている場合、第一処理命令群140bの処理結果が想定値と等しいかを判定することにより、第一処理命令群140bの改竄を検出することができる。
従来のハッシュチェックによる改竄チェックは、プログラムをデータとして読み込む必要があった。ところが、通常のプログラムは実行対象として読み込まれることはあっても、データとして読み込まれることは少なく、また読み込みに使用する命令も特殊なものである。よって、不正解析者は、命令を監視し、プログラムをデータとして読み込む命令が実行された場合、その読み込みを行っている処理は改竄チェック処理命令群の一部であり、読み込まれている処理は改竄防止対象となる重要な処理である可能性が高いと判断することができた。しかし、本実施の形態の方法では、プログラムをデータとしてアクセスすることなくプログラムの改竄を検出することが出来る。また、プログラムをデータとしてアクセスすることを禁止している言語でも改竄チェックを行うことができる。
(2)改竄防止処理生成装置110bの構成
図14は、改竄防止処理生成装置110bの構成を示す図である。ここで、改竄防止処理生成装置110bは、第一処理命令群140bの改竄チェックを行う出力処理命令群160bを生成する装置である。
改竄防止処理生成装置110bは、入力処理命令群保持部210b、被参照変数解析部220b、被参照変数情報保持部230b、被参照変数値代入処理命令群生成部240b、被参照変数値代入処理命令群保持部250b、被参照変数値保持部260b、被代入変数解析部270b、被代入変数情報保持部280b、想定値情報保持部295b、想定値算出部290b、依存処理命令群生成部201b、依存処理命令群保持部202b、分岐処理命令群生成部203b、分岐処理命令群保持部204b、出力処理命令群生成部205b、および出力処理命令群保持部206bを備えている。
入力処理命令群保持部210bは、第一処理命令群140bを取得して保持する。
被参照変数解析部220bは、第一処理命令群140bを実行する際に値を設定しておく必要のある引数等の変数(被参照変数)が何であるかを解析する。
被参照変数情報保持部230bは、被参照変数解析部220bによる解析によって得られた被参照変数の変数名等の情報を保持する。
被参照変数値代入処理命令群生成部240bは、被参照変数に値を代入する被参照変数値代入処理命令群310bを生成する。
被参照変数値代入処理命令群保持部250bは、被参照変数値代入処理命令群生成部240bが生成した被参照変数値代入処理命令群310bを保持する。
被参照変数値保持部260bは、被参照変数値代入処理命令群310bが被参照変数に代入する値を保持する。
被代入変数解析部270bは、第一処理命令群140bの処理結果が代入される変数(被代入変数)が何であるかを解析する。
被代入変数情報保持部280bは、被代入変数解析部270bによる解析によって得られた被代入変数の変数名等の情報を保持する。
想定値算出部290bは、被参照変数の値を被参照変数値保持部260bが保持する値とし、第一処理命令群140bを実行した際に得られる被代入変数の想定値を算出する。
想定値情報保持部295bは、想定値算出部290bが算出した想定値を保持する。
依存処理命令群生成部201bは、想定値に基づき依存処理命令群330bを生成する。
依存処理命令群保持部202bは、依存処理命令群生成部201bが生成した依存処理命令群330bを保持する。
分岐処理命令群生成部203bは、入力処理命令群保持部210bが保持する第一処理命令群140bを呼び出す分岐処理命令群320bを生成する。
分岐処理命令群保持部204bは、分岐処理命令群生成部203bが生成した分岐処理命令群320bを保持する。
出力処理命令群生成部205bは、被参照変数値代入処理命令群保持部250bが保持する被参照変数値代入処理命令群310bと、分岐処理命令群保持部204bが保持する分岐処理命令群320bと、依存処理命令群保持部202bが保持する依存処理命令群330bとからなる出力処理命令群160bを生成する。
出力処理命令群保持部206bは、出力処理命令群生成部205bが生成した出力処理命令群160bを保持する。
以下、実施の形態1と異なる入力処理命令群保持部210b、および依存処理命令群生成部201bについて説明する。他の部は、実施の形態1記載の対応する部と同等の処理を行うので、説明を省略する。
(2.1)入力処理命令群保持部210b
入力処理命令群保持部210bは、外部から第一処理命令群140bの入力を受け付ける。つまり、入力処理命令群保持部210bは、第一処理命令群140bを取得する。また、入力処理命令群保持部210bは、1以上の処理命令群を記憶する領域を備えている。入力処理命令群保持部210bは、改竄防止処理生成装置110bに入力された第一処理命令群140bを保持する。
(2.2)依存処理命令群生成部201b
依存処理命令群生成部201bは、想定値情報保持部295bが保持する想定値に基づき依存処理命令群330bを生成する。
具体的には、例えば、依存処理命令群生成部201bは、以下のA)〜D)の処理を行う。
A)依存処理命令群生成部201bは、想定値情報保持部295bが保持する想定値情報を読み込む。
B)依存処理命令群生成部201bは、その想定値を保持すべき変数(被代入変数)をVr1、その想定値をVa1とする。
C)依存処理命令群生成部201bは、変数Vr1と想定値Va1を比較し、等しい場合は0を返し、等しくない場合は実行処理装置130bで実行中の処理を停止する処理命令群を生成する。なお、ここでは一般的なプログラミングの作法にしたがって、検証結果が正しい場合(ここでは改竄がないことが確認された場合)には0を返すとしているが、これに限るものではない。0以外の値を返すとしてもよいし、何も値を返さないとしてもよい。すなわち、改竄がないことが確認された場合に、実行中の処理が継続される限り、返す値はどのようなものであっても構わない。
D)依存処理命令群生成部201bは、生成した依存処理命令群330bを依存処理命令群保持部202bに格納する。
より具体的には、想定値情報保持部295bが実施の形態1の(2.10)と同様の処理を行っている場合、依存処理命令群生成部201bは、以下のA)〜D)の処理を行う。
A)依存処理命令群生成部201bは、想定値情報保持部295bが保持する想定値情報「int plainData=0xF0DD」を読み込む。
B)依存処理命令群生成部201bは、その想定値を保持すべき変数「plainData」をVr1とし、その想定値「0xF0DD」をVa1とする。
C)依存処理命令群生成部201bは、変数Vr1と想定値Va1を比較し、等しい場合は0を返し、等しくない場合は実行処理装置130bで実行中の処理を停止する処理命令群「 if(plainData!=0xF0DD){exit(1);}return0;」を生成する。
D)依存処理命令群生成部201bは、生成した依存処理命令群330bを依存処理命令群保持部202bに格納する。
(2.3)改竄防止処理生成装置110bの効果
改竄防止処理生成装置110bは、プログラムをデータとして読み込むことなくプログラムの改竄をチェックできる改竄チェック処理命令群(出力処理命令群160b)を生成することが出来る。
図15は、改竄防止処理生成装置110bの効果を説明するための説明図である。
改竄防止処理生成装置110は、例えば、第一処理命令群140bを含む入力プログラム101bを取得して、その入力プログラム101bを改竄防止プログラム102bに変換して出力する。このとき、改竄防止処理生成装置110は、上述のように、出力処理命令群160bを生成して入力プログラム101bに追加している。
つまり、改竄防止処理生成装置110は、保護対象コードである第一処理命令群140bの呼出処理(被参照変数値代入処理命令群310bおよび分岐処理命令群320b)と、呼出処理によって行われた第一処理命令群140bの処理結果が想定値と異なるときに実行処理装置130bによって実行されている処理を中止させる判定/終了処理(依存処理命令群330b)とを、改竄防止処理として生成し、入力プログラム101bに追加している。
保護対象コード(第一処理命令群140)の呼出処理では、被参照変数値代入処理命令群310bにおいて、保護対象コードの被参照変数「encryptedData」に値「0x0022」が代入された状態で、保護対象コードが呼び出される。
その結果、改竄防止プログラム102bでは、従来のように保護対象コードがデータとして読み込まれることがないため、不正解析者によって改竄防止処理が見つけられるのを困難にすることができる。
さらに、判定/終了処理では、依存処理命令群330bの「if(plainData!=0xF0DD){exit(1);}return0;」が、上述の呼出処理によって保護対象コードが呼び出されて実行された結果(第一処理命令群140bの処理結果)である「plainData」の値に依存している。つまり、保護対象コードが改竄されていなければ、「plainData」の値は想定値「0xF0DD」となるため、改竄防止プログラム102bの出力処理命令群160が実行されると、改竄防止プログラム102bにおける入力プログラム101bと同等の処理が実行処理装置130bにより正しく実行される。
一方、保護対象コードが改竄されていれば、「plainData」の値は想定値「0xF0DD」と異なるため、実行処理装置130bによって実行されている、改竄防止プログラム102bにおける入力プログラム101bと同等の処理が中止されることとなる。
このように、本実施の形態における改竄防止処理生成装置110bは、入力プログラム101bに対して保護対象コードの呼出処理および判定/終了処理を生成して追加することにより、保護対象コードに対する改竄を確実に防止することができる。また、本実施の形態における改竄防止処理生成装置110bは、実行中にメモリ上にあるコードをデータとして読み込むことができないJava(登録商標)等の言語で記述されたプログラムに対しても、そのプログラムの保護対象コードに対する改竄を確実に防止することができる。
(実施の形態3)
本発明に関わる実施の形態3の処理システム1300について説明する。実施の形態3に係る処理システム1300は、1つの入力プログラム中に含まれる第一処理命令群(後述するA命令群に対応)と第二処理命令群(後述するB命令群とSUC_B命令群に対応)とを用いて、その入力プログラムの難読化を行う。また、実施の形態1および2では、第一処理命令群の処理結果を第二処理命令群でも用いるように難読化していたが、実施の形態3では、A命令群(第一処理命令群)の処理結果をSUC_B命令群(第二処理命令群)では用いない。つまり、実施の形態3では、第二処理命令群の処理途中で本来不要な処理である第一処理命令群に分岐し、その後第二処理命令群の続きを行わせることで、制御構造の複雑化を図っている。
実施の形態3では、このような入力プログラムの難読化(制御構造の複雑化)を図ることにより、保護対象コードであるA命令群(第一処理命令群)を改竄から確実に保護することができる。
従来、プログラムの処理の流れを困難にし、不正な解析を防止する技術として、非特許文献1(Chenxi Wang、“A Security Architecture for Survivability Mechanisms”、 Ph.D. Dissertation (2000))に記載の技術のような単純な無条件分岐命令を分岐先が分かり難い条件分岐命令に置換える方法や、プログラムを複数の命令群に分割して命令群の配置順序を入替える方法が知られている。不正な解析の結果は、その後の不正な改竄の際に手掛かりとなるため、解析の時点で不正行為を防止できるようにことは有用である。しかし、上述したような方法で難読化を行ったとしても、実際にプログラムを動かすことで命令群の実行順序や前後関係(例えば、PRE_A命令群の次にA命令群が実行されるという関係)を知ることは出来てしまう。そこで、実施の形態3では、プログラムを実際に動かした時にも命令群の実行順序等が分からないように制御構造を難読化する。
以下、実施の形態3の処理システム1300を説明する。
図16は、実施の形態3における処理システム1300の構成を示す図である。
本実施の形態における処理システム1300は、改竄防止処理生成装置(命令生成装置)1320と、実行処理装置1340とを備える。
改竄防止処理生成装置1320は、保護対象コードを確実に保護し得るプログラムを生成する装置であって、保護対象コードを含む入力プログラム1310を取得してその入力プログラム1310を難読化することにより、改竄防止プログラム1330を生成する。
また、改竄防止処理生成装置1320は、その生成された改竄防止プログラム1330を記録媒体1350に書き込む。
実行処理装置1340は、記録媒体1350に記録されている改竄防止プログラム1330を読み出して実行する。
なお、改竄防止処理生成装置1320は、改竄防止プログラム1330を記録媒体1350に書き込むことなく、通信媒体を介して実行処理装置1340に送信してもよい。
ここで、入力プログラム1310は、以降に述べるように、一つ以上の命令からなるPRE_A命令群と、PRE_A命令群の後に実行されるA命令群と、B命令群とを含む。
(1)入力プログラム1310の構成
図17は、入力プログラム1310の構成を示す図である。
入力プログラム1310は、A命令群1420と、A命令群1420の分岐元の命令群であるPRE_A命令群1410と、A命令群1420の分岐先の命令群であるSUC_A命令群1430と、B命令群1440と、B命令群1440の分岐先の命令群であるSUC_B命令群1450とを含んでいる。
ここで、各命令群は0以上の命令からなる命令の集合である。すなわち、一部の命令群については、存在していなくとも良い。例えば、A命令群1420がプログラムの先頭である場合には、PRE_A命令群1410は存在しなくともよい。また、A命令群1420やB命令群1440が、プログラムの最後である場合には、SUC_A命令群1430やSUC_B命令群1450は存在しなくともよい。
また、ここで、Y命令群がX命令群の分岐先であるとは、X命令群の後にY命令群が実行されることを意味する。具体的には、例えば、X命令群の直後にY命令群が配置されている場合や、X命令群にY命令群への分岐命令が含まれる場合などがある。なお、X命令群の直後に明示的な分岐命令が存在していなくとも、プログラムの記法上、X命令群の後にY命令群が実行される場合も、本実施の形態では分岐と呼ぶ。例えばC言語では、特に分岐命令等がない場合、プログラム中の命令は上から順に実行される。この場合、X命令群の下にY命令群が記述されていれば、X命令群の後にY命令群が実行されるので、Y命令群はX命令群の分岐先である。また、X命令群がY命令群の分岐元であるとは、Y命令群がX命令群の分岐先であることを意味する。
なお、分岐命令とは、具体的には、条件分岐命令や、無条件分岐命令、サブルーチンコール、例外を発生させる命令、割込みを発生させる命令などを含む。すなわち、ある命令群から別の命令群へ実行を移すような命令はいずれも本明細書で述べる分岐命令に当たる。例えば、アセンブリ言語の命令であれば、「CALL、RET」のような関数コールや「JA、JMP、LOOP」などのジャンプ命令、「INT」などの割り込み命令である。
図18は、C言語における入力プログラム1310の具体的な一例を示す図である。
入力プログラム1310は、PRE_A命令群1410と、A命令群1420と、SUC_A命令群1430と、B命令群1440と、SUC_B命令群1450とを含む。
(2)改竄防止プログラム1330の構成
改竄防止プログラム1330は、入力プログラム1310が改竄防止処理生成装置1320によって難読化されたプログラムである。
図19は、改竄防止プログラム1330の構成を示す図である。
改竄防止プログラム1330は、PRE_A命令群1410と、STR_A変数群値代入命令群1620と、A命令群1420と、CBR_AB条件分岐命令群1610と、SUC_A命令群1430と、B命令群1440と、STR_B変数群値代入命令群1630と、退避命令群1640と、BR_B分岐命令群1660と、復帰命令群1650と、SUC_B命令群1450とを含んでいる。
入力プログラム1310では、A命令群1420が実行されるのはPRE_A命令群1410が実行された後だけであったが、改竄防止プログラム1330は、B命令群1440の後にもA命令群1420が実行されるように変換されている。より具体的に述べると、改竄防止プログラム1330では、PRE_A命令群1410、A命令群1420、SUC_A命令群1430の順に各命令群の処理が実行される場合もあれば、B命令群1440、A命令群1420、SUC_B命令群1450の順で各命令群の処理が実行される場合もある。すなわち、B命令群1440とSUC_B命令群1450の間にA命令群1420の実行が割り込む場合がある。
図20は、C言語で表した改竄防止プログラム1330の具体的な一例を示す図である。
改竄防止プログラム1330は、入力プログラム1310に含まれる各要素に加え、以下の要素を含む。これらの要素は、改竄防止処理生成装置1320により、入力プログラム1310に付け加えられるが、この付け加える処理の詳細については後述する。
BR_B分岐命令群1660は、B命令群1440の後に、A命令群1420を実行させるための分岐命令である。
CBR_AB条件分岐命令群1610は、A命令群1420の実行後、適切な分岐先を判定してその分岐先に処理を分岐させるための命令群である。入力プログラム1310では、A命令群1420の後に実行される命令群は常にSUC_A命令群1430であったが、改竄防止プログラム1330においては、SUC_A命令群1430の場合と、SUC_B命令群1450の場合とがある。CBR_AB条件分岐命令群1610は、A命令群1420の実行後、SUC_A命令群1430とSUC_B命令群1450のどちらに分岐すべきかを判定して、適切な分岐先に処理を分岐させる。
STR_A変数群値代入命令群1620、およびSTR_B変数群値代入命令群1630は、CBR_AB条件分岐命令群1610の判定に用いる情報(本実施の形態では、後述する変数「var_ab0」の値)をセットする命令群である。改竄防止プログラム1330では、A命令群1420がPRE_A命令群1410の後に実行されているならば、次に実行されるべき命令群はSUC_A命令群1430であり、A命令群1420がB命令群1440の後に実行されているならば、次に実行されるべき命令群はSUC_B命令群1450である。そのどちらであるのかがわかるように、すなわち、PRE_A命令群1410が行われた後なのか、B命令群1440が行われた後なのかがわかるように、判定の手掛かりを残す命令群が、STR_A変数群値代入命令群1620およびSTR_B変数群値代入命令群1630である。
退避命令群1640は、既に実行された処理結果がその後に実行される処理によって影響されないように、その既に実行された処理結果を退避する命令群である。また、復帰命令群1650は、その退避された処理結果を復帰させる命令群である。
改竄防止プログラム1330では、B命令群1440の実行とSUC_B命令群1450の実行と間にA命令群1420の実行が割り込む。そのため、B命令群1440が終った時点での処理の途中結果を、A命令群の処理によって影響されないように退避しておく必要がある。この退避処理を行う命令群が退避命令群1640である。
また、復帰命令群1650は、退避命令群1640が退避した途中結果の内容を、SUC_B命令群1450に戻った時点で戻す。
以下、各命令群について、図19、図20を用いてより詳細に説明する。
(2.1)退避命令群1640
B命令群1440とSUC_B命令群1450との間に割り込むA命令群1420の処理によって、SUC_B命令群1450およびその後で実行される命令群の処理に影響が及ばないように、途中結果を退避しておく処理を行う命令群が退避命令群1640である。具体的には、退避命令群1640は、A命令群1420で値が代入される変数のうち、SUC_B命令群以降に実行される命令群において参照される変数に格納されている値を他の変数に格納する命令群である。
入力プログラム1310では、B命令群1440とSUC_B命令群1450以降との間には他の命令が存在しないため、B命令群までが実行された時点での途中結果が、SUC_B命令群以降にも引き継がれる。ここで、入力プログラム1310が、改竄防止処理生成装置1320によって難読化されると、B命令群1440とSUC_B命令群1450以降の命令との間にA命令群1420の実行が割り込むこととなる。このとき、A命令群1420が、SUC_B命令群1450以降の命令が用いる変数と同じ変数を変化させる命令を含む場合、上述した途中結果がA命令群1420によって書き換えられてしまうこととなる。このような事態が発生すると、改竄防止プログラム1330の実行結果が入力プログラム1310と異なるものとなってしまう。このような事態を避けるために、A命令群1420が実行される前後で途中結果を退避および復帰させる必要がある。
例えば図20のA命令群1420においては、変数「var_org0」と変数「var_org1」とが値が代入される変数である。そのうち変数「var_org2」は、SUC_B命令群1450中の命令「var_org1=var_org1+var_org2;」において値が参照されている。そのため、処理の途中結果である「var_org2」の値を退避する必要があるが、この「var_org2」に格納されている値を他の変数「var_save0」に退避する処理「var_save0=var_org2;」が退避命令群1640である。
なお、本実施の形態では、変数の値を例として述べているが、変数以外にもA命令群1420によって改変される恐れのある情報は退避しておくことが望ましい。このような情報の例としてはスタックや、レジスタ、キャッシュの記録内容などが考えられる。
(2.2)復帰命令群1650
復帰命令群1650は、難読化によってB命令群1440とSUC_B命令群1450の間に割り込むこととなったA命令群1420の処理が終った後に、退避命令群1640で退避しておいた値を元の変数に戻す命令群である。
具体的には、図20の復帰命令群1650は、変数「var_save0」に退避した値を変数「var_org2」に格納する処理「var_org2=var_save0;」として表される。
なお、A命令群が、SUC_B命令群以降の命令で参照する変数を変化させない場合は、これらの変数を退避する必要がないので、退避命令群1640と復帰命令群1650は不要である。
(2.3)CBR_AB条件分岐命令群1610
CBR_AB条件分岐命令群1610は、SUC_A命令群1430とSUC_B命令群1450とを条件分岐先に含む条件分岐命令である。なお、改竄防止プログラム1330が復帰命令群1650を含む場合には、退避していた内容を復帰させた上でSUC_B命令群1450以降の処理を行わなくてはならないので、SUC_B命令群1450の替わりに復帰命令群1650を条件分岐先とする。図20では、SUC_B命令群1450と復帰命令群1650にそれぞれ、「SUC_B」、「SUC_B_」を付しているが、CBR_AB条件分岐命令群1610は、復帰命令群1650が存在する場合には、ラベル「SUC_B_」が付された復帰命令群1650を分岐先とし、存在しない場合には、ラベル「SUC_B」が付されたSUC_B命令群1450を分岐先とする。復帰命令群1650が存在しない場合としては、復帰させるべき途中結果がない場合などが考えられる。
図20に例示した改竄防止プログラム1330は、復帰命令群1650を含む。したがって、CBR_AB条件分岐命令群1610は、SUC_A命令群1430と復帰命令群1650とを条件分岐先とし、「変数var_ab0」の値によって分岐先が決定する条件分岐命令「if(var_ab0%2==0)goto SUC_B_;」として表される。ここで、変数「var_ab0」は、A命令群1420が、PRE_A命令群1410の後に実行されたのか、B命令群1440の後に実行されたのかを示す手がかりとなる変数であり、後述するG_VAL_AB変数群にあたる。改竄防止プログラム1330では、このCBR_AB条件分岐命令群1610によって、A命令群1420の後にSUC_A命令群1430が実行される場合と、A命令群1420の後に復帰命令群1650(またはSUC_B命令群1450)が行われる場合とが生じるよう制御している。
なお、本実施の形態では、改竄防止プログラム1330はC言語で記述されているため、CBR_AB条件分岐命令群1610において、明示的にSUC_A命令群1430へ分岐する命令を記述していない。すなわち、C言語の記法上、CBR_AB条件分岐命令群1610のif文中の条件「var_ab0%2==0」が偽の場合、CBR_AB条件分岐命令群1610の直後にはSUC_A命令群が実行されるため、SUC_A命令群への明示的な分岐命令は不要である。つまり、図20の記述内容でも、実質的にCBR_AB条件分岐命令群1610はSUC_A命令群1430とSUC_B命令群1450とのいずれを実行するかの分岐を示すこととなる。なお、図20のCBR_AB条件分岐命令群1610の直後に「else goto SUC_A;」等の明示的な分岐命令が記述されていても良いことは言うまでもない。上述のように明示的な分岐命令を記述しておくことで、CBR_AB条件分岐命令群1610とSUC_A命令群1430とがプログラム上で離れた位置にあっても適切な分岐処理を行うことができる。
(2.4)STR_A変数群値代入命令群1620
STR_A変数群値代入命令群1620は、CBR_AB条件分岐命令群1610において、条件分岐先がSUC_A命令群1430と判定されるように、変数に値を代入する命令群である。すなわち、この命令群が実行されるときは、PRE_A命令群1410が実行された後にA命令群1420が実行され、さらにその後にCBR_AB条件分岐命令群1610が実行されるときであるので、STR_A変数群値代入命令群1620は、その旨を示す情報を変数の値として残している。なお、この変数を、以下ではG_VAL_AB変数群と呼ぶ。なお、G_VAL_AB変数群は1つの変数である必要はなく、複数の変数の集合であってもよい。また、プログラム中に明示的に変数として現れるもの以外のものであってもよく、例えばスタックの一番上に積まれている値などであってもよい。すなわち、判定の手掛かりが残せるような処理を行う命令群であれば、どのような命令群であっても良い。このG_VAL_AB変数群は、CBR_AB条件分岐命令群1610がどの命令に分岐すべきかを決定する際に用いられる。図20に示した具体例ではG_VAL_AB変数群は変数「var_ab0」である。
図20に示した具体例では、STR_A変数群値代入命令群1620は、CBR_AB条件分岐命令群1610のif文中の条件「var_ab0%2==0」が偽となるように「var_ab0」に値を代入する命令群「var_ab0=1;」である。ここで、条件「var_ab0%2==0」が偽となれば、CBR_AB条件分岐命令群1610がSUC_A命令群1430に分岐することは、CBR_AB条件分岐命令群1610の説明で述べたとおりである。すなわち、改竄防止プログラム1330では、PRE_A命令群1410の後にA命令群1420が行われた後には、(SUC_B命令群1450ではなく)SUC_A命令群1430が行われるようにするために、STR_A変数群値代入命令群1620を用いている。
(2.5)STR_B変数群値代入命令群1630
STR_B変数群値代入命令群1630は、上述のCBR_AB条件分岐命令群1610において、条件分岐先がSUC_B命令群1450と判定されるように、G_VAL_AB変数群に含まれる変数に値を代入する命令群である。すなわち、この命令群が実行されるときは、B命令群1440が実行された後にA命令群1420が実行され、さらにその後にCBR_AB条件分岐命令群1610が実行されるときであるので、STR_B変数群値代入命令群1630は、その旨を示す情報を変数の値として残している。ここで、STR_B変数群値代入命令群1630が、複数の変数を用いたり、変数以外のものを利用する構成であってもよいことは、STR_A変数群値代入命令群1620と同様である。
図20に示した具体的例では、CBR_AB条件分岐命令群1610のif文中の条件「var_ab0%2==0」が真となるように「var_ab0」に値を代入する命令群「var_ab0=8;」がSTR_B変数群値代入命令群1630である。ここで、条件「var_ab0%2==0」が真となれば、CBR_AB条件分岐命令群1610中のif文の判定結果が真となって「goto SUC_B_;」が実行されるため、復帰命令群1650への分岐処理が実行される。すなわち、改竄防止プログラム1330では、B命令群1440、退避命令群1640、A命令群1420の順に各命令群の処理が行われた後には、(SUC_A命令群1430ではなく)復帰命令群1650が行われるようにするために、STR_B変数群値代入命令群1630を用いている。なお、復帰命令群1650がない場合には、STR_B変数群値代入命令群1630は、B命令群1440が実行された後にA命令群1420が実行され、さらにその後にSUC_B命令群1450が実行されるようにするために、変数の値を設定する命令群である。
(2.6)BR_B分岐命令群1660
図20中のBR_B分岐命令群1660は、B命令群1440からA命令群1420へ分岐する命令群である。ただし、改竄防止プログラム1330が退避命令群1640を含む場合は、A命令群1420へ分岐する前に途中結果を退避する必要があるので、退避命令群1640による処理が終わった後でA命令群1420へ分岐する命令群となる。
図20に例示した改竄防止プログラム1330は退避命令群1640を含むので、BR_B分岐命令群1660は、退避命令群1640による処理が終わった後でA命令群1420へ分岐する分岐命令群「goto A;」として表される。
(2.7)改竄防止プログラム1330の処理の流れ
本実施の形態における改竄防止プログラム1330の処理の流れを、入力プログラム1310の処理の流れと比較して説明するため、先に、入力プログラム1310の処理の流れについて説明する。
図21は、入力プログラム1310の処理の流れを示す図である。
入力プログラム1310は、図21に示すように、分岐を含まない単純なものである。実行処理装置1340は、入力プログラム1310を実行した場合、まず、PRE_A命令群1410を実行し(ステップS200)、A命令群1420を実行する(ステップS202)。さらに、実行処理装置1340は、SUC_A命令群1430を実行し(ステップS204)、B命令群1440を実行し(ステップS206)、SUC_B命令群1450を実行する(ステップS208)。
図22は、改竄防止プログラム1330の処理の流れを示す図である。
一方、改竄防止プログラム1330は、図22に示すように、分岐と合流を含む。実行処理装置1340は、改竄防止プログラム1330を実行した場合、まず、PRE_A命令群1410を実行し(ステップS300)、次に、STR_A変数群値代入命令群1620を実行し(ステップS302)、その後、A命令群1420を実行する(ステップS304)。ここで、実行処理装置1340は、ステップS302でSTR_A変数群値代入命令群1620を実行することで、変数「var_ab0」に1を代入する。
そして、実行処理装置1340は、CBR_AB条件分岐命令群1610を実行することにより、変数「var_ab0」が「var_ab0%2==0」を満たすか否かを判別する(ステップS306)。このとき、実行処理装置1340は、ステップS302で変数「var_ab0」に1が代入されているため、変数「var_ab0」が「var_ab0%2==0」を満たさないと判別する(ステップS306の「var_ab0%2==1」)。
その結果、実行処理装置1340は、SUC_A命令群1430を実行し(ステップS308)、次に、B命令群1440を実行し(ステップS310)、さらに、STR_B変数群値代入命令群1630を実行する(ステップS312)。ここで、実行処理装置1340は、ステップS312でSTR_B変数群値代入命令群1630を実行するときには、変数「var_ab0」に8を代入する。
さらに、実行処理装置1340は、退避命令群1640を実行し(ステップS314)、その後、BR_B分岐命令群1660を実行すると(ステップS316)、再び、A命令群1420を実行する(ステップS304)。
そして、実行処理装置1340は、もう一度、CBR_AB条件分岐命令群1610を実行することにより、変数「var_ab0」が「var_ab0%2==0」を満たすか否かを判別する(ステップS306)。このとき、実行処理装置1340は、ステップS312で変数「var_ab0」に8が代入されているため、変数「var_ab0」が「var_ab0%2==0」を満たすと判別する(ステップS306の「var_ab0%2==0」)。
その結果、実行処理装置1340は、復帰命令群1650を実行し(ステップS318)、次に、SUC_B命令群1450を実行する(ステップS320)。
このように、A命令群1420は、STR_A変数群値代入命令群1620の後と、BR_B分岐命令群1660の後とで実行される。つまり、実行処理装置1340が入力プログラム1310を実行した場合には、A命令群1420は1回しか実行されないのに対し、実行処理装置1340が改竄防止プログラム1330を実行した場合には、A命令群1420は2回実行されることとなる。したがって、改竄防止プログラム1330を実行処理装置1340で実行させた場合と、難読化前のプログラムである入力プログラム1310を実行処理装置1340で実行させた場合とでは、各命令群が異なる順序で実行される。
(2.8)改竄防止プログラム1330の効果
不正解析者が改竄防止プログラム1330を解析した際のそのプログラムの実行順序と、入力プログラム1310の実行順序とは、図21および図22に示したように異なるため、不正解析者は改竄防止プログラム1330の実行順序を解析しても、難読化前の入力プログラムの実行順序を知ることが難しく、解析が困難になる。また、改竄防止プログラム1330の実行順序は、入力プログラム1310の実行順序よりも複雑になるので、解析や改竄を困難にすることが出来る。その結果、保護対象コードであるA命令群1420を確実に保護することができる。
また、不正解析者が、難読化のための冗長な処理を見つけ出して読み飛ばす、あるいは、削除するといった攻撃を取ることが考えられる。ここで、本実施の形態では、BR_B分岐命令群1660の後のA命令群1420の実行が冗長な処理に当たるので、不正解析者がA命令群1420が冗長であることをつきとめ、削除しようとすることが考えられる。しかし、本実施の形態の改竄防止プログラム1330では、A命令群1420は単なる冗長な処理ではなく、難読化前のプログラム(入力プログラム1310)で必要であった処理である。したがって、A命令群1420を削除すると、難読化前のプログラムにおいてA命令群1420を使っていた処理が実行されなくなる。その結果、改竄防止プログラム1330と入力プログラム1310との全体の処理結果が合わなくなる。つまり、不正解析者は必要な処理まで削除してしまうこととなる。よって、このような不正解析者の攻撃による改竄防止プログラム1330の改竄は困難になる。
また、不正解析者がプログラムの特定の部分の制御構造を知っていて、その知識を用いてその特定の部分を見つけ出す攻撃を行うことも考えられる(このような制御構造の例としては、公知の暗号化アルゴリズムなどが考えられる)。また、難読化対象(入力プログラム1310)が秘密情報を用いるプログラムであって、不正解析者がプログラムに含まれる特定の演算を知っていて、その秘密情報を見つけるために、その演算を見つけ出す攻撃も考えられる。しかし、本実施の形態における改竄防止プログラム1330の制御構造は不正解析者が知っている制御構造と異なるものとなっているので、不正解析者が知っている制御構造に基づく、改竄防止プログラム1330の制御構造に対する解析が困難になる。
(3)改竄防止処理生成装置1320の構成
続いて、改竄防止処理生成装置1320の説明を行う。改竄防止処理生成装置1320は、入力プログラム1310を難読化し改竄防止プログラム1330を生成する装置である。
図23は、改竄防止処理生成装置1320の構成を示す図である。
改竄防止処理生成装置1320は、入力部2010と、入力プログラム保持部2020と、被代入変数解析部2030と、被代入変数情報保持部2040と、被退避変数解析部2050と、被退避変数情報保持部2060と、退避命令群生成部2070と、退避命令群保持部2080と、復帰命令群生成部2090と、復帰命令群保持部2091と、条件分岐命令群生成部2092と、分岐条件保持部2093と、条件分岐命令群保持部2094と、変数群値代入命令群生成部2095と、変数群値代入命令群保持部2096と、分岐命令群生成部2097と、分岐命令群保持部2098と、改竄防止プログラム生成部2099と、改竄防止プログラム出力部2100とを備えている。
入力部2010は、SUC_A命令群1430を分岐先とするA命令群1420と、A命令群1420を分岐先とするPRE_A命令群1410と、SUC_B命令群1450を分岐先とするB命令群1440とを含む入力プログラム1310(例えば図18に示すプログラム)を受け付ける。
入力プログラム保持部2020は、入力部2010が受け付けた入力プログラム1310を保持する。
被代入変数解析部2030は、入力プログラム保持部2020が保持する入力プログラム1310中のA命令群1420に含まれる変数であって、値の代入がなされる変数(被代入変数)を解析(特定)する。
被代入変数情報保持部2040は、被代入変数解析部2030による解析によって得られた被代入変数の変数名等の情報を保持する。
被退避変数解析部2050は、SUC_B命令群1450に含まれる変数であって、値の参照がなされる変数(被参照変数)を解析(特定)する。さらに、被退避変数解析部2050は、被代入変数情報保持部2040が保持する被代入変数であり、かつ、被参照変数でもある変数(以下では、被退避変数と呼ぶ)を特定する。
被退避変数情報保持部2060は、被退避変数解析部2050で特定された被退避変数の変数名等の情報を保持する。
退避命令群生成部2070は、被退避変数が保持する値を退避用変数(本実施の形態では、変数「var_save0」など)に退避する命令群である退避命令群1640を生成する。
退避命令群保持部2080は、退避命令群生成部2070が生成した退避命令群1640を保持する。
復帰命令群生成部2090は、退避用変数に退避した値を被退避変数に戻すための命令群である復帰命令群1650を生成する。
復帰命令群保持部2091は、復帰命令群生成部2090が生成した復帰命令群1650を保持する。
条件分岐命令群生成部2092は、SUC_A命令群1430とSUC_B命令群1450とを条件分岐先に含み、分岐先決定用の変数であるG_VAL_AB変数群(本実施の形態では、変数「var_ab0」など)の値に基づき分岐先を決定するCBR_AB条件分岐命令群1610を生成する。
分岐条件保持部2093は、CBR_AB条件分岐命令群1610がSUC_A命令群1430を分岐先とする条件を満たすために分岐先決定用変数が取るべき値の集合、および、SUC_B命令群1450を分岐先とする条件を満たすために分岐先決定用変数が取るべき値の集合を保持する。
条件分岐命令群保持部2094は、条件分岐命令群生成部2092が生成したCBR_AB条件分岐命令群1610を保持する。
変数群値代入命令群生成部2095は、G_VAL_AB変数群(本実施の形態では、変数「var_ab0」など)に、SUC_A命令群1430を分岐先とする条件を満たす値を代入する命令群の生成、および、SUC_B命令群1450を分岐先とする条件を満たす値を代入する命令群の生成を行う。
変数群値代入命令群保持部2096は、変数群値代入命令群生成部2095が生成した命令群を保持する。
分岐命令群生成部2097は、B命令群1440の後にA命令群1420が実行されるように制御するBR_B分岐命令群1660を生成する。
分岐命令群保持部2098は、分岐命令群生成部2097が生成したBR_B分岐命令群1660を保持する。
改竄防止プログラム生成部2099は、入力プログラム保持部2020が保持する入力プログラム1310および、各命令群保持部が保持する命令群を用いて改竄防止プログラム1330を生成する。
改竄防止プログラム出力部2100は、改竄防止プログラム生成部2099が生成した改竄防止プログラム1330を記録媒体1350に記録する。
以下、各構成要素の動作についてより詳細に説明する。また、具体例として、図18の入力プログラム1310が改竄防止処理生成装置1320に入力された場合の動作を説明する。
(3.1)入力部2010
入力部2010は、入力プログラム1310を受け付ける。入力プログラム1310は、入力プログラム1310の構成で述べたように、A命令群1420、PRE_A命令群1410、SUC_A命令群1430、B命令群1440、およびSUC_B命令群1450を含む。入力部2010は、さらに、入力プログラム1310のうち、いずれの部分が、A命令群1420、PRE_A命令群1410、SUC_A命令群1430、B命令群1440、またはSUC_B命令群1450であるかの指定を受け付ける。
(3.2)入力プログラム保持部2020
入力プログラム保持部2020は、命令群を記憶する領域を備えている。入力プログラム保持部2020は、入力部2010が受け付けた入力プログラム1310を保持する。
(3.3)被代入変数解析部2030
被代入変数解析部2030は、入力プログラム保持部2020が保持する入力プログラム1310中のA命令群1420において、なんらかの処理結果が格納される格納先を解析(特定)する。
具体的には、例えば、A命令群1420が変数の値を代入する処理を含むのであれば、被代入変数解析部2030は、変数の変数名や型を解析(特定)する。また、例えば、A命令群1420がスタックポインタからの相対値を指定してスタックに値を格納する処理を含むのであれば、被代入変数解析部2030は、そのスタックポインタや、スタックのサイズやスタックポインタからの相対値を解析(特定)する。また、例えば、A命令群1420がアドレス変数で指定した位置に値を格納する処理を含むのであれば、被代入変数解析部2030は、その格納されるアドレスを解析(特定)する。以降の説明では、これらのA命令群1420のなんらかの処理結果が格納される格納先の情報を総称して、被代入変数情報と呼ぶ。なお、本実施の形態では、A命令群1420中に直接的に現れる変数以外であっても、なんらかの処理結果が格納される格納先の情報を被代入変数情報と呼ぶ。例えば、スタック等がOSの機能として実現されている場合、スタックポインタやスタックのサイズはA命令群1420中には明示的には表れないことがあるが、このような値も被代入変数情報である。
次に、被代入変数解析部2030は、解析した被代入変数情報を被代入変数情報保持部2040に格納する。例えば、図18のA命令群1420を解析の対象とする場合、被代入変数解析部2030は、値の代入が行われる変数「var_org0」と変数「var_org2」の変数名と型「int var_org0」と「int var_org2」を特定し、それぞれを被代入変数情報保持部2040に格納する。
なお、本実施の形態では、入力プログラム1310におけるA命令群1420の範囲は、ラベル「A:」から始まり、次の他のラベルが現れる前までとする。以降の説明における、PRE_A命令群1410、SUC_A命令群1430、B命令群1440、SUC_B命令群1450の範囲も同様に、各命令群は何らかのラベルから次のラベルが現れる前までの範囲であるものとする。
このラベルは、入力部2010を介してユーザからの指定により付されるものとしてもよいし、入力プログラム1310に元から付されているラベルを利用しても良い。
(3.4)被代入変数情報保持部2040
被代入変数情報保持部2040は、被代入変数解析部2030が解析したA命令群1420の被代入変数情報を記憶する。被代入変数が複数ある場合には、各被代入変数についての被代入変数情報を記憶する。
本実施の形態では、図18のA命令群1420に対して被代入変数解析部2030による解析が行われた場合、被代入変数情報保持部2040は、各被代入変数の型と変数名である「int var_org0」と「int var_org2」とを記憶する。
(3.5)被退避変数解析部2050
被退避変数解析部2050は、SUC_B命令群1450以降の命令群の処理結果に影響を与える変数であって、かつ、A処理命令群で値が変更される変数を解析(特定)する。なお、被退避変数解析部2050の解析対象は、被代入変数解析部2030の解析対象と同様、A命令群1420中に直接的に現れる変数以外のものも含む。このような変数を解析してその変数の値を退避しておかなくては、A処理命令群がSUC_B命令群1450の前に実行されることにより、改竄防止プログラム1330の処理結果が入力プログラム1310とは異なるものとなってしまうこととなることは上述のとおりである。
まず、被退避変数解析部2050は、入力プログラム保持部2020が保持する入力プログラム1310中のSUC_B命令群1450、および、SUC_B命令群1450以降を実行する際に必要となる変数を特定する。ここで、実行する際に必要となる変数とは、B命令群1440の実行が終了した時点における変数の値がSUC_B命令群1450以降の命令で使用される変数、すなわち、SUC_B命令群1450以降の処理結果に影響を与える変数のことを示す。より具体的には、B命令群1440までに値が代入され、SUC_B命令群1450以降の命令に含まれる代入式の右辺に表れる変数がこれに当たる。
次に、特定された変数のうち被代入変数情報保持部2040に保持されている変数があれば、被退避変数解析部2050は、その変数を被退避変数とし、被退避変数の変数名等の情報を被退避変数情報保持部2060に格納する。すなわち、被退避変数解析部2050は、A命令群1420で値が代入され、SUC_B命令群1450以降の命令群で必要となる変数を、退避変数として抽出する。
より具体的には、SUC_B命令群1450が変数を参照する処理を含む命令群であれば、被退避変数解析部2050は、その変数の変数名や型を解析(特定)する。また、例えば、SUC_B命令群1450がスタックの値を参照する処理を含む命令群であれば、被退避変数解析部2050は、参照するスタックのサイズを解析(特定)する。また、例えば、SUC_B命令群1450がアドレス変数で指定した位置に格納された値を参照する処理を含むのであれば、被退避変数解析部2050は、そのアドレス変数や格納する値の型を解析(特定)する。以下の説明では、これらのSUC_B命令群1450を実行する際に必要なパラメータや変数に関する情報を総称して被参照変数情報と呼び、パラメータや変数自体のことを被参照変数と呼ぶ。
次に、その被参照変数のうち、被代入変数情報保持部2040に保持されている変数があれば、被退避変数解析部2050は、その変数を被退避変数とし、被退避変数の変数名等の情報を被退避変数情報保持部2060に格納する。
例えば、図18のSUC_B命令群1450の場合、「var_org1=var_org1+var_org2;var_org1 =var_org1*123;」において、変数「var_org1」および変数「var_org2」の値が参照されている。よって、被退避変数解析部2050は、変数「var_org1」および変数「var_org2」を被参照変数とし、「int var_org1」および「int var_org2」を被参照変数情報とする。このうち、「int var_org1」は被代入変数情報保持部2040に保持されておらず、「int var_org2」は保持されている。したがって、保持されている方の「int var_org2」の変数「var_org2」は、SUC_B命令群1450の処理結果に影響を与える変数であって、かつ、A命令群1420で値が変更される変数である。よって、変数「var_org2」の値を、A命令群1420の処理を行う前に退避し、SUC_B命令群1450の処理を行う前にその値を戻さなければならない。被退避変数解析部2050は、「int var_org2」を被退避変数情報とし、被退避変数情報保持部2060に格納する。
なお、SUC_B命令群1450の処理結果に影響を与える変数であって、かつ、A命令群1420で値が変更される変数が抽出されるのであれば、被退避変数解析部2050が行う処理は上記のものに限らない。例えば、被退避変数解析部2050は、被代入変数情報保持部2040に保持されている変数を取り出し、これがSUC_B命令群1450以降の命令に含まれているかを検索しても良い。また、被退避変数解析部2050は、被代入変数情報保持部2040を用いずに、入力プログラム保持部2020が保持する入力プログラム1310から、A命令群1420によって値が変更される変数を直接取り出してもよい。
(3.6)被退避変数情報保持部2060
被退避変数情報保持部2060は、被退避変数情報を記憶する領域を備えている。
被退避変数情報保持部2060は、被退避変数解析部2050が解析した被退避変数情報を記憶する。なお、被退避変数が複数ある場合には、被退避変数情報保持部2060は、各被退避変数についての被退避変数情報を記憶する。
具体的には、図18のSUC_B命令群1450の場合、被退避変数情報保持部2060は、被退避変数の変数名と型「int var_org2」を記憶する。
(3.7)退避命令群生成部2070
退避命令群生成部2070は、被退避変数情報の値を退避させる退避命令群1640を生成して退避命令群保持部2080に格納する。より詳細には、以下の処理を行う。
A)退避命令群生成部2070は、被退避変数をどう退避するかを決める。具体的には、どの変数に退避するかなどを決定する。本実施の形態では、退避命令群生成部2070は、被退避変数の退避先として新たな変数を作成して、その変数に被退避変数の値を退避させる。
B)退避命令群生成部2070は、決定した退避のさせ方に従って、被退避変数の値を退避させる命令群である退避命令群1640を生成する。
C)退避命令群生成部2070は、生成した退避命令群1640を退避命令群保持部2080に格納する。
以下、図18の入力プログラム1310が改竄防止処理生成装置1320に入力された場合における、退避命令群生成部2070の具体的な動作の例を説明する。
A)退避命令群生成部2070は、被退避変数情報保持部2060より被退避変数情報を取得し、被退避変数の個数を調べる。ここでは、被退避変数は「int var_org2」のみであるので、1つである。退避命令群生成部2070は、判定した個数分の退避用変数を新たに作成し、作成した退避用変数「int var_save0」を退避に用いる変数に決める。
B)退避命令群生成部2070は、被退避変数の値を退避用変数に退避する退避命令群1640を生成する。ここでは、退避命令群生成部2070は、命令「var_save0=var_org2;」を生成する。なお、被退避変数が複数ある場合は、退避命令群生成部2070は、それぞれの被退避変数について、退避命令群を生成する。また、退避命令群として被退避変数そのものを退避させるのではなく、暗号化などの何らかの変換を施して退避してもよい。本実施の形態では、このような変換を施した上で退避する場合および無変換のまま退避する場合の両方を含めて、変換と呼ぶ。
C)退避命令群生成部2070は、生成した退避命令群1640を退避命令群保持部2080に格納する。ここでは、「var_save0=var_org2;」が格納される。
(3.8)退避命令群保持部2080
退避命令群保持部2080は、命令群を記憶する領域を備える。退避命令群保持部2080は、退避命令群生成部2070が生成した退避命令群1640を記憶領域に記憶する。
図18に示した入力プログラム1310が改竄防止処理生成装置1320に入力された場合、退避命令群生成部2070が生成した退避命令群1640が「var_save0=var_org2;」となるので、退避命令群保持部2080は、「var_save0=var_org2;」を記憶する。
(3.9)復帰命令群生成部2090
復帰命令群生成部2090は、退避用変数に退避した値を被退避変数に戻すための命令群である復帰命令群1650を生成する。より詳細には、以下の処理を行う。
A)復帰命令群生成部2090は、退避命令群保持部2080が保持する退避命令群1640を取得する。
B)復帰命令群生成部2090は、取得した退避命令群1640が行う変換の逆変換を行う命令群を生成してその命令群を復帰命令群1650とする。
C)復帰命令群生成部2090は、復帰命令群1650を復帰命令群保持部2091に格納する。
以下、図18の入力プログラム1310が改竄防止処理生成装置1320に入力された場合における、復帰命令群生成部2090の具体的な動作の例を説明する。
A)復帰命令群生成部2090は、退避命令群保持部2080が保持する退避命令群1640「var_save0=var_org2;」を取得する。
B)復帰命令群生成部2090は、「var_save0=var_org2;」の逆変換である「var_org2=var_save0;」を生成し、復帰命令群1650とする。
C)復帰命令群生成部2090は、復帰命令群1650「var_org2=var_save0;」を復帰命令群保持部2091に格納する。
(3.10)復帰命令群保持部2091
復帰命令群保持部2091は、命令群を記憶する領域を備える。復帰命令群保持部2091は、復帰命令群生成部2090が生成した復帰命令群1650を記憶領域に記憶する。
上記の具体例では、復帰命令群生成部2090が生成した復帰命令群1650が「var_org2=var_save0;」であるので、復帰命令群保持部2091は、復帰命令群生成部2090で生成された「var_org2=var_save0;」を記憶する。
(3.11)条件分岐命令群生成部2092
条件分岐命令群生成部2092は、SUC_A命令群1430とSUC_B命令群1450とを条件分岐先に含み、分岐先決定用のG_VAL_AB変数(変数「var_ab0」)の値に基づき分岐先を決定するCBR_AB条件分岐命令群1610を生成する。なお、復帰命令群1650がある場合には、条件分岐命令群生成部2092は、SUC_B命令群1450に替えて復帰命令群1650を分岐先として含むCBR_AB条件分岐命令群1610を生成する。
具体的には、以下の処理を行う。
A)条件分岐命令群生成部2092は、分岐先決定用の変数を決定する。本実施の形態では、新しく変数を生成し、その変数を分岐先決定用の変数とする。
B)条件分岐命令群生成部2092は、分岐先決定用の変数の値がどのような値の時にSUC_A命令群1430を条件分岐先とするかを決定する。また、条件分岐命令群生成部2092は、分岐先決定用の変数の値がどのような値の時にSUC_B命令群1450を条件分岐先とするかを決定する。ここで決定する条件の具体例としては、例えば、変数の値が所定の値と一致する、所定の値よりも大きい、変数の値に何らかの変換を施した値が所定の値と一致するなどである。
C)条件分岐命令群生成部2092は、上記のB)で決めた条件分岐先がSUC_A命令群1430となる分岐先決定用の変数の値の集合を分岐条件保持部2093に格納する。また、条件分岐命令群生成部2092は、B)で決めた条件分岐先がSUC_B命令群1450となる分岐先決定用の変数の値の集合を分岐条件保持部2093に格納する。
D)復帰命令群保持部2091が復帰命令群1650を保持する場合は、条件分岐命令群生成部2092は、SUC_A命令群1430と復帰命令群1650を条件分岐先とし、保持しない場合は、SUC_A命令群1430とSUC_B命令群1450を条件分岐先とするCBR_AB条件分岐命令群1610を生成する。
E)条件分岐命令群生成部2092は、生成したCBR_AB条件分岐命令群1610を条件分岐命令群保持部2094に格納する。
以下、図18の入力プログラム1310が改竄防止処理生成装置1320に入力された場合における、条件分岐命令群生成部2092の具体的な動作の例を説明する。
A)条件分岐命令群生成部2092は、入力プログラム1310に含まれない変数を新たに用意し、分岐先決定用のG_VAL_AB変数とする。ここでは、分岐先決定用の変数は「var_ab0」とする。
B)条件分岐命令群生成部2092は、分岐先決定用の変数が2の倍数でない時、すなわち、「var_ab0%2 ==1」の時、SUC_A命令群1430を分岐先とし、2の倍数の時、すなわち、「var_ab0%2 ==0」の時、SUC_B命令群1450を分岐先とすることを決定する。
なお、ここでは、分岐先決定用の変数がどのような値の時にSUC_A命令群1430を分岐先にするかの一例を示したが、その決め方は他の方法であっても構わない。例えば、分岐先決定用の変数の値がランダムに選択した値の時にSUC_A命令群1430を分岐先とすると決めても構わない。
C)条件分岐命令群生成部2092は、上記のB)で決めた条件分岐先がSUC_A命令群1430となる分岐先決定用の変数の値の集合を分岐条件保持部2093に格納する。ここでは、条件分岐命令群生成部2092は、集合「var_ab0%2 ==1」、すなわち2の倍数以外の値の集合を格納する。
さらに、条件分岐命令群生成部2092は、条件分岐先がSUC_B命令群1450となる分岐先決定用の変数の値の集合を分岐条件保持部2093に格納する。ここでは、条件分岐命令群生成部2092は、集合「var_ab0%2 ==0」、すなわち2の倍数を格納する。
ここで、集合を格納するとは、集合に含まれる全ての値を格納するのであっても構わないし、「var_ab0%2 ==0」のような集合を表す式を格納するのであっても構わない。
D)条件分岐命令群生成部2092は、復帰命令群保持部2091が復帰命令群1650を保持する場合は、SUC_A命令群1430と復帰命令群1650を条件分岐先とし、保持しない場合は、SUC_A命令群1430とSUC_B命令群1450を条件分岐先とするCBR_AB条件分岐命令群1610を生成する。ここでは、復帰命令群保持部2091は復帰命令群1650を保持するので、条件分岐命令群生成部2092は、復帰命令群1650の先頭にラベル「SUC_B_」を設け、CBR_AB条件分岐命令群1610「if(var_ab0%2==0) goto SUC_B_;」を生成する。
E)条件分岐命令群生成部2092は、生成したCBR_AB条件分岐命令群1610「if(var_ab0%2==0) goto SUC_B_;」を条件分岐命令群保持部2094に格納する。
(3.12)分岐条件保持部2093
分岐条件保持部2093は、変数の値の集合を記憶する領域を少なくとも2つ備える。第一の領域は、条件分岐命令群生成部2092の分岐先がSUC_A命令群1430となる条件を満たす変数の値の集合である第一の集合を記録する。また、第二の領域は、条件分岐命令群生成部2092の分岐先がSUC_B命令群1450(もしくは復帰命令群1650)となる条件を満たす変数の値の集合である第二の集合を記憶する。ここで、集合を格納するとは、集合に含まれる全ての値を格納するのであっても構わないし、「var_ab0%2==0」のような集合を表す式を格納するのであっても構わない。
上記の具体例の場合、第一の領域は、条件分岐命令群生成部2092の分岐先がSUC_A命令群1430となる条件を満たす変数の値の集合である「var_ab0%2==1」を保持する。また、第二の領域は、条件分岐命令群生成部2092の分岐先が復帰命令群1650となる条件を満たす変数の値の集合である「var_ab0%2==0」を保持する。
(3.13)条件分岐命令群保持部2094
条件分岐命令群保持部2094は、命令群を記憶する領域を備える。条件分岐命令群保持部2094は、条件分岐命令群生成部2094が生成したCBR_AB条件分岐命令群1610を記憶領域に記憶する。
上記の具体例の場合、条件分岐命令群保持部2094は、条件分岐命令群生成部2092が生成したCBR_AB条件分岐命令群1610「if(var_ab0%2==0) goto SUC_B_;」を記憶する。
(3.14)変数群値代入命令群生成部2095
変数群値代入命令群生成部2095は、STR_A変数群値代入命令群1620と、STR_B変数群値代入命令群1630を生成する。具体的には、以下の処理を行う。
A)変数群値代入命令群生成部2095は、分岐条件保持部2093が保持する第一の集合および第二の集合を取得する。
B)変数群値代入命令群生成部2095は、分岐先決定用の変数に、第一の集合に含まれる値を代入する命令群を生成し、STR_A変数群値代入命令群1620とする。また、変数群値代入命令群生成部2095は、分岐先決定用の変数に、第二の集合に含まれる値を代入する命令群を生成し、STR_B変数群値代入命令群1630とする。なお、第一の集合または第二の集合に複数の値が含まれる場合、変数群値代入命令群生成部2095は、いずれかの値を選択して代入する値とする。この選択方法はランダムであってもよいし、何らかの基準に従って選択してもよい。
C)変数群値代入命令群生成部2095は、生成した命令群を変数群値代入命令群保持部2096に格納する。
以下、図18の入力プログラム1310が改竄防止処理生成装置1320に入力された場合における、変数群値代入命令群生成部2095の具体的な動作の例を説明する。
A)変数群値代入命令群生成部2095は、分岐条件保持部2093が保持する第一の集合および第二の集合を取得する。これらは、それぞれ「var_ab0%2==1」または「var_ab0%2==0」である。
B)変数群値代入命令群生成部2095は、分岐先決定用の変数を、第一の集合に含まれる値とする命令群を生成し、STR_A変数群値代入命令群1620とする。ここでは、分岐先決定用の変数は「var_ab0」であり、例えば、1が第一の集合に含まれる値である。よって、変数群値代入命令群生成部2095は、「var_ab0=1;」をSTR_A変数群値代入命令群1620とする。同様に、変数群値代入命令群生成部2095は、「var_ab0=8;」をSTR_B変数群値代入命令群1630とする。
C)変数群値代入命令群生成部2095は、生成したSTR_A変数群値代入命令群1620とSTR_B変数群値代入命令群1630とを変数群値代入命令群保持部2096に格納する。
(3.15)変数群値代入命令群保持部2096
変数群値代入命令群保持部2096は、命令群を記憶する領域を備える。変数群値代入命令群保持部2096は、変数群値代入命令群生成部2095が生成したSTR_A変数群値代入命令群1620とSTR_B変数群値代入命令群1630とを記憶領域に記憶する。
上記の具体例の場合、変数群値代入命令群保持部2096は、変数群値代入命令群生成部2095が生成したSTR_A変数群値代入命令群1620とSTR_B変数群値代入命令群1630とである、「var_ab0=1;」と「var_ab0=8;」とを保持する。
(3.16)分岐命令群生成部2097
分岐命令群生成部2097は、B命令群1440からA命令群1420に分岐するためのBR_B分岐命令群1660を生成する。
具体的には、図18の入力プログラム1310が処理対象である場合、分岐命令群生成部2097は、A命令群1420へ分岐するBR_B分岐命令群1660である「goto A;」を生成する。
(3.17)分岐命令群保持部2098
分岐命令群保持部2098は、命令群を記憶する領域を備える。分岐命令群保持部2098は、分岐命令群生成部2097が生成したBR_B分岐命令群1660を記憶領域に記憶する。
例えば、上記の具体例の場合、分岐命令群保持部2098は、分岐命令群生成部2097が生成したBR_B分岐命令群1660である「goto A;」を保持する。
(3.18)改竄防止プログラム生成部2099
改竄防止プログラム生成部2099は、入力プログラム保持部2020が保持する入力プログラム1310および、各命令群保持部が保持する命令群を用いて改竄防止プログラム1330を生成する。具体的には、改竄防止プログラム生成部2099は、入力プログラム1310に対して、各命令群保持部が保持する命令群を以下の位置に挿入または配置することにより、改竄防止プログラム1330を生成する。
A)改竄防止プログラム生成部2099は、PRE_A命令群1410中のいずれかの位置にSTR_A変数群値代入命令群1620を挿入する。
B)改竄防止プログラム生成部2099は、A命令群1420の最後にCBR_AB条件分岐命令群1610を配置する。
C)改竄防止プログラム生成部2099は、B命令群1440中のいずれかの位置にSTR_B変数群値代入命令群1630を挿入する。
D)改竄防止プログラム生成部2099は、B命令群1440の最後に退避命令群1640を、さらにその後ろに、BR_B分岐命令群1660を配置する。
E)改竄防止プログラム生成部2099は、SUC_B命令群1450の直前に復帰命令群1650を配置する。
具体的な例としては、改竄防止プログラム生成部2099は、図18の入力プログラム1310に対して、生成して保持されている各命令群を挿入すると、図20の改竄防止プログラム1330を生成する。
なお、入力プログラム1310自体に対して、すでに他の難読化手法による変換などが施されている場合、A命令群1420やB命令群1440の最後に正常系での実行時には実行されないダミー命令等が含まれている場合がある。この場合は、CBR_AB条件分岐命令群1610や退避命令群1640は、必ずしも各命令群の最後でなくとも良い。すなわち、正常系で実行される命令のうちでの最後の位置に配置すれば良い。
(3.19)改竄防止プログラム出力部2100
改竄防止プログラム出力部2100は、改竄防止プログラム生成部2099が生成した改竄防止プログラム1330を受け取って格納する。また、改竄防止プログラム出力部2100は、改竄防止プログラム1330を記録媒体1350に記録する。
なお、本実施の形態では、分岐先決定用のG_VAL_AB変数(変数「var_ab0」)が追加変数に相当し、条件分岐命令群生成部2092が変数生成手段として構成されている。また、STR_A変数群値代入命令群1620が第一条件値代入命令に相当し、STR_B変数群値代入命令群1630が第二条件値代入命令に相当し、変数群値代入命令群生成部2095が条件値代入命令生成手段として構成されている。
(3.20)改竄防止処理生成装置1320の処理の流れ
図24は、改竄防止処理生成装置1320の動作を示すフローチャートである。図24を用いて、入力プログラム1310を改竄防止プログラム1330に変換する処理、つまり難読化の処理の流れを説明する。
まず、改竄防止処理生成装置1320の入力部2010は、入力プログラム1310と、入力プログラム1310におけるA命令群1420、PRE_A命令群1410、SUC_A命令群1430、B命令群1440、およびSUC_B命令群1450の位置の指定とを受け付け、入力プログラム保持部2020に格納する(ステップS400)。
被代入変数解析部2030は、入力プログラム保持部2020が保持するA命令群1420の被代入変数情報を解析し、被代入変数情報保持部2040に格納する(ステップS402)。
被退避変数解析部2050は、入力プログラム保持部2020が保持する入力プログラム1310中のSUC_B命令群1450、および、SUC_B命令群1450以降を実行する際に必要となる変数を特定する。そして、被退避変数解析部2050は、特定された変数のうち被代入変数情報保持部2040に保持されている変数を被退避変数とし、被退避変数情報保持部2060に格納する(ステップS404)。
退避命令群生成部2070は、退避命令群1640を生成して退避命令群保持部2080に格納する(ステップS406)。
復帰命令群生成部2090は、復帰命令群1650を生成して復帰命令群保持部2091に格納する(ステップS408)。なお、ステップS404で被退避変数が1つも見つからなかった場合は、退避命令群1640および復帰命令群1650を生成する必要がないので、ステップS406およびステップS408の処理は行われない。
条件分岐命令群生成部2092は、CBR_AB条件分岐命令群1610を生成し、条件分岐命令群保持部2094に格納する(ステップS410)。
変数群値代入命令群生成部2095は、STR_B変数群値代入命令群1630およびSTR_A変数群値代入命令群1620を生成し、変数群値代入命令群保持部2096に格納する(ステップS412)。
分岐命令群生成部2097は、BR_B分岐命令群1660を生成し、分岐命令群保持部2098に格納する(ステップS414)。
改竄防止プログラム生成部2099は、改竄防止プログラム1330を生成し、改竄防止プログラム出力部2100に格納する(ステップS416)。また、改竄防止プログラム出力部2100は、改竄防止プログラムを記録媒体1350に記録する。
(3.21)改竄防止処理生成装置1320の効果
改竄防止処理生成装置1320は、入力として与えられた入力プログラム1310を、入力プログラム1310と同一の結果が得られる改竄防止プログラム1330に変換することが出来る。ここで、不正解析者が改竄防止プログラム1330を実際に動かして解析を行ったとしても、入力プログラム1310の命令群の実行順序や制御構造を知ることが困難であることは、改竄防止プログラム1330の説明にて述べたとおりである。
また、改竄防止処理生成装置1320は、入力プログラム1310をより複雑な制御構造を持つ改竄防止プログラム1330に難読化することが出来る。
(その他の変形例)
なお、本発明を上記実施の形態に基づいて説明してきたが、本発明は、上記の実施の形態に限定されないのはもちろんである。以下のような場合も本発明に含まれる。
(1)実施の形態1およびその変形例ならびに実施の形態2,3では、C言語の記法に合わせるため、難読化の処理中に変数宣言等の命令を追加していたが、これらの命令を追加するタイミングは、上記で述べたものに限られない。難読化の処理が完了した後、最後にこれらの命令を追加するとしても良いし、他のタイミングで追加するとしても良い。また、難読化後の記述言語によってはこの処理が不要な場合もある。
(2)実施の形態1およびその変形例ならびに実施の形態2では、実行処理装置と改竄防止処理生成装置とは別装置としていたが、これに限られるものではない。例えば、実行処理装置に改竄防止処理生成装置と同等の機能を持った処理生成部を含ませ、プログラムの実行時には、その処理生成部による難読化を行った上で、実行してもよい。この構成によると、実行されるプログラムは本発明による難読化が行われたプログラムとなるため、実施の形態1および2と同様に不正な改竄および解析を防止することができる。なお、この場合、実行処理装置内でのプログラムの格納場所を耐タンパ化等により保護することにより、オリジナルのプログラムを保護しておくことが望ましいことは言うまでもない。
さらに、実行処理装置は、プログラム配信サーバから配信されたプログラムを実行する装置であって、改竄防止処理生成装置に加え、更に復号装置を含み、暗号化されて配信されたプログラムを復号化し、さらに難読化を行った上で実行する構成であるとしてもよい。このような構成によると、プログラム配信サーバから配信されたプログラムを実行処理装置で難読化し実行することが出来る。
また、実施の形態3において、改竄防止処理生成装置と実行処理装置を別々な構成を示したが、同様にこれに限られるものではない。実施の形態1および2と同様に上記のような変形例が考えられる。
(3)実施の形態3では、被退避変数解析部2050は、被代入変数情報保持部2040の一部の変数を被退避変数としたが、被代入変数情報保持部2040が保持する変数の全てを被退避変数としても構わない。このような構成を用いた場合、退避しなくとも結果に影響が出ない変数まで余分に退避される可能性があるが、被退避変数を選ぶ処理が不要となる分、難読化の処理をより高速にすることが出来る。
また、A命令群1420に含まれる全ての変数を被退避変数としたり、入力プログラム1310に含まれる全ての変数を被退避変数とする構成であっても構わない。このような構成を用いれば、被代入変数の解析自体が不要となるので、更に、難読化の処理を高速にすることが出来る。
(4)実施の形態3では、退避命令群生成部2070は、退避命令群1640「var_save0=var_org2;」を生成するとしたが、「var_save0=var_org2+2;」などのように、逆変換可能な他の命令を生成しても構わない。その場合、復帰命令群生成部2090は、逆変換となる復帰命令群1650「var_org2 = var_save0−2;」を生成する。なお、逆変換可能な命令を生成する方法は上記にて挙げた方法に限るものではなく、公知の方法を用いても、将来的に考え出される方法を適用してもよい。
また、一つの被退避変数を、複数の段階の処理によって退避するような退避命令群を生成する構成であっても構わないし、複数の被退避変数に対して、最終的に被退避変数全てが退避されるような複数の退避命令群を生成する構成であっても構わない。すなわち、退避命令群の実行によって最終的に退避変数が退避されるのであれば、退避命令群の構成は問わない。さらに、一部の被退避命令群に対しては複数の退避命令群を生成し、他の被退避命令群については、それぞれ1つの退避命令群を生成するといったようにしても構わない。このような構成を用いれば、不正解析者が、改竄防止プログラムに含まれる命令群の中から退避命令群や復帰命令群を見つけ出すことが困難になる。
また、退避命令群生成部2070は、新たに変数を追加して退避用変数とする構成を説明したが、退避用変数は、難読化のために生成した他の変数と併用する構成であっても構わない。このような変数の例としては、他の手法による難読化において正常系での実行時には実行されないダミーの処理を付加する場合の、ダミー処理中で用いられる変数などが考えられる。また、プログラム中にあって、既に使用されていない変数などを用いても構わない。このような構成を用いれば、不正解析者が改竄防止プログラムで使われる変数のうち、いずれが難読化前からあった変数で、いずれが退避用変数であるかを解析することが困難になる。よって、改竄防止プログラムのなかのどの部分に本手法が適用されているかを知ることが困難になる。
(5)実施の形態3では、改竄防止プログラム1330に含まれる各命令群をそれぞれ独立した命令群として示したが、それらのうち複数を合成した命令群を生成しても構わない。また、実施の形態1およびその変形例ならびに実施の形態2でも、上述と同様、複数の命令群を合成した命令群を生成してもよい。例えば、実施の形態3において、復帰命令群1650である「var_org2= var_save0;」とSUC_B命令群1450である「var_org1=var_org1+var_org2;var_org1=var_org1*123;」とを生成する代わりに、それらを合成した命令群「var_org1=var_org1+var_save0;var_org1=var_org1*123;」を生成しても構わない。上記の例では、プログラムの解析により、変数「var_org2」の値が「var_save0」の値と同一であることが分かるので、SUC_B命令群1450中のvar_org2をvar_save0と置き換えている。このような構成を用いれば、不正解析者が改竄防止プログラムから復帰命令群や退避命令群を見つけ出すことが困難になる。よって、改竄防止プログラムのなかのどの部分に本手法が適用されているかを知ることが困難になる。
なお、上記の例以外にも複数の命令から前後の矛盾なく合成した新しい命令を生成する手法がコンパイラ等の分野で知られている。詳細な説明は省略するが、本手法に対して適宜それらの手法を用いてもよいことは言うまでもない。
(6)実施の形態3では、分岐命令群生成部2097は、BR_B分岐命令群1660である「goto A;」の替わりに条件分岐命令群を生成しても構わない。例えば、BR_B分岐命令群1660を「if(var_org2 >200) goto A;」としても構わない。
このような構成を用いれば、改竄防止プログラム1330の動作はvar_org2の値によって、異なる動作となる。上記の例では、改竄防止プログラム1330は、「var_org2」の値が「200」を超えるかどうかに応じて動作を変える。そのため、不正解析者に(本来は特に意味のない値である)「200」という値が何か重要な値であると思い込ませることができるので、解析作業がより困難になる。
なお、実施の形態1およびその変形例ならびに実施の形態2においても、上述と同様、分岐命令群生成部203,203bは、分岐処理命令群320,320a,320bである「plainData=decrypt(encryptedData)」の代わりに条件分岐命令群を生成してもよい。
(7)実施の形態3では、入力プログラムにおいて、A命令群1420がB命令群1440よりも前にある場合について説明したが、逆であっても構わない。
(8)実施の形態3では、入力プログラムにおいて、A命令群の分岐元ブロックがPRE_A命令群の1つのみである場合を説明したが、分岐元ブロックは複数あっても構わない。分岐元ブロックが第一PRE_A命令群、第二PRE_A命令群、…と複数ある場合には、それぞれの分岐元ブロックに対して同様にSTR_A変数群値代入命令群を追加すればよい。このような構成を用いれば、改竄防止処理生成装置1320によって制御構造の複雑なプログラムの難読化が可能となる。この場合、各命令群に追加するSTR_A変数群値代入命令群を、それぞれ、最終的な計算結果は同一となるものの途中の計算過程が異なる命令としてもよい。これにより、不正解析者に対して、STR_A変数群値代入命令群がどの命令であるかを分かりにくくすることができる。
また、実施の形態3では、A命令群一つに対して、B命令群が一つであったが、これらはどちらか、あるいは両方が複数であっても構わない。このような構成を用いれば、改竄防止プログラムのバリエーションが豊富になり、不正解析者が改竄防止プログラムから入力プログラムを想像することがより困難になる。なお、実施の形態1およびその変形例ならびに実施の形態2においても、上述と同様、矛盾が無い範囲で、同一種の命令群の数が複数あってもよい。
(9)実施の形態3では、入力プログラムにおけるB命令群の分岐先ブロックはSUC_B命令群の1つのみであったが、分岐先ブロックは複数あっても構わない。例えば、B命令群1440の分岐先ブロックが第一SUC_B命令群と第二SUC_B命令群である場合、B命令群1440の最後で「var_org2」の値によって分岐先を決定する。このように分岐先を決定するCBR_B条件分岐命令は、例えば、「if(var_org2%2==0){goto SUC_B_1;} else{goto SUC_B_2;}」として表される。この場合、CBR_AB条件分岐命令群1610は、「var_ab0%2!=0」の時は、SUC_Aを分岐先とし、「var_ab0%2==0」の時は、「var_org2」の値に基づき、分岐先を決定する。すなわち、この処理を行うCBR_AB条件分岐命令群1610を、C言語を用いて具体的に記述すると以下のようになる。
「if(var_ab0%2==0){
if(var_org2%2==0){goto SUC_B_1;}
else{goto SUC_B_2;}
}」
なお、「SUC_B_1」は第一SUC_B命令群に付されたラベルであり、「SUC_B_2」は第二SUC_B命令群に付されたラベルである。
このような、CBR_AB条件分岐命令群1610では、PRE_A命令群が実行された後にA命令群が実行された場合には、「var_ab%2!=0」となるので、CBR_AB条件分岐命令群1610の直後にあるSUC_A命令群が分岐先となる。また、B命令群が実行された後にA命令群が実行された場合には、「var_ab%2==0」となるので、上述の命令群の2行目から3行目に含まれているCBR_B条件分岐命令の条件に基づき第一SUC_B命令群または第二SUC_B命令群が条件分岐先となる。
なお、CBR_AB条件分岐命令群1610は、上記のように、実施の形態3と同様のCBR_AB条件分岐命令群1610にCBR_B条件分岐命令を含ませる構成に限らない。上記の例の場合は、「var_ab%2!=0」の時にSUC_A命令群が分岐先となり、「var_ab%2==0」かつ「var_org2%2==0」の時に第一SUC_B命令群が分岐先となり、「var_ab%2==0」かつ「var_org2%2!=0」の時に第二SUC_B命令群が分岐先となる処理となれば、CBR_AB条件分岐命令群1610は、他の構成であっても構わない。
例えば、CBR_AB条件分岐命令群1610を以下のような命令群としてもよい。
「tmp = (var_ab0%2)*2+(var_org2%2);
switch(tmp){ case 0:
case 1:
goto SUC_A;
case 2:
goto SUC_B_1;
case 3:
goto SUC_B_2; }」
また、同様に、A命令群の分岐先ブロックについても、SUC_A命令群の1つのみである場合について説明したが、分岐先ブロックは複数あっても構わない。第一SUC_A命令群と第二SUC_A命令群とが、変数「var_org2」の値が2の倍数かどうかによって分岐先となる場合における、CBR_AB条件分岐命令群1610の例を以下に示す。
「if(var_ab0%2==0){goto SUC_B;}
else{
if(var_org2%2==0){goto SUC_A_1;}
else {goto SUC_A_2;}
}」
なお、「SUC_A_1」は第一SUC_A命令群に付されたラベルであり、「SUC_A_2」は第二SUC_A命令群に付されたラベルである。
上記の例では、「var_ab0」が2で割り切れない場合、第一SUC_A命令群へ分岐するか、第二SUC_A命令群へ分岐するかの処理が行われる。なお、SUC_A命令群が複数ある場合のCBR_AB条件分岐命令群1610の作り方も上述のものに限られない。具体的な例は、SUC_B命令群が複数ある場合と同様であるので省略する。
また、SUC_A命令群およびSUC_B命令群の両方ともが複数あってもよいことはいうまでもない。
以下、このような構成を用いた場合の効果について述べる。
不正解析者による攻撃の例として、プログラムの不正改竄を行う際に、条件分岐命令を無条件分岐命令に改竄することが考えられる。例えば、改竄対象のプログラムが、ユーザが入力したIDが正しい値であるかをチェックし、正しい値であった場合には第一SUC_B命令群を行い、間違った値であった場合には第二SUC_B命令群を行うプログラムである場合に、不正解析者は条件分岐命令を改竄して第一SUC_B命令群に分岐する無条件分岐命令に改竄することを行う。このような改竄を行うと、正しいIDを知らなくとも、正しいIDを知っている正規のユーザと同等のプログラムを実行することが出来る。ここで、上述した難読化を行ったプログラムに対して、条件分岐命令を無条件分岐命令に置き換える改竄を行った場合、例えば、上にあげたCBR_AB条件分岐命令群1610を「goto SUC_B_1;」におきかえた場合、入力されたIDが正しい値でない場合であっても第一SUC_B命令群を行うようにすることが出来る(改竄がなければ、第二SUC_B命令群が実行されるはずである)。しかし、上述した難読化を施したCBR_AB条件分岐命令群1610は、SUC_Aを実行する前にも呼び出されるので、このような改竄を行うと、SUC_A命令群を行うべき場合にも、無条件で第一SUC_B命令群が行われてしまうこととなる。よって、このような改竄を行うと、SUC_A命令群の実行自体が行われなくなってしまうという不正解析者が意図しない影響が生じる。このため、不正解析者に対して、自身が行った改竄による影響を把握しにくくすることができるので、不正解析行為および改竄行為を行いにくくなる。
特に上記の構成と変形例(6)で述べた構成を組み合わせた場合、入力値等によって(例えば、「var_org2」の値によって)上記の改竄による影響が発生する場合と発生しない場合とができる。そのため、不正解析者が影響の出ない入力値を使って解析を行った場合に本手法が適用された部分の把握がより困難になり、不正解析行為および改竄行為を行いにくくなる。
さらにまた、非特許文献1に記載の難読化技術のような実際には分岐しないダミーの分岐先を含む条件分岐命令群を追加しても構わない。具体的には、上記にあげた条件分岐命令群の例に、「case 4」、「case 5」、…とダミーの分岐先を追加しても構わない。このような構成を用いれば、第二SUC_B命令群へと分岐する箇所のみを第一SUC_B命令群へ無条件分岐するよう改竄しようとしても、いずれの箇所を改竄すればよいかを知ることが困難になる。また、アセンブリ言語などで記述されたプログラムを難読化する場合には、相対ジャンプを用いた条件分岐命令を用いても構わない。
さらにまた、第一SUC_B命令群と同等の処理を行う第一SUC_B命令群1、第一SUC_B命令群2、…を設け、本来第一SUC_B命令群に分岐する条件の時に、上記同等な処理のいずれかに分岐しても構わない。第二SUC_B命令群、第一SUC_A命令群についても同様である。このようにすることで、不正解析者が、どの命令群が第一SUC_B命令群等に当たる処理を示しているのかを特定することを困難にすることができる。
(10)実施の形態3では、SUC_B命令群の分岐元はB命令群ただ一つである場合について説明したが、B命令群以外に、SUC_B命令群の分岐元としてC1命令群、C2命令群、…があっても構わない。その場合、SUC_B命令群に復帰命令群を追加する都合上、C1命令群、C2命令群、…にも復帰命令に対応する退避命令群を追加する必要がある。また、C1命令群にSUC_B命令群以外の分岐先であるD1分岐先命令群、D2分岐先命令群、…がある場合には、C1命令群に復帰命令群を追加する都合上、D1分岐先命令群、D2分岐先命令群、…にも退避命令群を追加する。
制御構造の複雑なプログラムに対しては、上記の操作を繰り返し行い、退避命令群を追加する対象となる命令群と復帰命令群を追加する対象となる命令群とを決定する。決定した命令群に退避命令群、復帰命令群の追加を行うことで、本発明による難読化を行うことができる。
(11)実施の形態3では、B命令群の後にA命令群が実行された場合、A命令群の実行結果は使用されない構成を示したが、A命令群を行った後の結果をSUC_B命令群で使用する構成としても構わない。この場合は、実施の形態1または2と同様の効果が得られる。
図25は、本変形例に係る改竄防止プログラムの構成を示す図である。
本変形例に係る改竄防止プログラム1330aは、PRE_A命令群1410と、STR_A変数群値代入命令群1620と、A命令群1420と、CBR_AB条件分岐命令群1610と、SUC_A命令群1430と、B命令群1440と、STR_B変数群値代入命令群1630と、退避命令群1640と、被参照変数値代入処理命令群2210と、BR_B分岐命令群1660と、復帰命令群1650と、SUC_B依存処理命令群2220とを含んでいる。
つまり、本変形例に係る改竄防止プログラム1330aは、実施の形態3の改竄防止プログラム1330と比べて、被参照変数値代入処理命令群2210をさらに含むとともに、改竄防止プログラム1330のSUC_B命令群1450の代わりに、SUC_B依存処理命令群2220を含んでいる。
また、本変形例に係る改竄防止プログラム1330aでは、A命令群1420は実施の形態1の第一処理命令群140に相当し、被参照変数値代入処理命令群2210は実施の形態1の被参照変数値代入処理命令群310に相当し、BR_B分岐命令群1660は実施の形態1の分岐処理命令群320に相当し、SUC_B依存処理命令群2220は実施の形態1の依存処理命令群330に相当する。
図26は、C言語で表した改竄防止プログラム1330aの具体的な一例を示す図である。
被参照変数値代入処理命令群2210は、A命令群1420を呼び出して実行する際に必要となる各種パラメータに値を設定する処理である。具体的には、例えば、被参照変数値代入処理命令群2210は、「var_org2=5;」として表され、被参照変数「var_org2」に値「5」を代入する処理を示している。
したがって、BR_B分岐命令群1660によって、A命令群1420に処理が分岐すると、そのA命令群1420が改竄されていなければ、A命令群1420の処理により被代入変数「var_org0」に想定値「40(=5×8)」が代入されるとともに、変数「var_org2」に7(=5+2)が代入される。
一方、SUC_B依存処理命令群2220は、A命令群1420を呼び出した後に実行される処理命令群であり、入力プログラム1310のSUC_B命令群1450と同等の処理を行うプログラム命令群である。SUC_B命令群1450そのものと異なる点は、SUC_B命令群1450の一部の処理が、A命令群1420の処理結果を使用した処理に置き換えられている点である。
具体的には、例えば、SUC_B依存処理命令群2220は、「var_org1=var_org1+var_org2; var_org1=var_org1*(var_org0*3+3)」として表される。つまり、SUC_B依存処理命令群2220では、SUC_B命令群1450の「123」が、A命令群1420の処理結果を使用した「(var_org0*3+3)」に置き換えられている。
したがって、SUC_B依存処理命令群2220は、A命令群1420の処理により、被代入変数「var_org0」の値として想定値「40」が得られていれば、SUC_B命令群1450と同等の処理を実行することができる。
図27は、改竄防止プログラム1330aの処理の流れを示す図である。
改竄防止プログラム1330aの処理は、図22に示す改竄防止プログラム1330の処理と比べて、さらに、被参照変数値代入処理命令群2210を実行する処理(ステップS315)を含むとともに、図22に示すステップS320の処理の代わりに、SUC_B依存処理命令群2220を実行する処理(ステップS321)を含んでいる。
すなわち、実行処理装置1340は、改竄防止プログラム1330aを実行した場合には、退避命令群1640を実行した後(ステップS314)、被参照変数値代入処理命令群2210を実行する(ステップS315)。その後、実行処理装置1340は、BR_B分岐命令群1660を実行する(ステップS316)。また、実行処理装置1340は、復帰命令群1650を実行した後には(ステップS318)、SUC_B依存処理命令群2220を実行する(ステップS321)。
図28は、本変形例に係る改竄防止処理生成装置が改竄防止プログラム1330aを生成する動作を説明するための説明図である。
なお、図28では、PRE_AはPRE_A命令群1410を示し、AはA命令群1420を示し、SUC_AはSUC_A命令群1430を示し、BはB命令群1440を示し、SUC_BはSUC_B命令群1450またはSUC_B依存処理命令群2220を示す。また、変数「X0」は変数「var_org0」を示し、変数「X1」は変数「var_org1」を示し、変数「X2」は変数「var_org2」を示す。さらに、変数「Y」は変数「var_ab0」を示し、変数「P」は変数「var_save0」を示す。
改竄防止処理生成装置は、入力プログラム1310を取得すると、保護対象とすべき命令群を特定し、その保護対象の命令群が複数の処理経路で実行されるように、その入力プログラム1310を難読化する。すなわち、改竄防止処理生成装置は、1つの処理経路の一部として存在する保護対象の命令群が改竄された場合には、その改竄によって他の処理経路で異常が発生するような改竄防止プログラム1330aを生成する。
具体的には、改竄防止処理生成装置は、図28の(a)に示すように、B命令群1440とSUC_B命令群1450との間を選択位置に設定する。そして、改竄防止処理生成装置は、図28の(b)に示すように、その選択位置で保護対象のA命令群1420が再び実行されるように、入力プログラムの実行経路(処理経路)を変更する。
すなわち、改竄防止処理生成装置は、B命令群1440からA命令群1420に処理が分岐するように、BR_B分岐命令群1660「goto A」を新経路として追加する。
このとき、改竄防止処理生成装置は、PRE_A命令群1410の後にA命令群1420が実行されたときには、その後、SUC_A命令群1430が実行され、B命令群1440の後にA命令群1420が実行されたときには、その後、SUC_B命令群1450が実行されるように、幾つかの命令群を追加する。例えば、改竄防止処理生成装置は、STR_A変数群値代入命令群1620「Y=1」と、STR_B変数群値代入命令群1630「Y=8」と、CBR_AB条件分岐命令群1610「if(Y%2==0)goto SUC_B」とを追加する。
次に、改竄防止処理生成装置は、図28の(c)に示すように、B命令群1440の後にA命令群1420が再び実行されるような実行経路の変更によって、SUC_B命令群1450の処理結果が変化しないように、SUC_B命令群1450の整合性を確保する。
すなわち、改竄防止処理生成装置は、退避命令群1640「P=X2」と復帰命令群1650「X2=P」とを追加する。これにより、改竄防止処理生成装置は、B命令群1440の後にA命令群1420が実行されても、その実行結果がSUC_B命令群1450の処理結果に影響を与えてしまうのを防ぐことができる。
さらに、改竄防止処理生成装置は、図28の(d)に示すように、SUC_B命令群1450の処理結果が、B命令群1440の後に実行されるA命令群1420の実行結果に依存するように、SUC_B命令群1450をSUC_B依存処理命令群2220に変更する。このとき、改竄防止処理生成装置は、被参照変数値代入処理命令群2210「X2=5」を追加する。
その結果、A命令群1420が改竄されていなければ、B命令群1440の後のA命令群1420の実行によって変数「X0」の値として想定値「40」が得られ、SUC_B依存処理命令群2220は、SUC_B命令群1450と同等の処理となる。一方、A命令群1420が改竄されていれば、B命令群1440の後のA命令群1420の実行によって変数「X0」の値として想定値「40」が得られず、SUC_B依存処理命令群2220は、SUC_B命令群1450と異なる異常な処理となる。
このように本変形例に係る改竄防止処理生成装置は、A命令群140の実行結果を使用するSUC_B依存処理命令群2220を生成する。これは、本変形例に係る改竄防止処理生成装置が、実施の形態1およびその変形例の改竄防止処理生成装置110,110aと同様の構成を有することによって実現される。つまり、本変形例に係る改竄防止処理生成装置は、実施の形態3の図23に示す改竄防止処理生成装置1320に対して、実施の形態1およびその変形例における想定値算出部290,290aおよび依存処理命令群生成部201,201aなどを追加して構成される。
ここで、保護対象のA命令群1420やSUC_B命令群1450には、関数の代わりに、ユーザインターフェースや外部アクセスに関するAPI(Application Program Interface)が含まれていてもよい。
図29は、本変形例に係る改竄防止処理生成装置が、APIを含む改竄防止プログラムを生成する動作を説明するための説明図である。
なお、図29では、PRE_AはPRE_A命令群を示し、AはA命令群を示し、SUC_AはSUC_A命令群を示し、BはB命令群を示し、SUC_BはSUC_B命令群またはSUC_B依存処理命令群を示す。
ここで、図29の(a)に示すように、A命令群は例えば「X=GetText(V)」として表される。「GetText(V)」は、アドレス変数Vの示すアドレスに、ユーザが入力した文字列を格納するAPIである。同様に、SUC_B命令群は例えば「S=GetText(T)」として表される。「GetText(T)」は、アドレス変数Tの示すアドレスに、ユーザが入力した文字列を格納するAPIである。
つまり、改竄防止処理生成装置は、図29の(a)に示すように、A命令群およびSUC_B命令群にAPIを含む入力プログラムを取得する。このような場合でも、改竄防止処理生成装置は、上述と同様、保護対象とすべき命令群を特定し、その保護対象の命令群が複数の処理経路で実行されるように、その入力プログラムを難読化する。すなわち、改竄防止処理生成装置は、1つの処理経路の一部として存在する保護対象の命令群が改竄された場合には、その改竄によって他の処理経路で異常が発生するような改竄防止プログラムを生成する。
具体的には、改竄防止処理生成装置は、保護対象となるA命令群にAPIが含まれているか否かを判定する。ここで、APIが含まれていると判定すると、改竄防止処理生成装置は、そのAPIをコールする他の処理を検索する。その結果、改竄防止処理生成装置は、そのAPIをコールするSUC_B命令群を見つけると、図29の(a)に示すように、B命令群とそのSUC_B命令群との間を選択位置に設定する。そして、改竄防止処理生成装置は、図29の(b)に示すように、その選択位置で保護対象のA命令群が再び実行されるように、入力プログラムの実行経路(処理経路)を変更する。
すなわち、改竄防止処理生成装置は、B命令群からA命令群に処理が分岐するように、BR_B分岐命令群「goto A」を新経路として追加する。
このとき、改竄防止処理生成装置は、PRE_A命令群の後にA命令群が実行されたときには、その後、SUC_A命令群が実行され、B命令群の後にA命令群が実行されたときには、その後、SUC_B命令群が実行されるように、幾つかの命令群を追加する。例えば、改竄防止処理生成装置は、STR_A変数群値代入命令群「Y=1」と、STR_B変数群値代入命令群「Y=8」と、CBR_AB条件分岐命令群「if(Y%2==0)goto SUC_B」とを追加する。
次に、改竄防止処理生成装置は、図29の(c)に示すように、B命令群の後にアドレス変数Vの値を変更してA命令群が再び実行されても、その変数Xおよびアドレス変数Vの値がSUC_B命令群以降の処理でも不必要に変更されてしまうことがないように、変数Xおよびアドレス変数Vの整合性を確保する。すなわち、改竄防止処理生成装置は、退避命令群「P1=X; P2=V」と復帰命令群「X=P1; V=P2」とを追加する。
さらに、改竄防止処理生成装置は、図29の(d)に示すように、SUC_B命令群の処理結果が、A命令群の実行結果に依存するように、SUC_B命令群「S=GetText(T)」をSUC_B依存処理命令群「S=X; *T=*V」に変更する。すなわち、改竄防止処理生成装置は、アドレス変数Vにより示されるアドレスに処理結果が格納されているので、その処理結果を本来のSUC_B命令群の処理結果の代わりに使用する。なお、このとき、改竄防止処理生成装置は、被参照変数値代入処理命令群「V=T」を追加する。
その結果、A命令群が改竄されていなければ、SUC_B依存処理命令群は、SUC_B命令群と同等の処理となる。一方、A命令群が改竄されていれば、つまり、A命令群がシリアルの入力をする処理である場合に不正解析者が例えば「X=(シリアルの値の定数)」とするような改竄を行えば、SUC_B依存処理命令群は、SUC_B命令群と異なる異常な処理となる。
(12)実施の形態3では、PRE_A命令群、A命令群、SUC_A命令群、B命令群、およびSUC_B命令群とは同一の入力プログラムに含まれる命令群であるとしたが、別々の関数として実現してもよい。
例えば、実施の形態1と同様、第一処理命令群に相当するA命令群と、第二処理命令群に相当するB命令群およびSUC_B命令群とを別々の関数として入力することなどが考えられる。この場合、B命令群からA命令群を含む関数を読み出し、その関数の処理結果を破棄すれば(または、明示的に破棄しなくとも参照しなければ)、SUC_B命令群以降の処理に命令群Aの影響が現れないようにしつつ、実施の形態3と同様の難読化を行うことができる。なお、A命令群を含む関数を参照呼びで呼び出す場合などには、引数として与えた変数が変化してしまい、SUC_B命令群以降の処理に影響が出る恐れがあるので、実施の形態3と同様、退避処理命令群や復帰処理命令群を関数呼び出しの前後に追加する。
また、実施の形態1およびその変形例では、第一処理命令群と第二処理命令群とは別々に入力されるものであるとしたが、実施の形態3と同様、同一の入力プログラム中、または、同一の関数中の別の処理であるとしても良い。この場合も上記と同様の効果が得られることは言うまでもない。
(13)実施の形態3では、B命令群の後にA命令群が実行されるようにするために、BR_B分岐命令群1660を用いる構成を説明したが、これに限られるものではない。例えば、分岐命令を使う代わりに、命令群の処理の順番を入れ替え、退避命令群1640の直後に、A命令群を配置するとしてもよい。この場合には、BR_B分岐命令群1660は不要となるが、命令群の実行順序を入力プログラム1310と同じにするため、STR_A変数群値代入命令群1620の後にA命令群への分岐命令を挿入する等の変換が必要となる。
(14)実施の形態3では、入力プログラムのうち、どの部分をA命令群とし、どの部分をB命令群とするかをユーザが指定する構成であったが、改竄防止処理生成装置が入力プログラムの中からランダムに選択した命令群をA命令群又はB命令群とする構成としても構わない。そのような構成をする場合、改竄防止処理生成装置は、A命令群又はB命令群の決定後、PRE_A命令群およびSUC_A命令群を決定する必要がある。この場合、改竄防止処理生成装置は、決定したA命令群の分岐元ブロックを解析し、解析したブロックを第一PRE_A命令群、第二PRE_A命令群、…とする。第一PRE_B命令群、第二PRE_B命令群、…についても同様である。また、改竄防止処理生成装置は、命令群の分岐先ブロックを解析し、解析したブロックを第一SUC_A命令群、第二SUC_A命令群、…とする。第一SUC_B命令群、第二SUC_B命令群、…についても同様である。
(15)実施の形態3では、分岐先決定用のG_VAL_AB変数は、「var_ab0」の1つだけであったが、複数であってもよい。この場合、例えば、SUC_A命令群へ分岐すべきか否か示す変数とSUC_B命令群へ分岐すべきか否かを示す変数とを異なる変数にすることなどができる。
(16)実施の形態3では、改竄防止処理生成装置1320への入力として、SUC_A命令群を含んだ入力プログラムを用いていたが、これに限られるものではない。例えば、A命令群の分岐先である命令がOS側の関数である場合などには、必ずしもSUC_A命令群に相当する命令が入力プログラムに含まれない。すなわち、改竄防止処理生成装置1320は、SUC_A命令群が入力として与えられない場合でも、A命令群の分岐先である命令のアドレスや関数名さえ分っていれば、そのアドレスや関数名が示す命令群に分岐するようCBR_AB条件分岐命令群を構成することで、難読化ができる。
(17)実施の形態1およびその変形例ならびに実施の形態2,3の説明では、プログラム生成の処理の流れの一例を示したが、互いに依存関係のない処理については順序を入替えたり、並列化して実行しても構わない。
また、ここで述べた難読化を他の難読化手法と一緒に適用しても良い。
例えば、実施の形態1およびその変形例ならびに実施の形態2,3では、基本的には入力された命令群を、出力する命令群にそのまま含ませていたが、それに限られるものではない。別の難読化手法などにより、入力プログラムに基づいて、各命令群に等価な命令群を生成した上で、その命令群を難読化後のプログラムに含ませても良い。このようにすることで、入力プログラムの命令群と出力されるプログラムの命令群との対応関係を分かりにくくすることができる。ここで、全ての命令群からそれぞれの等価な命令群を生成するのではなく、一部については等価な命令群を生成し、他の命令群については、入力プログラムそのままの命令群を出力するとしてもよい。つまり、本変形例における等価な命令群とは特に何も変換されない命令群も含み、等価な命令群の生成とは入力プログラムから各命令群を抽出するだけの処理も含む。なお、上記の効果を得るためには、各命令群のうち、少なくとも1つが元とは異なるが等価な処理を行う命令群に変換されればよく、他の命令群が元とは異なる命令群に変換されるかどうかは問わない。
(18)ここで例えば、図3に示す第二処理命令群150を本発明と異なる他の手法により難読化して実行処理装置130に実行させる場合には、その難読化された第二処理命令群150を解析することなく、それらを他の機器に容易に移植して、その機器においても第二処理命令群150を正常に実行させることができる。
例えば、第二処理命令群150では、暗号鍵を用いて復号化が行われる。その暗号鍵や復号化処理の内容は秘密とされるべき情報(秘密情報)であって、解析されてはならない。したがって、上述のように第二処理命令群150は難読化される。しかし、第二処理命令群150が難読化されて、その秘密情報の解明を防ぐことができても、上述のような移植という不正行為が容易に行われれば、その難読化は無意味になってしまう。また、そのような不正行為を防ぐためには、難読化された第二処理命令群150のコードサイズを大幅に増加させる必要がある。
したがって、実施の形態1およびその変形例の改竄防止処理生成装置110では、実行処理装置130に元々含まれている命令群を第一処理命令群140として用い、処理経路がその第一処理命令群140に分岐するように出力処理命令群160を生成してもよい。これにより、出力処理命令群160のコードサイズの増大を小さく抑えつつ上述のような移植を困難にすることができる。
図30は、第一処理命令群140が実行処理装置130に元々含まれている場合における本発明の効果を説明するための説明図である。
改竄防止処理生成装置110は、保護対象である第二処理命令群150を取得する。例えば、第二処理命令群150は、処理ブロックB0,B1,…B9を含んでいる。また、第一処理命令群140を構成する処理ブロックBAは、実行処理装置130に元々含まれている。そこで、改竄防止処理生成装置110は、処理経路が処理ブロックB0から処理ブロックBAに分岐して処理ブロックB1に戻るように、第二処理命令群150を修正することにより、出力処理命令群160を生成する。つまり、改竄防止処理生成装置110は、第一処理命令群140を保護対象の一部とし、第二処理命令群150を出力処理命令群160に難読化する。
その結果、不正解析者は、第二処理命令群150による処理を他の機器に実行させるような不正行為を行う場合には、第二処理命令群150だけでなく第一処理命令群140も移植しなければならない。しかし、第一処理命令群140は、実行処理装置にもともと組み込まれている処理を行う命令群であるので、別の装置への移植は困難である。したがって、このような不正行為を困難にすることができる。さらに、第二処理命令群150の難読化により、命令群が大幅に増加されることがないので、出力処理命令群160のコードサイズの増大を小さく抑えることができる。また、各実行処理装置に固有の処理を行うような命令群を第一処理命令群140として選ぶことで、さらに移植を困難にすることができる。
なお、第一処理命令群140は必ずしもプログラム命令である必要はなく、実行処理装置130に元々含まれている装置や回路(例えば、オーディオ再生に使用する回路)などとしてもよい。また、移植を困難にするために、実行処理装置130に第一処理命令群140の役割を担う専用の装置や回路を追加してもよい。これらの場合、分岐処理命令群には、第一処理命令群140に分岐する動作の代わりに、上述した装置や回路を動作させる命令を含ませればよい。なお、被参照変数は、例えば、その装置や回路に対する入力となり、被代入変数は、その装置や回路の出力となる。
このような構成を用いれば、単に実行処理装置130で動作するプログラムを移植しても、前記の装置や回路を持たない環境では、移植したプログラムを動作させることが出来なくなるので、不正者がプログラムを移植する攻撃を防止することができる。
(19)ここで例えば、暗号などの秘密情報を含む処理(命令群)には、一般的にはあまり使用されないテーブル引きやビットシフト演算などの特徴的な演算(以下、特徴的演算)が含まれる場合がある。したがって、図16に示す実行処理装置1340が入力プログラム1310を実行するような場合には、不正解析者は、特徴的演算を目印にして、入力プログラム1310から、秘密情報を含む命令群を容易に見つけ出して不正に解析することができる。
したがって、例えば実施の形態3の改竄防止処理生成装置1320では、特徴的演算を含む命令群をA命令群1420として、改竄防止プログラム1330を生成してもよい。
図31は、A命令群1420が特徴的演算を含む場合における本発明の効果を説明するための説明図である。
改竄防止処理生成装置1320は、入力プログラム1310を取得すると、特徴的演算を含む命令群を検索して、見つかった命令群をA命令群1420として、上述した実施の形態3と同様の難読化処理を行う。その結果、改竄防止処理生成装置1320が生成するプログラムは、上述の実施の形態3と同様に、その特徴的演算を含むA命令群1420が繰り返して実行されるような改竄防止プログラム1330となる。
これにより、改竄防止プログラム1330の処理経路において特徴的演算が実行される箇所が増加する。したがって、不正解析者が秘密情報を含む命令群を見つけ出そうとする不正解析を困難にすることができる。
なお、実施の形態1およびその変形例ならびに実施の形態2においても、上述と同様、改竄防止処理生成装置は、特徴的演算を含む命令群を第一処理命令群として、出力処理命令群を生成してもよい。
(20)ここで、実施の形態1およびその変形例ならびに実施の形態2,3では、保護対象となる命令群(第一処理命令群またはA命令群)に分岐する分岐処理命令群を生成したが、この分岐処理命令群を生成することなく、図28の(d)に示すような依存化のみを行ってもよい。
例えば、コンテンツの再生を制限するプログラムを改竄して、そのプログラムの再生制限を解除してしまうような攻撃が想定される。このようなプログラムは、例えば、コンテンツの再生回数が所定の制限回数以下であれば、そのコンテンツの再生を許可する。または、プログラムは、コンテンツを再生する機器を認証し、正当な機器にのみそのコンテンツの再生を許可する。または、プログラムは、そのコンテンツが不正にコピーされたものであるか否かを判定し、不正にコピーされたものでなければ、そのコンテンツの再生を許可する。
つまり、不正解析者は、コンテンツの再生許否を判定するための条件分岐命令をそのプログラムから見つけ出して、常に再生許可されるようにその条件分岐命令を無条件分岐命令に改竄しようとする。
図32は、不正解析者による改竄の例を示す図である。
不正解析者は、まず、図32の(a)および(b)に示すように、プログラムを実行させて、再生許可時におけるログと再生不許可時におけるログとを比較する。その結果、不正解析者は、図32の(c)および(d)に示すように、ログに差異が生じる部位を特定し、その部位の直前にある、コンテンツの再生許否を判定するための条件分岐命令(処理ブロックB19)を見つけ出す。
そこで、不正解析者は、条件分岐命令である処理ブロックB19を解析し、処理ブロックB19では、再生許可のときに変数aに1が代入され、再生不許可のときに変数aに0が代入されることを解明する。したがって、不正解析者は、処理ブロックB19において常に変数aに1が代入されるように、その処理ブロックB19を条件分岐命令から無条件分岐命令に変更しようとする。
そこで、この攻撃に対処するために、本発明では、図28の(d)に示すような依存化のみを行ってもよい。
図33は、本変形例に係る改竄防止処理生成装置が依存化のみを行う例を示す図である。
本変形例に係る改竄防止処理生成装置400は、図32に示す条件分岐命令を含むプログラムを入力プログラムPiとして取得する。そして、改竄防止処理生成装置400は、その入力プログラムPiの中の再生許可時の処理(被制限処理)に含まれる1つの定数を特定する。つまり、改竄防止処理生成装置400は、処理ブロックB26に含まれる定数「10」を見つけ出す。さらに、改竄防止処理生成装置400は、その入力プログラムPiの条件分岐命令(処理ブロックB19)で、コンテンツの再生許否の判定結果が格納される変数である判定変数aと、再生許可のときにその判定変数aに格納される判定結果を示す値である被制限値「1」とを処理ブロックB19から抽出する。
その結果、改竄防止処理生成装置400は、処理ブロックB26に含まれる定数「10」を、「a=1」のときにその定数「10」と等しくなるような数式「a*5+5」に変換することにより、処理ブロックB26の処理を処理ブロックB19の処理結果(実行結果)に依存させる。
つまり、改竄防止処理生成装置400は、入力プログラムPiにおいて処理ブロックB19の判定結果に関わらず再生許可時の処理が実行されるように、再生不許可時のエラー処理(処理ブロックB30〜B39)を削除するとともに、処理ブロックB26「x=x+10」を、処理ブロックB26a「x=x+a*5+5」に置き換えることにより、改竄防止プログラムPoを生成する。
これにより、改竄防止プログラムPoでは、処理ブロックB26で再生が許可されたとき、つまり判定変数aに1が代入されたときには、コンテンツが正常に再生されるような処理が行われる。一方、処理ブロックB26で再生が許可されなかったとき、つまり判定変数aに0が代入されたときには、コンテンツが正常に再生されるような処理は行われず、異常な処理が行われる。したがって、判定変数aに正当な値が代入されなかった場合には、コンテンツを正常に再生することができなくなるので、入力プログラムPiと同等の処理ができる。
また、本変形例では、改竄防止プログラムPoを実行したときのログが、再生許可時と再生不許可時とで等しくなるため、保護対象となる条件分岐命令が見つけ出されて無条件分岐命令に改竄されるのを困難にすることができる。
図34は、本変形例に係る改竄防止処理生成装置400の構成の一例を示す図である。
改竄防止処理生成装置400は、入力プログラム保持部401、定数選択部402、変数抽出部403、変換部404、および改竄防止プログラム保持部405を備えている。
入力プログラム保持部401は、入力プログラムPiを取得して保持する。
定数選択部402は、入力プログラムPiの中の再生許可時の処理(被制限処理)を特定し、さらに、その処理に含まれる1つの定数を選択する。
変数抽出部403は、入力プログラムPiの中の条件分岐命令において判定結果が格納される判定変数を、その条件分岐命令から抽出する。さらに、変数抽出部403は、条件分岐命令において被制限処理を実行すべきと判定されるときにその判定変数に格納される値である被制限値を抽出する。
なお、判定結果を示す値を判定変数に格納する条件分岐命令は、複数の命令からなる命令群であってもよい。また、判定変数は、入力プログラムPi中に明示的に表れる変数である必要はない。例えば、判定変数はスタックであってもよい。この場合、被制限値とは、そのスタックに格納された値である。また、判定変数は、アドレス変数で指定される位置に対応する記憶領域であってもよい。この場合、被制限値とは、その位置に格納された値である。さらに、被制限値も1つの値に限るものではなく、値の集合であってもよい。この場合、処理ブロックB26aとして、判定変数に代入された値がこの集合に属するどの値であっても処理ブロックB26と同じ処理を行うような命令群を生成する。このような性質を持つ命令群の生成の仕方は、実施の形態1の変形例6における依存処理命令群の生成の仕方と同様である。
また、このような条件分岐命令において判定変数に被制限値を代入する処理は、実施の形態1およびその変形例ならびに実施の形態2における第一処理命令群の処理や、実施の形態3のA命令群の処理と同様である。
変換部404は、条件分岐命令の判定結果に関わらず被制限処理が実行されるように、入力プログラムPiの中のエラー処理を削除する。さらに、変換部404は、定数選択部402で選択された定数を、判定変数を用いた数式に変換する。なお、変換部404は、その定数を、判定変数を用いた関数に変換してもよい。このとき、変換部404は、判定変数に被制限値が代入されたときにその数式によって算出される値が上述の定数と等しくなるように数式を生成する。変換部404は、このような処理により改竄防止プログラムPoを生成して改竄防止プログラム保持部405に格納する。なお、変換部404は、実施の形態1およびその変形例ならびに実施の形態2の依存処理命令群生成部201,201a,201bと同様の処理を行うことにより、上述の数式を生成する。
改竄防止プログラム保持部405は、変換部404によって生成された改竄防止プログラムPoを取得して保持する。
図35は、本変形例に係る改竄防止処理生成装置400の動作の一例を示すフローチャートである。
改竄防止処理生成装置400は、まず、入力プログラムPiの被制限処理に含まれる定数を選択する(ステップS500)。さらに、改竄防止処理生成装置400は、入力プログラムPiの条件分岐命令から判定変数および被制限値を抽出する(ステップS502)。そして、改竄防止処理生成装置400は、ステップS500で選択された定数を、判定変数を用いた数式に変換する(ステップS504)。また、このとき、改竄防止処理生成装置400は、条件分岐命令の判定結果に関わらず被制限処理が実行されるように、入力プログラムPiの中のエラー処理を削除する。その結果、入力プログラムPiは改竄防止プログラムPoに変換される。
(21)また、実施の形態1およびその変形例では、第二処理命令群150が、圧縮されたコンテンツを解凍する処理であるとして説明したが、他の処理であってもよい。さらに、実施の形態1およびその変形例ならびに実施の形態2では、第一処理命令群140が、コンテンツの暗号化された再生可能回数を復号して平文の再生可能回数を出力する処理であるとして説明したが、他の処理であってもよい。すなわち、本発明の適用対象は、実施の形態1およびその変形例ならびに実施の形態2で述べた復号処理や解凍処理等を行う命令群に限らない。改竄を防止する必要がある命令群であれば、どのようなものにでも適用できる。例えば、その適用例として、コンテンツの利用権を管理する命令群などが挙げられる。
(22)実施の形態1およびその変形例ならびに実施の形態2,3では、各プログラムや命令群がC言語のプログラムである場合の例を示したが、これに限られるものではない。それぞれ、他のプログラミング言語、UML等のモデリング言語、コンパイラ等の中間言語、アセンブリ言語、マシン語等であっても構わない。
(23)実施の形態1およびその変形例ならびに実施の形態2,3で、難読化する対象はコンピュータプログラミング言語に関わらず、論理回路記述言語等の論理回路の設計の情報(具体的には、VHDL等のハードウェア記述言語で記述されたプログラム等)であっても構わない。難読化により得られるプログラムについても同様である。すなわち、本発明で難読化対象とするプログラムおよび難読化により得られるプログラムは、コンピュータプログラミング言語で記述されたプログラムに限らず、上述した論理回路の設計の情報も含む概念である。
(24)上記の各装置は、具体的には、マイクロプロセッサ、ROM、RAM、ハードディスクユニット、ディスプレイユニット、キーボード、およびマウスなどから構成されるコンピュータシステムである。そのRAMまたはハードディスクユニットには、コンピュータプログラムが記憶されている。つまり、マイクロプロセッサが、コンピュータプログラムにしたがって動作することにより、各装置は、その機能を達成する。ここでコンピュータプログラムは、所定の機能を達成するために、コンピュータに対する指令を示す命令コードが複数個組み合わされて構成されたものである。なお、各装置は、マイクロプロセッサ、ROM、RAM、ハードディスクユニット、ディスプレイユニット、キーボード、マウスなどの全てを含むコンピュータシステムには限らず、これらの一部から構成されているコンピュータシステムであってもよい。
(25)上記の各装置を構成する構成要素の一部または全部は、1個のシステムLSI(Large Scale Integration:大規模集積回路)から構成されているとしてもよい。システムLSIは、複数の構成部を1個のチップ上に集積して製造された超多機能LSIであり、具体的には、マイクロプロセッサ、ROM、およびRAMなどを含んで構成されるコンピュータシステムである。そのRAMには、コンピュータプログラムが記憶されている。つまり、マイクロプロセッサが、コンピュータプログラムにしたがって動作することにより、システムLSIは、その機能を達成する。
(26)上記の各装置を構成する構成要素の一部または全部は、各装置に脱着可能なICカードまたは単体のモジュールから構成されているとしてもよい。そのICカードまたはモジュールは、マイクロプロセッサ、ROM、およびRAMなどから構成されるコンピュータシステムである。そのICカードまたはモジュールは、上記の超多機能LSIを含むとしてもよい。つまり、マイクロプロセッサが、コンピュータプログラムにしたがって動作することにより、そのICカードまたはモジュールは、その機能を達成する。このICカードまたはこのモジュールは、耐タンパ性を有するとしてもよい。
(27)本発明は、上記の改竄防止処理生成装置が改竄防止処理を生成する方法としても実現される。また、本発明は、これらの方法によりコンピュータに改竄防止処理を生成させるコンピュータプログラムや、コンピュータプログラムからなるディジタル信号としても実現される。
(28)また、本発明は、上述のコンピュータプログラムまたはディジタル信号をコンピュータ読み取り可能な記録媒体、例えば、フレキシブルディスクや、ハードディスク、CD−ROM、MO、DVD、DVD−ROM、DVD−RAM、BD(Blu−ray Disc)、半導体メモリなどに記録したものとしても実現される。また、これらの記録媒体に記録されているディジタル信号としても実現される。
(29)また、本発明は、電気通信回線、無線通信回線、有線通信回線、インターネットを代表とするネットワーク、またはデータ放送等を経由して伝送される、上述のコンピュータプログラムまたはディジタル信号としても実現される。
(30)また、本発明は、マイクロプロセッサとメモリを備えたコンピュータシステムとしても実現される。この場合、そのメモリは、上述のコンピュータプログラムを記憶しており、マイクロプロセッサは、そのコンピュータプログラムにしたがって動作する。
(31)また、そのコンピュータプログラムまたはディジタル信号を記録媒体に記録して移送することにより、またはコンピュータプログラムまたはディジタル信号をネットワーク等を経由して移送することにより、独立した他のコンピュータシステムにより本発明の処理を実施してもよい。
(32)本発明は、これらの実施の形態及び変形例の組合せであってもよい。