CodeIQ Blog

自分の実力を知りたいITエンジニア向けの、実務スキル評価サービス「CodeIQ(コードアイキュー)」の公式ブログです。

バイナリアンになろう!『たのしいバイナリの歩き方』 #book #binary

CodeIQの中の人、hnanami です。

今回は、『たのしいバイナリの歩き方』の著者である、株式会社FFRIの愛甲健二さんから寄稿いただきました。

f:id:codeiq:20131109162210j:plain
発売直後に増刷も


===============================

はじめまして。愛甲健二と申します。

普段は株式会社FFRIというセキュリティ系の会社でプログラマをやっています。得意な言語はCとアセンブラで、アセンブラはx86系がメイン、サブでARMといった感じです。

アセンブラを扱うプログラマというのは少しめずらしいかもしれませんが、「仕事で」というよりも、使っているツールやコンパイラの仕組みなどを調べているうちにいつの間にかローレイヤーの世界に足を踏み入れた感じになってしまいました。もしかしたらわりと古いタイプのエンジニアかもしれません(汗)。

さて、今日は「バイナリの楽しさを知ってもらいたい」ということで、今年の7月に発売された『たのしいバイナリの歩き方』を執筆していたときに感じていたことをメインに、バイナリ系の技術について紹介させいただきたいと思います。

バイナリで遊ぼう ~「アセンブラ短歌」、ご存じですか?

「仕事において必要かどうか」で技術を学ぶこともありますが、単純に「おもしろいからやる」ということもありますよね。特に「バイナリアン」と呼ばれる人にはそういう方が多いようにも思えます。

たとえば、皆さんはアセンブラ短歌というものをご存じでしょうか。

6a 00 58 50 40
68 79 61 6d 61 50 40
6a 08 5a 5b 40
68 57 61 6b 61 54 40
59 cd 80 58 58 58 c3

http://kozos.jp/asm-tanka/

ご覧のとおり、五・七・五・七・七、三十一バイトのただの機械語ですが、これをLinux環境で実行すると「Wakayama」と表示されます。

また、この機械語は五・七・五・七・七それぞれでアセンブラ命令が区切られており、五・七・五・七までの4ブロックは終端がすべて0x40で一致しています。つまり“韻をふんでいる”わけです。

ちなみに、最初の行をアセンブラ命令にすると、以下のようになります。

・6a 00 = push 0
・58 ⇒ pop eax
・50 ⇒ push eax
・40 ⇒ inc eax

つまり、最初の五バイトでeaxをゼロクリアしてスタックに戻し、さらに1加算する、といった処理をしているのです。

アセンブラ短歌は、坂井弘亮氏が考案したもので、公式サイトでは次のように説明されています。

「アセンブラ短歌」は五・七・五・七・七の三十一バイト(みそひとバイト)から成る機械語コードでプログラムを書いてみるという近未来の文化的趣味であり、近年、国内のハッカー間で密かなブームが起きています。

http://kozos.jp/asm-tanka/

「機械語を短歌に見立てる」というなんともユニークな発想ですが、いかにも“コンピュータで遊ぶ”というHacker的なアイディアではないでしょうか。

しかも、このアセンブラ短歌を解説する書籍も発売されるようです。アセンブラ短歌に関するくわしいことは坂井弘亮氏の公式サイトに載っていますので、興味がわいた方はぜひ立ち寄ってみてください。

またアセンブラ短歌をブラウザ上で楽しめるサイトAssembler Tanka on Javascriptもあります。よかったら遊んでみてください。

機械語を解析する仕事もあります

アセンブラ短歌は遊びですが、機械語を扱う仕事もあります。

21世紀になって久しく、いまやブラウザ上で3Dゲームがプレイできるこの時代に「まさか機械語を扱う仕事があるなんて!」と思われるかもしれませんが、実際にあるのです。

たとえば、アンチウイルスソフトを開発している大手企業は、コンピュータウイルスの解析者、いわゆるリバースエンジニアを多く雇っています。彼らの仕事は、日々発見されるコンピュータウイルスを分析することです。もちろん、コンピュータウイルスにソースコードなどはありませんから、機械語を読み解いていく以外に動作を解析する手段はないのです*1。なので、彼らはプログラミングとは別に、アセンブラを始めとしたリバースエンジニアリング技術(解析技術)も持ちます。

「アセンブラなんて……」と思われるかもしれませんが、コンピュータセキュリティの分野ではいまだその技術は求められているのです。

セキュリティの競技大会ではこんな問題が出題されます

CTF(Capture the Flag)という言葉を聞いたことはありませんか。これはセキュリティ技術を競い合う大会のひとつで、バイナリ、Web、ネットワーク、暗号といったさまざまな分野のセキュリティ技術に関する課題をチームで攻略していくものです。

最も大きな大会はDEFCON CTFと呼ばれるもので、毎年夏にラスベガスで決勝戦が行われます(予選はオンライン)。このCTFは、DEFCONという毎年1万人以上が集まる世界最大級のセキュリティカンファレンスのメインイベントのひとつとして開催されており、世界的にも注目される大会なのです。

そんな大会で以前出題されたバイナリ分野の問題を紹介しましょう。

問題:何の関数であるかを答えよ
00000000  89C7           MOV EDI, EAX
00000002  89DE           MOV ESI, EBX
00000004  89CA           MOV EDX, ECX
00000006  C1E9 02        SHR ECX, 2
00000009  F3:A5          REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
0000000B  89D1           MOV ECX, EDX
0000000D  81E1 04000000  AND ECX, 3
00000013  F3:A4          REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
00000015  C3             RETN

左端がアドレス、真ん中に機械語があり、そしてアセンブラ命令となっています。

このコードを解読して、何の関数であるかを答えます。x86を知っている方なら数秒でわかるものですが、一般的なプログラミング言語(高級言語)を知っているだけでは解けないかもしれません。ちなみに答えは「memcpy」です。

もちろん、ソフトウェア開発ではこのような技術が必要になる機会はあまりないでしょう。Java、C#、JavaScript、Ruby、Pythonなどなど、ソフトウェア開発に向いているプログラミング言語は山ほどあります。しかし、コンピュータウイルスの分析や脆弱性攻撃を行うExploitの調査などを主目的とするセキュリティ企業では、いまだ機械語の技術が必要になることが多々あるのです*2

アセンブラを学んでみよう

機械語、アセンブラ、バイナリといった分野は、ソフトウェアエンジニアとしては少し特殊な技術かもしれません。では、どうやったらこのような技術を学べるのでしょうか。

まずは、学習に役立ちそうなツールを紹介しましょう。

Windows環境ならば、以下のツールがよく使われます。

IDA
 -逆アセンブラ

OllyDbg
 -デバッガ

Stirling
 -バイナリエディタ

IDAは、高機能な逆アセンブラで、有償版は数万円もする高価なソフトウェアなのですが、デモ版や廉価版(フリー版)も提供されています。初心者が学ぶだけならば、廉価版でも十分に有用です。

OllyDbgは汎用デバッガで、こちらはフリーウェアです。WindowsならWinDbgや開発環境に付属するデバッガを使うのが一般的かもしれませんが、わかりやすさ、解説記事の多さ、プラグインの充実度などの理由で、よく使われます。

Stirlingは一般的なバイナリエディタです。

これらに加えて、アセンブラとリンカがあれば、学ぶには十分です。それぞれ、以下を使いましょう。

NASM
 -アセンブラ

ALINK
 -リンカ

NASMはバージョン2.10.09を、ALINKはWin32 versionとWin32 Import library(win32.lib)をダウンロードしてください。

Hello World!と書かれたメッセージボックスを表示するプログラムは次になります。

hello32.asm
extern MessageBoxA
section .text
global main
main:
    push dword 0
    push dword title
    push dword text
    push dword 0
    call MessageBoxA
    ret
section .data
    title: db 'MessageBox', 0
    text: db 'Hello World!', 0

hello32.asmを用意してNASMでobjファイルを、ALINKでexeファイルを生成します。

コマンドプロンプト
C:\nasm-2.10.09>nasm -fwin32 hello32.asm
C:\nasm-2.10.09>alink -oPE hello32 win32.lib -entry main
ALINK v1.6 (C) Copyright 1998-9 Anthony A.J. Williams.
All Rights Reserved

Loading file hello32.obj
Loading file win32.lib
matched Externs
matched ComDefs
Generating PE file hello32.exe

まず、hello32.exeを実行すると、メッセージボックスが表示されます。

また、hello32.exeをIDAで開くと、逆アセンブルされたコード(といってもhello32.asmと同じですが)が表示されます。

そしてOllyDbgを使うと、1命令ずつの実行結果を追うことができます。

hello32.exeは自分で書いたアセンブラコードから出力した機械語なのであまりおもしろくはありませんが、C言語で記述しgccのようなコンパイラで生成した実行ファイルを眺めてみると、自分が書いたプログラムがどのような機械語に変換されているかを確認できます。普段意識していなかったローレイヤーな部分が垣間見れて、おもしろいですよ。

著書である『たのしいバイナリの歩き方』でも、おもしろさを重視した内容でバイナリを解説しています。もしバイナリ系の技術に興味があれば、ぜひ読んでみてください。

コンピュータの世界は、次から次へと新しい技術が生まれるため、「エンジニアは学び続けなければならない」とよく言われます。それはその通りだと思いますが、ただいくら変化が速く、流行が変わっても情報工学の基本が大きく変わるわけではありません。

5年前、10年前にも存在して、きっと5年後、10年後にも存在するような技術も、また数多くあると思います。機械語、アセンブラをはじめとしたバイナリ系の技術も、またそうであると感じています。

ぜひみなさんも、バイナリ系の技術に触れてみてください。


エンジニアのための新しい転職活動!CodeIQのウチに来ない?の特集ページを見る

*1:実際は、機械語をアセンブラコードに変換したものを解読していきます。

*2:ちなみに、紹介した問題はDEFCON CTF 2008のオンライン予選において、バイナリ分野の1問目として出題されたものです。