ソフトウェアのリバースエンジニアリング技術の必要性 (そしてJavaとCの逆コンパイラについて) | プログラムは楽しげに走らねばならない♪

ソフトウェアのリバースエンジニアリング技術の必要性 (そしてJavaとCの逆コンパイラについて)

2007/06/27(水) 追記

関連記事「Cの逆コンパイラはどこまで実現可能か,Javaはなぜ逆コンパイルされやすいのか? 」を追加しました.



セキュリティとリバース・エンジニアリング (ITpro)

という記事を非常に興味深く読んだ.ようやくリバース・エンジニアリングの必要性が社会に認知され始めたか,というのが感想である.


この記事のタイトルは,仕事中に Google Desktop から私の目に飛び込んできた.ソフトウェアのリバースエンジニアリング技術には以前からとても興味があったし,マルウェア対策に不可欠な手段になるだろうと思っていたので,そのタイトルに目を奪われた.そしてすぐ記事を読み,すぐブログを書かずにはいられなくなり,今仕事中だけどこっそり書いている.(^^;)


ほとんどのソフトウェアの利用規定では,リバースエンジニアリングを禁止している.ソフトウェアのリバースエンジニアリングのツールを有償または無償で提供した場合,「クラッキングを助長する」として,ソフトウェア・ベンダや一般社会から厳しい批判に晒されるおそれが多分にある.


実際,オランダのプログラマである故 Hanpeter van Vliet氏が1996年に Java の逆コンパイラ Mocha を無償公開した時には,一部のメディアに一方的な批判記事を書かれたり,論争が巻き起こったりしたと聞く.(ちなみに同氏はその年の12月31日に癌で死去,享年34歳だったそうな.ああもう10年も経ったのか.(遠い目))


私はリバースエンジニアリングに強い興味を持つ者の一人として,それが何の役に立つのかを考えることが時々ある.リバースエンジニアリングツールを擁護する立場から従来言われてきたのは,次のような意見だと思う.

  1. ソースもドキュメントもないレガシープログラムを理解するのに役立つ.(うんうん)
  2. 開発中にわけがわからなくなってしまったプログラムを理解・整理するのに役立つ .(おいおい)
  3. 開発中に誤ってソースファイルを消してしまった場合, オブジェクトファイルや実行ファイルからソースを復元できる. (バックアップくらいちゃんと取っとけ!)

(1) 以外は到底世間に納得してもらえるような理由ではない.私はこれらに加えて,ウィルスなどマルウェアを短時間で解析するための強力なツールになるのではないかと以前から思っていた.解析対象となるのはマルウェアだけではない.クラッカーの攻撃対象となりそうなソフトウェアの脆弱性をクラッカーより早く発見して穴を塞ぐためにも,リバースエンジニアリングは必要である.例えばバッファ・オーバーフローを発生する可能性のある部分を自動的に検出するとか.ゼロデイ攻撃が問題になり始めた現在,リバースエンジニアリングはゼロデイ防御に不可欠な技術である.いや,解析するだけでなくもう一歩進めて,自動的にマルウェアを無毒化・駆除するための対策ソフトを自動生成するようにするのが望ましい.


私は以前からソフトウェアの解析技術に非常に興味を持っている.といっても他人の書いたソフトをクラックしたいわけではない.(そうしたくなるような興味深い謎のあるソフトなんて滅多にお目にかかれない.)
「プログラムを理解するプログラム」や「プログラムを作るプログラム」といった,AI (人工痴呆 知能) 的なテーマに興味があるのである.プログラムがプログラムを理解するための一つの通過点として,そして理解していることを示す一つの方法として,C言語の逆コンパイラを作ってみたいと思っているわけだ.名前だけはもう考えてある.「C-1 (C Inverse)」である.Cコンパイラの逆関数 (inverse) という意味だ.


アイディアは色々あるが,実装はつい最近始めたばかり.とりあえず,x86 の逆アセンブラから着手した.「x86 の逆アセンブラなんて,その辺にころがってるやん.」と言われそうだが,今作りかけている逆アセンブラは人間が読むためのアセンブラソースを出力するものではない.逆コンパイラの一部であり,上位の解析プログラムに情報を渡すためのものだ.しかし,仕事や他の関心事で中断することもしばしば.C-1 が実現するのは(十?)何年先になることやら.(´д`)


昔から逆コンパイラのアイディアを色々考えていながら何も着手していなかった私は,Mocha が登場したとき,「やられたっ! 先を越された!」と思ったものだ.私は Java の逆コンパイラを作ろうと思っていたわけではないが,Hanpeter van Vliet 氏が対象言語として Java として選んだのは素晴らしい.目の付け所が 眉の下 違う.Java は逆コンパイラが作りやすい言語なのだ.


Mocha の発表から間もない頃,ヨーロッパ (だったと思う) のある Java 関連サイトで「Java はなぜ逆コンパイルしやすいか」という内容の記事を見たことがある.だが,「オブジェクト指向だから」とか,「CPU 独立なバイトコードを採用しているから」といった全くピント外れの勘違いな説明で,思わず失笑してしまった.(そして「違う!」と叫びたかった.)


Java のクラスファイルの構造を知っている人は,構造体 (インスタンス) の定義などがクラスファイルに含まれているからだと思うだろう.確かにそれもある.そのおかげで,コメント以外の情報はすべて復元できるかもしれない.しかしそれは本質的ではない.かりに Java がクラスファイルを使わず,普通のオブジェクトファイルにコンパイルされていたとしても,C に比べればずっと逆コンパイルは容易だろうと思う.


Java が逆コンパイルしやすい本質的な理由は,その言語仕様にある(… と偉そうなことを書くほど Java のことを知っているわけでも,使っているわけでもないので,Java に詳しい方,違っていたらお気軽に指摘してください).Java が逆コンパイルしやすい最大の理由は,ポインタ演算を禁止していることと,Cの共用体に相当するものがないことから,ポインタが指しているデータの型 (クラス) を限定しやすいことにある,と思っている.これらはガーベージ・コレクションを可能にするための必要条件でもある.(実はクラスキャストも関係するはずだが,クラスキャストをちゃんと調べているわけではないのでここでは書かないでおく.(卑怯者!))


それから,goto 文を禁止していることは,制御構造を解析・復元しやすくしているはず.ただし現状の Java 逆コンパイラは制御構造の解析能力に限界があり,goto 文を吐き出す場合があるらしい.


Mocha の登場以後,雨後の筍のようにさまざまな Java 逆コンパイラ が出てきた.だから今更 Java の逆コンパイラを作りたいとは全く思わない.これに対し,C の逆コンパイラは未踏の領域だし,Java 逆コンパイラより遙かに難しい.dcc という先駆的な研究はあるものの,まだまだ実用レベルにはほど遠い.一生に一度は,他人が逆立ちしても作れないソフトを開発したいものだ.実用レベルの C 逆コンパイラが作れるといいが.なおこの記事を書いている最中に初めて知ったのだが,マルウェアを解析するために dcc を改良した ndcc というのがあるらしい.


今更ですが,私とほぼ同じ年齢でありながら,私よりはるかに先を行き,あまりにも早く逝ってしまった Hanpeter van Vliet 氏のご冥福をお祈りします.



関連記事


解析魔法少女美咲ちゃん マジカル・オープン!
やねう解析チーム
秀和システム (2004/08)
売り上げランキング: 52272
おすすめ度の平均: 3.5
5 意外と、イイ
5 アセンブラ及びC言語の学習に
4 楽しくクラックの基礎を学べる

アセンブリ言語の教科書
愛甲 健二
データハウス (2005/07)
売り上げランキング: 75351
おすすめ度の平均: 3.5
1 冗長感は否めない、そして索引も必要
1 ゆとり教育の教科書
5 アセンブリ言語の良書