川村渇真の「知性の泉」

私の得意技:逆アセンブルしながら処理内容を解析


 私は、変な得意技をいくつか持っています。その1つが、ソフトを逆アセンブルしながら実行させ、その動きを解析してしまう技です。この技を駆使して何をやっていたのか、簡単に紹介しましょう。一部に危ない内容もありますが、もう時効なので公開しても大丈夫でしょう。なお、この話は難しい用語と内容が多く含まれるので、分からない部分は軽く読み飛ばしてください。


モニタープログラムのTMONは最高!

 コンピュータ用のツールの中には、モニタープログラムと呼ばれる種類のソフトがあります。メモリー上にロードされたソフトの実行コードを逆アセンブルしたり、ブレークポイントを設定して動作を追いかけたりといった、非常に面白い機能を持っているツールです。CPUとOSが異なると動かないので、使用マシンとOSに合ったソフトを用意する必要があります。
 こうしたソフトを使っていた所有マシンは、NEC製のPC-9801とApple製のMacでした。PC-9801では、MS-DOSに付属しているDEBUG(だと記憶してますが、かなり昔の話なので自信がありません)を使っていました。Mac用としてはMacsBugが有名ですが、私が好んで使っていたのは市販製品のTMON(「ティーモン」と読んでいましたが、それが正しかったかどうか未だに不明)です。のちにTMON Professionalにバージョンアップして、CPUがPowerPCに変わるまで使い続けました。
 このTMONは、本当によくできたツールでした。モニタープログラムなのに複数のウィンドウが開けるのです。レジスタ値の表示、逆アセンブル表示、メモリ使用状況の表示、メモリ上のデータの16進表示など、何種類かのウィンドウが使えます。また、同じ種類のウィンドウが複数開け、違う箇所の逆アセンブルも表示可能です。さらに凄いのは、表示の開始位置を式で指定できる点です。実行箇所のアドレスを保持するプログラムカウンタを指定すれば、次の実行箇所を常に表示できます。スタックに使っているレジスタを指定すれば、スタックの一番上が常に見れます。

唯一残っていたTMONの画面ダンプ。モニタープログラムなので、通常の画面ダンプ操作では表示画像を保存できません。仕方がないので、C言語で専用のプログラムを作り、この画面ダンプをファイルとして保存した記憶があります。

TMONの画面ダンプ

 こういった便利な機能があるため、実行の様子を解析するのが非常に楽になります。本当に素晴らしいツールでした。しかし、Mac用のCPUがPowerPCに変わったとき、対応版が噂されたものの登場しなかったので、使うことができなくなってしまいました。とても悲しかったのを覚えています。

OSやアプリのパッチ当てに使っていた

 さて、こうしたモニタープログラムを使って、何をしてたのでしょうか。それは、OSやアプリへのパッチ当てです。日本語が表示できないアプリを日本語化したり、OSの機能を少し変更したり、デフォルトの設定を変えたり、プロテクトを外したりです。
 最後のプロテクト外しというのは、ソフトの命令を書き換えて、プロテクトがかかってない状態にする変更です。コピーフリーになるのでヤバイ行為でしたが、とても面白いので手当たり次第にやっていました。もちろん、プロテクトを外したソフトは自分だけの宝物にして、公開しませんでした。最初のきっかけは、自分が購入したゲームにプロテクトがかかっていて、使いにくかったからです。そのため、ゲームで遊ぶ前にプロテクトを外し、それが終わってからゲームを楽しみました。ゲームで遊ぶのは、すぐ飽きてやらなくなるので、まるでプロテクトを外すためにゲームを購入していたみたいでした。とはいうものの、外すのにかかる時間は、慣れてくると10分とか20分ぐらいしかかかりません。早いときは5分ぐらい、長くても30分以内で外せるようなり、外すのも途中で飽きてしまいました。
 当時は、オープンソースなんて広まってませんでしたから、市販のOSやアプリはもちろん、フリーで使えるソフトでも、ソースコードが公開されていないものがほとんどでした。そのため、気に入らない箇所を変更しようと思っても、ソースコードを修正して再コンパイルする方法が使えません。仕方がないので、モニタープログラムで逆アセンブルしながら、ソフトの動作を解析し、修正したい機能の箇所を探すわけです。その箇所が見付かったら、変更後の命令コードを考え、16進表記で作ります。あとは、該当するファイルを16進表記編集できるツールで開き、該当箇所を新しい16進表記コードで置き換えるだけです。
 大変なのは、変更後の命令コードが長くなる場合です。実際あったのは、次のような変更でした。フォントIDが命令コードの中に埋め込まれていて、1バイトを使っていました。しかし、変更したいフォントIDは2バイトの長さが必要なので、そのままでは入りません。そこで、前後の命令コードが実現している機能を細かく調べ、十数行分の命令コードを別な命令コードで置き換えながら、2バイトのフォントIDを埋め込みました。当然ですが、新しい命令コードは、前の命令コードとまったく同じ機能を実現させています。同じ機能を実現するのに、異なる命令コードの組み合わせでできるため、こういった変更も可能なのです。全体の長さが重要なので、命令コードごとのバイト数を計算しながらの変更となりました。
 命令コードの変更で大事なのは、余計な副作用を生じさせない点です。同じルーチンを別な場所でも呼び出していることが多いため、そちらに悪影響を与えない形で変更しなければなりません。この点も考慮しながら、どこをどのように直せばよいのか深く検討して、該当箇所を求めます。

パッチ当てには、CPUやOSの知識が必要

 実行を追いながらソフトの機能や動きを解析するには、CPUの基本構造、アセンブラの表記、OSの内部構造、OSが提供しているAPIなどを理解している必要があります。アセンブラのもととなる機械語命令はCPUの種類ごとに異なるため、それぞれ覚えなければなりません。
 こうした条件を満たせば、あとは本人の解析力だけです。いくつかのソフトを逆アセンブルしながら実行状況を追っていると、いろいろな動きが推測できるようになります。また、ソフトごとで作り方に癖があって、ソフトがどのパターンなのか判断すれば、推測が当たりやすくなります。こうした経験を積んでいくことで、解析力がアップしていきました。
 私のアセンブラ遍歴も簡単に紹介しましょう。まず、Intel製の8ビット・マイクロプロセッサ「8080」の動作を最初に覚えて、そのアセンブラが理解できるようになりました。次に覚えたのは、IBM製の大型汎用機「370シリーズ」のアセンブラでした。この32ビットCPUは非スタックマシンなので、スタックマシンである8080と合わせて、両タイプのCPUのアセンブラが使えるようになりました。その次に、NEC製の1チップ・マイクロプロセッサ「μPD7800シリーズ」(この型番の記憶も自信なし)を使ったハードの設計を担当しました。自分で設計したハードの検査用プログラムを作る必要があるので、このCPUのアセンブラもマスターしたわけです。このCPUボードは、アナログの入力と出力もあったので、同シリーズのうちA/Dコンバータ内蔵のCPUを用いました。8ビット時代ですから、かなり前の懐かしい話です。
 その後、パソコンの世界に入り、PC-9801で8086の、Macで68000のアセンブラを覚えました。その先は、MacのCPUがPowerPCになったのですが、TMONが対応しなかっため、PowerPCのアセンブラは真剣に調べませんでした。こうして並べると、何種類ものCPUでアセンブラを使ってますね。

解析を邪魔する仕掛けとの戦い

 市販製品の中には、逆アセンブルさせないように、特殊な仕掛けを組み込んでいるソフトもありました。モニタープログラムで解析されているかどうかアプリ自身が定期的に調べ、そうだと分かったらマシンを誤動作させて、自分のプログラムが解析されるのを阻止しようというわけです。
 誤動作の方法は2種類ありました。1つは、CPUを暴走させる方法です。暴走した状態だと、リセットスイッチを押して再起動するしかありません。もう1つは、マシンを勝手に再起動させる方法です。こちらの方は、自分で再起動させる手間が生じない分だけ、解析する側にとっては楽でした。
 こうした動作は、CPUが持つデバッガ用の機能を横取りして実現します。どんなCPUでも、デバッガがブレークポイント機能を実現できるように、専用の命令を用意しています。モニタープログラムも、それを使ってブレークポイントを設定するので、簡単に誤動作してしまうわけです。もちろん、ソフトの作者が、こういった機能を理解しているからこそ、誤動作させるように作れるのです。
 このように誤動作する場合は、その部分の命令コードを書き直して、まず誤動作しないように変更してしまいます。上記の仕組みを理解していれば、その部分を探すことが可能です。当然ながら、何度も再起動するので、見付けるまでに時間がかかってしまいます。でも、時間さえかければ必ず見付かるので、地道に探すしかありません。もし逆アセンブルするツールを持っているなら、逆アセンブルした命令コードのテキストを先頭から順番に調べ、誤動作を起こしている箇所を発見する方が早く見付かる場合もあります。どちらにするかは、そのときの感で決めるしかないでしょう。該当箇所が見付かったらパッチを当てて、誤動作しないように変更すれば、後は通常のソフトと同じように解析できます。
 誤動作させるのではなく、実行コードを暗号化してファイルに保存しているアプリもありました。最初に動く命令コードだけそのまま保存してあり、それが残りの命令コードを読み込み、暗号化した命令コードを復元してメモリ上に展開します。後は、展開後の命令コードを実行するだけです。
 こうしたソフトの場合、修正箇所を見付けても終わりになりません。暗号化した命令コードに対応させる必要があるからです。いくつか方法があります。1つは、変更後の状態を暗号化したコードを作って、ファイルを更新する方法です。もう1つは、復元したコードをファイルに保存して、復元処理をバイパスする方法です。どちらも、かなり大変な作業となります。
 以上のように、プロテクトがかかっているソフトの一部では、簡単に外されないように仕掛けを組み込んでいました。これと戦うのも、けっこう面白かったです。時間はかかりましたが、解析できたときの喜びは格別でした。

動作が調べられるなら、プロテクトは必ず破られる

 以上のような解析やパッチ当てですが、最初は非常に楽しみながらやっていました。本当に面白かったからです。全部で100本以上(おそらく200本近く。いや、もっとかも)のソフトにパッチを当てたと思います。その一部は、電子会議室に書き込んだり、連載として雑誌上で公開していました。もちろん、プロテクト外しではなく、日本語化するパッチをです。
 これだけの数をこなすと、確実に飽きてきます。対象となるソフトは新しくても、やっている内容は前と同じだからです。最後の方は、面白みをまったく感じなくなって、自分が本当に必要な場合以外は、やらなくなりました。さらに、必要だと思っても、面倒になってやらなくなったのです。最後にパッチを当ててから、もう10年近く経つでしょうか。

 ここまでの話から分かるように、ソースコードを持っていなくても、実行コードさえ得てしまえば、世の中のすべてのソフトは動きを解析できるし、改造もできてしまいます。完全なるプロテクトなど、まず不可能だと思ったほうがよいでしょう。解析や改造できる人は限られていますが、その人がやろうと思えば、絶対に破られるものなのです。
 ビデオや音楽などの暗号化も、時間さえかければ絶対に破れます。やろうとするかどうかで決まることなので、大金をもらったからとか、技術的な好奇心から解析するが出てくるでしょう。「破られるか破られないか」の問題ではなく、「破られるのはいつか」という問題なのです。暗号化する側がやれることは、少しでも破られにくく作って、破られる時期を遅らせることと、ハードウェア上の工夫などにより、破られたものを簡単に使えなくするぐらいでしょう。
 誤解する人がいると困るので、あえて言っておきますが、私はここ数年間、逆アセンブルすらしていません。ホントです。他にやりたいことが数多くあって、忙しいからです。ですから、私を疑うのはやめましょう。私のような方法で解析できる人は、それほど多くはないものの、皆さんが考えるよりは多くいると思います。ここで紹介したような解析ですが、できない人には非常に難しく思えるみたいですけど、それほど難しくはないのです。頭をそこそこ使いますが、創造性はほとんど必要ないし、根気よく続ければ何とかなる種類のものですから。というわけで、私以外の人々を疑ってください。無駄な時間を使わないためにも。
 なお、逆アセンブルした内容を効率的に解析するためのノウハウもありますが、それを公開するとプロテクト外しを手助けすることになるので、割愛しました。


下の飾り