CYBIRDエンジニア Advent Calendar 2014 4日目の@to-takahashiです。
最近、長時間プログラムをしていると腰が痛くなるようになってきました。。
何かの記事で読んだのですが、運動などをして体が疲れた状態になっていると頭の回転があがる・・というのを信じて朝、近所の土手をジョキングするようにしています。
(メタボ率も下がり一石二鳥w)
昨日は@decokunのなぜBackbone.Modelのchangeイベントが発火しないかについての2つの陥っていがちなパターンでしたね。
ただ今JS勉強中なので、今度Backboneでアプリ開発する時には参考にさせてもらおうと思います。
今回は「バイナリとわたし」と題しまして、バイナリファイルってこんなに身近なんだよってことをお伝えしたいと思います。
バイナリとの出会い
わたしが最初にバイナリファイルと出会ったのは、学生時代にバイトしていたソフトハウス(当時はこう呼ばれていました)で、PC版ゲームのデバッグのアルバイトをしている時でした。
スーパープログラマーのような人がマスターディスクにコピー防止のプロテクトコードを埋め込んでいたりしるのをみて、何だかよくわからないけどスゴイな・・と感じたことを記憶しています。
社会人デビューした後は、スーファミとかアーケード基盤とかのゲーム開発に携わっていたこともあり、最初に学んだプログラム言語がアセンブラだったりしたので、自然とバイナリデータには慣れ親しんでいきました。
バイナリと仲良くなると何がうれしいの?
画像データのヘッダ部分をちょっと書き換えて簡易暗号化(って呼んでよいか微妙ですが・・)するとか、ゲーム開発時に画像データの中に当たり判定に利用するビットを埋め込んだり、、大昔しに開発されたライブラリ中の処理の内容を確認したかったけれどソースがどうしても見つからず、バイナリをディスアセンブラして該当ロジック部分の仕様を確認・・なんてこともできます。
最近ではスマートフォンのアプリ開発をする機会が増えて、昔のようにROMにバイナリを焼くようなことも無くなり、アセンブラという単語自体も死語になりつつあると感じる今日この頃、16進数の羅列を眺める機会も減ってきているのには寂しさを感じます。
バイナリファイルをのぞいてみましょう
とはいえ、バイナリファイルをのぞいてみることで、いろいろな情報を得ることができる場面もまだまだありますので、いくつか紹介したいと思います。
Exif(イグジフ)
Exchangeable image file formatの略で、デジカメの画像保存などに使われています。
http://ja.wikipedia.org/wiki/Exchangeable_image_file_format
例えば、写真を撮影した時に保存されるJPEGファイル中には以下のような情報が埋め込まれています。
・ 撮影日時
・ 撮影時のGPS情報(緯度・経度)
・ 画像データ
・ サムネイルデータ など
自宅で撮影した場合などは撮影場所が特定されてしまうのでちょっと怖いですね。
また、上記の「画像データ」はいわゆる目にみえる(表に出ている)画像となりますが、それとは別にサムネイル画像のデータが保存されている場合があります。
目に見える画像データの方にはモザイクをかけたけど、サムネイルの方はそのまま出回ってしまったなんてこともありますので注意が必要です。
また、これらのExif情報を表示したり編集したりするソフトも多く出回っていますので、意図的にGPS情報が書き換えられていたなんてこともあるかもしれません。
iOSの .ipaファイル
iOSでAdhocや申請用アプリをエクスポートするとできるやつです。
この".ipa"ファイルですが、拡張子を".zip"に変更するとZIPで簡単に解凍することができます。
以下、".ipa"ファイルの中身です。
・ /Payload/
・ /Payload/Application.app/
・ /META-INF/
・ /iTunesArtwork
・ /iTunesMetadata.plist
アイコン画像やプログラムコードが含まれていることがわかります。
さらに、上記のApplication.appと以下のようなコマンドラインツールでいろいろな情報を取得することが可能です。
otool
リンクしているライブラリ一覧やディスアセンブルした結果を確認する事ができます。
strings
バイナリに含まれているObjective-CのSelectorを出力できます。
iOSの Provisioningファイル
個人的にはこちらのファイルをのぞく機会が一番多いです。
バイナリファイルではありますが、メモ帳などで開くことでファイル中の以下のようなテキスト情報を読み取ることができます。
・ プロビジョニングの有効期限
・ インストールすることができるデバイスID
・ ProductIDやチームID
Adhocのインストールがうまくいかなかった時などに、ちょっと覗いてみると解決につながるヒントが見つかるかもしれません。
さらに一歩進めてリバースエンジニアリングについて
リバースエンジニアリングとは、プログラムコードのバイナリデータ(16進数の羅列)からソースコードを逆追跡することです。
最近では、スマートフォン業界でもセキュリティについての話題が多く、「リバースエンジニアリング」という単語もチラホラと聞くようになってきたと感じます。
リバースエンジニアリングを極めることで以下のようなことができるようになります。
・ アプリケーションの脆弱性の調査
・ バッファオーバーフローする可能性はないか?
・ 暗号化や複合化のロジックに弱点はないか?
・ セキュリティ対策
・ バグ修正
(但し、上記のようなことを実際に行おうとする場合、元のソースコードをイメージしたり、理解できなければいけないため、非常に高度なプログラミングスキルが求められます。)
リバースエンジニアリングについて何の考慮もされていないアプリケーションの場合、例えばAPIの接続先のURLやパスワード等の文字列が簡単に読み取れてしまうようなこともありますが、リバースエンジニアリングによってこんなことができちゃうんだ・・ということを理解・把握しておけば難読化やその他のいろいろなセキュリティ対策に活かせるかもしれません。
最後に・・
バイナリの中身を解析する行為って合法なの? と疑問に思う方も多いと思います。
法律的に全く問題がないかというと確かに微妙なところが多く、いろいろな議論が行われているのが現状です。
市販されているソフトウェアや他者が作成したバイナリファイルを変更することは間違いなく違法ですので絶対に行ってはいけません。
一方、メモリ上にロードされたコードに変更を加えることについては、合法・違法の意見が分かれている状況です。
リバースエンジニアリングはその使い方によって、正義にも悪者にもなり得る可能性がありますので注意が必要です。
個人的にはバイナリの構成やリバースエンジニアリングに興味を持つことで、ハードウェアやOS、コンパイラの知識、アセンブラやC言語の知識も必要になり、間違いなくエンジニアとしてのスキル向上につながると思っています。
プログラムが動く原理を根本から理解していれば、どんな新しいプログラム言語が出てきても全く怖いことはないはずですので、これからも一歩抜きん出たエンジニアになれるよう精進していきたいと思います。
みなさまにもバイナリファイルをちょっとでも身近に感じていただけたら幸いです。
明日は@hosokawa-yutaさんです。
楽しみですねー