才事記

リバースエンジニアリング
バイブル

コード再創造の美学

姜乘卓(ガン・ビョンタク)

インプレス 2013

[訳]金凡峻(キム・ポジュン)
編集:畑中二四 監修:金輝剛(キム・フィガン)
装幀:オガワヒロシ

各業界でREがさかんになっているようだが、ぼくとしては新しい世代が編集工学とREの蜜月をもっと深めてほしいと思っている。今夜はそのことを少し煽るために、編集術がリバースエンジニアリングによって強化されてきた例を、ちょっと小出しにしておいた。

 編集工学ではリバースエンジニアリング(RE)はほぼ日常茶飯事である。編集工学だけでなく、言語や文脈や意味を扱う仕事にはREが欠かせない。ロラン・バルト(714夜)やウンベルト・エーコ(241夜)はREの天才だった。
 中学や高校で国語の解釈問題を解いたり、授業で英文解釈をしたりさせられたりするけれど、あれもずばりREである。英文解釈はともかく(それで英語がうまくなるとはかぎらないので、それはともかく)、国語の先生はREができなければ先生になれない。言葉と文脈と意味の関係をいろいろ分解したり、再構成したりしなければならない仕事だ。ということは国語の先生はもっと自覚的な編集工学者になっていてもよかったわけだ。
 国語だけではなく、実はこれまで長きにわたって学問や科学や技術の大半が確立してきたのは、REが機能しているからであった。ただし、いささかタコ壷的なREだった。アカデミックな学問には検証や査定が必要なのだが、既存の学問はそのぶんタテ割りのREばかりにのめりこんだ。
 もったいない。知と方法の相互乗り入れが困難になった。そこで、そうした学問の形成プロセスに少しずつ分け入り、そこにひそむリバースモード(RM)に注目し(リバースの途中のプロセスに注目して)、そこに隠れていた共通性をいろいろ集め、束ねるべきを束ね、バイパスやトンネルを工事し、じょじょに編集工学を構想していったのである。
 こうして編集工学はREを基本スキルのひとつにするようになったのだが、そのようにした理由には、もっと身近なことを編集工学の観察対象にしたかったからでもあった。それは「思い出す」(recall・remind・remember)ということがアタマの中でREもどきの作業をしていることだろうとみなせたからだ。

「記憶と想起」について板書講義をする松岡
丸善創業150周年記念トーク「千夜千冊の秘密」において。
場所:代官山樫山 時:2020年8月20日

 われわれには、幼児の頃から組み上げてきたたくさんのスキルがある。バラバラに身につけたものがほとんどだが、やがて少年少女となり、青年青女になって、気がつくと「いっぱし」になっている。「いっぱし」は性徴の変化や学校経験によって、急にやってくる。だから自分がどう構成されてきたのか、自分でわからない。脳と心と体のどこでスキルがストックされたかも、わからない。
 けれども、いくつかの方法を組み合わせると「失われた時」が求められることがある。こういうプロセスにも、リバースエンジニアリングが顔を出す。
 というわけで、REはたいへん広範にわたる有効力をもつのだが、しかし今夜は、このようなREやRMをいろいろな角度で解説したいのではありません。コンピュータ・システムにとってのリバースエンジニアリングをとりあげ、その入口をスケッチしておきたい。

『リバースエンジニアリングバイブル』の原著

 本書は、本気でSE(システムエンジニア)やリバーサー(REをする当人)をめざす者のための、よくできたRE入門書だった。
 著者の姜乘卓(ガン・ビョンタク)は斯界では“window31”で知られるREの専門家であり、かつまた名うてのハッキングテクノロジストとして知られ、セキュリティ技術の解読者でもある。韓国国防部、KISA、高麗大学、NEXONなどにかかわってきた。
 一方、本書を刊行しているインプレスは、1992年に元アスキーの塚本慶一郎さんが創業したメディアカンパニーで、編集工学研究所の兄貴分にあたる会社だ。ぼくはこれまで何度もインプレスの重鎮、井芹昌信さんの力を借りてきた。井芹さんは「インターネットマガジン」を創刊し、長らく編集長を務めたインターネット博士である。

著者が運営するセキュリティブログ「Broken Code

インプレスR&D代表の井芹昌信氏
井芹氏はアスキー出版に入社後、出版技術部部長、電子編集推進室室長を務める。92年、インプレスの設立に取締役として参画。長年にわたってコンピューター関連の出版事業に携わってきた。現在はインプレスR&Dの代表取締役。デジタルファーストの次世代型電子出版プラットフォーム「NextPublishing」を運営し、「インターネット白書」の出版などIT関連メディア事業を展開している。
https://www.bcnretail.com/hitoarite/detail/20190726_129733.htmlより

雑誌「iNTERNET magazine」創刊号(1994年9月)
当時、少しずつ盛り上がりをみせていた「インターネット」を一般社会に普及させることを目的に創刊。インターネット黎明期の貴重な情報源として注目を集め、時代の象徴となった。

「iNTERNET magazine」に収録されていた“プロバイダーマップ”
全国のプロバイダー回線を図示したマップ。当時のインターネットインフラは回線速度が遅かったため、各プロバイダーの接続状況や、回線容量が知りたいユーザーが当時多かった。画像は、最後の号の付録。日本のインターネットインフラが十分に成長し、その役目に一区切りをつけた。

 それではわかりやすいところから話していくが、一般に工業製品の多くは設計図や仕様書は概略程度しか公表されない。コンピュータ・プログラムのソースコードも、最近は公開されることも少なくなくなったけれど、どんどんふえつつあるプロプライエタリ・ソフトウェア(proprietary software)はほぼ非公開である。情報セキュリティの保持が厳密になってきたからだ。けれども、よくできたプログラミングこそ、覗いてみたい。
 そういうIT業界においては、リバースエンジニアリング(reverse engineering)とは「ソースコードを逆追跡すること」をいう。だから日本語では「逆行工学」ともいうのだが、逆行というよりも「行ったり来たり工学」とか「往還工学」だと思ったほうがいい。時計を部品に分解したら、またそれらの部品を組み合わせて元の時計に戻していく。そこに「行ったり来たり」や「往還」がある。それに似て、REはその「行ったり来たり」の技能なのである。
 もっと広く工業界全般の事情でいえば、機械やシステムを分解したり、プラントや製品を検査したり、建設工程を仕上げたり確認したり、ソフトウェアの動作を解析するときに、REはのべつつかわれてきた。「ものづくり」は大小難易の差はあるけれど、すべてREをともなう仕事なのだ。
 多くの「ものづくり」の現場では、たいてい先行モデルが試作され、これにもとづいて形状や機能や属性が吟味される。このとき当初にクレイモデルやプラスチックモデルなどを先行させて、この測定値を「型」としてCADデータなどにしておかなければ、その先の仕事ができなくなる。最近はそれを3Dスキャナーや3Dプリンターでできるようにもなった。
 CAD(Computer-Aided Design)はコンピュータ支援設計というもので、そういうCAD状態をもつということが、そもそもリバースエンジニアリング状態で仕事をするということなのだ。

メルセデス・ベンツ・W196のリバースエンジニアリングの流れ
右上の絵から順に、クレイモデル、非接触カメラ撮影式の3次元計測器での形状データ測定、測定結果である点群データの張り合わせ、断面線の作成、3D CAD化、そして実車になる。

3Dプリンターで作成したセイゴオ人形

 ICTシステムにおけるREの醍醐味は、ソースコードなしにソースコードを捕捉するところにある。
 では、REによってソースコードを探りあてるにはどんな技能が必要で、その技能によってどんなことがわかってくるのだろうか。ごくごくかんたんな案内になるけれど、概略は次の通りだ。

 プログラマーが、C言語のあるコードを使ってコーディングを完了してビルドすると、ソースコードはコンピュータが理解できる言語である機械語に翻訳される。これがコンパイル(compile)処理である。
 この処理によってオブジェクト・ファイルが生成され、リンクされる複数のライブラリと結合され、最終的にEXEやDLLができあがる。EXEは“execution”の略で、そのEXEファイルがそのままアプリケーションの本体になる。DLLは“Dynamic Link Library”の略で、動的リンクをつかったライブラリのことをいう。
 このビルドされたファイルには元のソースコードの姿がなくなっている。そう見えるのだが、これをリバースエンジニアリングすると、EXEやDLLがバイナリーに解析され、元のソースコードにまで辿りつける可能性が出てくる。
 ついでPEヘッダーを解析すれば、どのライブラリがリンクされていたかもわかるし、ボタンを押したときに実行されていたコードの流れも追跡できる。ただし、コンパイラがオブジェクト・ファイルを作成してバイナリーデータをビルドしたのちの内容を、アセンブラコードで再解析しているので、元のソースコードと完全には一致はしない。この微妙な差をどう見るかはモンダイだが、実際にはSEやプログラマーの才能でカバーする。

 いっぱしのリバースエンジニアリングができるようになることを「リバーサーになる」という。REを始めるにあたって、リバーサー(reverser)になるために本書が最初にマスターしたほうがいいと勧めているのは、アセンブラを理解することである。
 アセンブリ言語で書いたプログラムがアセンブラだ。ふつう、CやC++に慣れてしまうと、アセンブラは使いにくい(と感じることが多い)。
 たとえば、冷蔵庫から水を取り出して飲むというプログラムは、C系ならば「水を飲む→冷蔵庫のドアを明ける→(bOpen==TRUE)→水を取り出す→飲む」ですむが、アセンブラでは「冷蔵庫の前に立つ」「冷蔵庫のドアを手で持つ」「冷蔵庫のドアを開ける」→(オープンに成功)→「冷蔵庫の中を見る」「手を伸ばす」「冷蔵庫の中に手を入れる」「水のボトルをつかむ」「水のボトルを取り出す」「フタを開ける」「コップを手に持つ」「コップの中身を飲む」というふうになる。
 アセンブラは1度に1つの動作しか指示できないのだ。このためアセンブラを少し覗くくらいでは、全体のプロシージャが把握できない。しかし、このアセンブラのじれったい特有性こそがリバースエンジニアリングにとってキモになる。
 したがってプログラミングの基本はC系の文法であり、リバースエンジニアリングの基本はCコードがアセンブラに変わったときに何を解釈できるかということにある。だからREにとりかかるには、アセンブラコードを覗いているとき、アセンブラの表現するかたまりをCコードに変換する「しくみ」(あるいは手立て)が、アタマの中ですぐに思い浮かんでくるようになる必要があるわけだ。

C/C++(上)とアセンブラ(下)の比較
C/C++では何行かのコードで済むものが、アセンブラに変更すると数十行数百逆行になってしまう。
『リバースエンジニアリングバイブル』p.5-6より

 次に関数を扱えるようにならなければならない。関数がわからなければ、パラメータがいくつで「戻り値」(引数=argument)としてどんなものを渡してくるかが把握できない。編集工学でも、この「戻り値」あるいは「返り値」の具合についての見当がとても重要になる。(編集工学では「問→感→応→答→返」をループさせて使う。「返」が「戻り値」にあたる)。
 REにとって厄介な作業のひとつに、プログラマーが直接コーディングした部分ではなく、ビルト時にコンパイラが自動生成したコードをフィルタリングするという作業がある。それなりのリバーサーになるには、このへんをこなせなくてはならない。それには関数を作成するときに前後に追加されるコードにどんな特徴があるかを学習しておかなければならない。
 関数の呼び出し規約(calling convention)には、_cdecl、_stdcall、_fastcall、_thiscallの4種類がある。これらがそれぞれどんな呼び出しをするのか、それがどんな引数の戻り値になりそうのか、そこらへんの勘をはたらかせたい。この勘のはたらきから、いよいよリバースエンジニアリングのまさにリバースっぽい「逆分析」(逆行工学)が始まる。
 たとえば_thiscallは、いまさしかかっているオブジェクトのポインターをECX(ループをカウントするレジスタ)に入れて渡すということをする。このことはオブジェクト指向プログラミングでどういうものが「クラス」と呼ばれているかということを想えば見当がつく。

関数の基本構造
関数sum()の場合。2行のC/C++コード(上)が、逆アセンブルされたコード(下)を見ると、10行にもなる。
『リバースエンジニアリングバイブル』p.26-27より

__fastcallを使用した関数の逆アセンブル
逆アセンブルされたコード(下)を見ると、「sub esp, 0ch」でスタック領域を確保して、EDXレジスタを使用していることがわかる。関数の呼び出しの前にEDXレジスタとECXレジスタに値を入れる箇所があったら__fastcall規約の関数だと判断できる。
『リバースエンジニアリングバイブル』p.29より

__thiscallを使用した関数の逆アセンブル
ECXに値(thisポインター)が足されていることが__thiscallの特徴。一つのクラス(抜き型)から複数の独立したオブジェクトを生成することができるため、それぞれを区別する値としてthisポインターが使用されている。
『リバースエンジニアリングバイブル』p.30より

 データとメソッドを切り離さずに一緒にしたオブジェクト指向では、①カプセル化、②継承(インヘリタンス)、③多態性(ポリモーフィズム=多相性)の活用が特徴になっている。これらはクラスとその派生関係の設定の仕方(動的なバインディング)によって維持される(初期の編集工学はこのオブジェクト志向の考え方を踏襲した)。
 つまりクラスとは、データメンバーとメソッドとが一括された情報単位なのだ。クラスにこそカプセル性と継承性と多態性がそなわっているのだ。これを発展させたのがC++のthisポインターだった。
 ということはECXにオブジェクトのポインターを入れて渡すということは、どんな異なるアドレスにいるクラスにも、リバースが効くということになる。
 ここまでくると、IF文(条件文)やループをリバースすることもできるようになる。Cコードの条件文を逆アセンブルするときでも、for、while、gotoなどのループをリバースさせるときでも、なんとか対処できるようになる。

 本書はこのあと中級の解説に入っていくのだが、詳しいことは省きたい。中級や上級を案内するには、ソースコードをあれこれ具体的に示さなければ説明できない(そんなこと、ぼくにはお手上げだ)。ただ、PEヘッダーについてはリバーサーたちがけっこう迷うようなので、一言ふれておく。
 PEは“Portable Executable File Format”の略である。プログラマーが作成したファイル(File)を、移植可能な異なるアドレスに移動しても(Portable)、実行可能に(Executable)するためのフォーマット(Format)をつくっておくということだ。
 プログラミングでは、たとえばAというコードを作成して、それをビルドすると、コンパイラはAに関連するすべてのヘッダーファイルとソースファイルを、1つの機械語にまとめてコード作成をする。ビルドを開始すると最初におこなわれることが、これだ。しかし、この状態ではコンピュータが理解できる言語ができたというだけで、ファイルの実行はできない。
 そこで続けてリンク作業にとりかかる。リンカーは当該OS上でファイルを実行できるようにするため、動的ライブラリ、いくつものリソースデータ、インポート/エクスポートテーブルを処理するための情報などを、決まった場所に書き出していく。
 このときウィンドウズなら、決まったルールにしたがって情報を用意し、EXEファイル作成時にこれらの情報をヘッダーとして示す。これがPEヘッダーに当たるものである。
 こうしてPEヘッダーには実行ファイルを動かすためのいろいろな情報が記録されていることになる(1冊ずつの本がヘッダーに含まれたようなものだ)。実行ファイルはメモリにロードされるとき、PEに含まれている実行をもとにDLLをロードして、さまざまなリソースのためのメモリ空間を割り当てる(1冊ずつの本がそれぞれの本棚に並ぶようなものだ)。
 このようになっているので、EXEやDLLを実行すると、プログラマーが作成したコードが実行される前に、OEヘッダーから情報を取り出すことが可能なのである。

PEファイル生成処理のプロセス図
『リバースエンジニアリングバイブル』p.83より

ツール「VX PE-Viewer」の画面
PEの各構造体やメンバーをクリックすると、実際にそれらがPEフォーマットのどの部分に位置し、範囲はどこからどこまでかをブロックで表示してくれるツール。
『リバースエンジニアリングバイブル』p.84より

 ざっと、こんなふうに本書は進んでいく。いま説明したところまでで100ページくらい、全体は380ページあるので4分の1だ。もしもプログラミングが未体験で、それでもREスキルのなんらかの特徴に関心のある一般読者がいるなら、ぜひとも本書を覗いてみられるのがいいだろう。
 ハウトゥー本ではあるが、著者が「技」の好き嫌いを洩したり、ときどき「REの心」を綴っているので、何かとても大事なことが伝わってくるはずだ。

 冒頭にも書いたように、リバースエンジニアリングはかなり多くの領域で活躍している。ゲーム業界でも早々に重視された。REゲームというものも、かなりある。カードゲーム、RPG、FPS、MMOなど、いずれにもREが適用されている。
 会社をリバースエンジニアリングするというビジネスもふえてきた。「フォーブス」が、オーストラリアのアジャイル型ソフト開発会社アトラシアン社をREしたリックソフト社の大貫浩を紹介していた。アトラシアン社をREすることで、自社の東証マザーズ上場したという例だ。大貫は、日本人の発想にはリバースエンジニアリングが適していると言っている。俳句や文楽が日本的リバースエンジニアリングの好例だ。
 各業界でREがさかんになっているようだが、ぼくとしては新しい世代が編集工学とREの蜜月をもっと深めてほしいと思っている。今夜はそのことを少し煽るために、編集術がリバースエンジニアリングによって強化されてきた例を、ちょっと小出しにしておいた。

国際ハッキング大会のワンショット
国内外で毎年いくつもの大会が開催され、リバースエンジニアリングを利用したキー生成の問題も出題される。
『リバースエンジニアリングバイブル』p.167より

海外のウイルスソフトメーカー主催のF-Secura大会のメイン画面(左)と出題問題(右)
2007年に開催。100%オンラインで行われ、F-Securaが提供するリンクをたどっていって、プログラムをダウンロードして問題を解くと次の問題に進める。Level3まで3つの問題を解決すると合格、F-Secureに入社するチャンスが与えられる。
『リバースエンジニアリングバイブル』p.168-169より

 編集工学ではコンピュータ支援を借りずにアタマの中でその状態に入ることを、「編集的現在に立つ」というふうに見る。けれども、ふだんのわれわれは自分がどのようにリバースエンジニアリングができるのか、どういう編集的現在にいるのか、なかなかわからない。とくに自分の意識がそのリバースモードに入っていても、そのプロセスが取り出せない。
 そこで編集工学では、自分なりの連想やアナロジーのプロセスを意識上の「注意のカーソル」をつかって逆追跡し、ナマREやナマRMの渦中を覗くエクササイズをする。とくに連想をトレースする。それを試みられるようにしたのがイシス編集学校だ。かなりおもしろい学校になっている。すでに750人をこえる師範代が活躍している。
 いまやどんな思考作業にも(表現作業にも)コンピュータは欠かせなくなってはいるが、そのコンピュータ(=スマホ)に支援されたわれわれが、その支援のしくみをヒントに、あらためてナマの思考性や表現性を掴み出すことは、十分に可能なのである。だから、たまにはリバースエンジニアリングのしくみをコンピュータから逆学習することも、オツに感じられるにちがいない。今夜はその「感じ」を伝えるための千夜千冊だった。
 もう一言、加えよう。リバースエンジニアリングのコツは体も知っている。先だって体操の内村航平が種目を鉄棒に絞って東京オリンピックに向かうことを決断したドキュメンタリーを見たが、そのなかで内村がしきりに手や体を動かして、自分がかつてなしとげてきた凄技をリバースしようとしていた。
 体全体がREをおぼえているばかりではない。このことは手のひらにおいても成り立ってきた。轆轤や手びねりで茶碗をつくっていても、その「手」はたえずREをくりくえしているはずなのだ。手のひらもREをおぼえているはずなのだ。
 このように見てくると、リバースエンジニアリングはもっともっとふだんの思考や表現において普及されていいと思われてくる。REを特殊技能化せずに、できるだけ「ふだん使い」することを奨めたい。

(図版構成:寺平賢司)


⊕『リバースエンジニアリングバイブル-コード再創造の美学』⊕

∈ 著者:姜秉卓
∈ 監修:金輝剛
∈ 訳者:金凡峻
∈ 発行者:土田米一
∈ 発行所:株式会社インプレス
∈ 発行:2013年9月20日

⊕ 目次情報 ⊕

∈ 第1部 リバースエンジニアリングの基本
∈ 01章 リバースエンジニアリングのためだけのアセンブラ
∈ 02章 C言語の文法と逆アセンブル
∈ 03章 C++のクラスとリバースエンジニアリング
∈ 04章 DLLの分析

∈ 第2部 リバースエンジニアリング中級
∈ 05章 PEヘッダー
∈ 06章 よく使われるパターン
∈ 07章 MFCリバーシング

∈ 第3部 演算ルーチンリバーシング
∈ 08章 シリアルキー抽出法
∈ 09章 コードフェイキング

∈ 第4部 アンチリバースエンジニアリング
∈ 10章 教科書的なアンチデバッグ
∈ 11章 ハイレベルなアンチデバッグ
∈ 12章 パッカーが使用する技術
∈ 13章 回避方法

∈ 第5部 一段階高いレベルのバイナリ作り
∈ 14章 コードフック
∈ 15章 コードパッチング
∈ 16章 難読化とダミーコード

⊕ 著者略歴 ⊕
姜秉卓(ガン・ビョンタク)
window31というニックネームで活動し、韓国雑誌『月刊マイクロソフト』に約3年間、リバースエンジニアリング、悪性コードなど、ハッキング、セキュリティ関連の記事を連載した。韓国国防部、KISA、侵害事故対応協議会、高麗大学、KAIST大学、弘益大学などで数回にわたり、リバースエンジニアリングのための講義を行う。韓国国内では最初にデベロッパー・セキュリティ分野でマイクロソフトMVPを受賞しており、セキュリティのブログBroken Codeを運営しながら、各種ハッキング/セキュリティ・テクニカル・コラムを作成している。現在はNEXON Americaの情報セキュリティチームリーダーとして、アメリカ支社のセキュリティ業務を担当している。

⊕ 訳者略歴 ⊕
金凡峻(キム・ボムジュン)
1974年11月生まれ。法政大学経営学部出身。大学時代に趣味でプログラミング勉強し、韓国に帰国後、家庭用デジタル機器製作会社で組み込みエンジニアとして勤務する。2006年、再び日本に渡り、TVレコーダー制作会社およびゲーム会社に勤務する。2012年に帰国し、現在は韓国でプログラミング関連の書籍の執筆や翻訳を行っている。主な著書に、『作りながら学ぶOSカーネル』、『脳を刺激するハードウェア入門』、『UNITYで作るスマートフォン3Dゲーム開発講座』などがある。