※Rackサーバの方のUnicornではない.
はじめに
UnicornはQEMUベースの軽量,マルチプラットフォーム・マルチアーキテクチャ・JIT対応のCPUエミュレータ.周辺機器をエミュレーションしないため用途は限られるが,GoやPythonなど複数言語のバインディングを備えている.現在システムセキュリティ分野で最も注目されているOSSのひとつと言っても過言ではなく,AsiaCCS 2016で発表されたROPチェーン解析ツールROPMEMUや,遺伝的アルゴリズムによってROPチェーンを自動生成するツールroperのバックエンドとして用いられたり,Unicornと同じように注目を集めているバイナリ解析ツールangrとの連携が進められたりと,一大コミュニティを形成しつつある.
コンセプトの説明はBlack Hat USA 2015の発表スライドに譲るとして,ここではその利用方法と内部実装にふれる.
Pythonバインディング
情報セキュリティに興味があり,セキュリティ関係の仕事に携わりたいという人には,Pythonはうってつけの言語だ.その理由は,リバースエンジニアリングと攻撃コード作成のためのライブラリが充実しているためだ.
— Justin Seitz『サイバーセキュリティプログラミング———Pythonで学ぶハッカーの思考』序文
リバースエンジニアリングというタスクにUnicornを用いることを考える.他言語を選ぶ積極的な理由やPythonへのアレルギーがなければ,他のライブラリとの連携も考慮して,Pythonバインディングを活用すべきだろう.
エミュレーション
最もシンプルな用例:
1 | #!/usr/bin/env python |
これを実行すると次のような出力が得られる.
1 | Emulate i386 code >>> Tracing basic block at 0x1000000, block size = 0x2 >>> Tracing instruction at 0x1000000, instruction size = 1 >>> Tracing instruction at 0x1000001, instruction size = 1 >>> Emulation done. Below is the CPU context >>> ECX = 0x1235 >>> EDX = 0x788f >>> Read 2 bytes from [0x1000000] = 0x41 0x4a |
はい.
なおエミュレーション時に各命令のトレースを得たければ,同じ開発陣による逆アセンブラCapstoneのPythonバインディングを併用して(詳細は割愛)次のようなフックを用意すればよい:
1 | ... |
実行すると命令のトレースが得られる.
1 | ... >>> Tracing instruction at 0x1000000, instruction size = 1, inc ecx >>> Tracing instruction at 0x1000001, instruction size = 1, dec edx ... |
このように,Unicornではプラグイン側のエントリポイントからQEMUの機能を呼び出していくことになる.
Pythonバインディングの内部
この内部では,ctypesによる共有ライブラリのロードが行われている.unicorn/bindings/python/unicorn/unicorn.pyを見よう:
1 | for _lib in _all_libs: |
ここで_ucにunicorn.dll(環境によって異なるがいずれにせよ共有ライブラリ)がロードされている.
さて,これまで利用してきた関数のプロトタイプ宣言はunicorn/bindings/python/unicorn/unicorn.pyにある:
1 | # setup all the function prototype |
メモリ・レジスタを読み書きできることがわかる.
さきほどは基本ブロック・命令単位のコールバック関数———フック———を設置した.その他のフックも次のように書ける:
1 | mu.hook_add(UC_HOOK_BLOCK, hook_block) # 基本ブロック単位 |
こうしたフックや,これまで用いてきたレジスタやメモリの読み書き・エミュレーションといった機能はUcクラスのメソッドとして用意されている:
1 | class Uc(object): |
おわりに
PythonからUnicornを利用する方法を紹介した.
結局のところctypesでラップされており,こうした機能がどのようにして実行されるのかは本体のコードを読まなければ理解できない.そういうわけで,次回はUnicorn本体の実装を読んでいく.