エグゼクティブ サマリー
Cisco Talos は IDA Pro 向け GhIDA と Ghidraaas の 2 つのツールをリリースしました。
「GhIDA」は IDA ワークフローに逆コンパイラ Ghidra を統合する、IDA Pro 向けのプラグインです。シンボルの名前を変更、強調表示するための機能を備えているほか、操作画面やコメント機能が改善されるなどの特徴があります。x86/x64PE と ELF バイナリ関数を逆コンパイルできるため、リバース エンジニアリングに役立ちます。GhIDA は Ghidra のローカル インストール ファイルか、Ghidraaas(Ghidra as a Service)のいずれかを使用します。「Ghidraaas」は REST API を介して Ghidra 逆コンパイラを利用可能にする単純な Docker コンテナーです。
以下の短いビデオでは新しいツールをご紹介しています。
特長
GhIDA には次のような特徴があります。
- 逆コンパイラと逆アセンブラの各画面の同期:デフォルト設定で、逆アセンブラの画面を逆コンパイラの画面と同期できます。IDA グラフ画面またはテキスト画面のいずれかで関数をクリックすると、それに応じて逆コンパイラの画面が更新されます。関数を逆コンパイルした際に結果がキャッシュ保存されるため、関数間の遷移が速くなります。
- 逆コンパイル コードをシンタックスで強調表示:逆コンパイル コードが、pygments Python ライブラリを使用して C コードとしてシンタックスで強調表示されます。
- シンボル名をダブルクリックしてコード間を移動:逆コンパイラ画面で関数名をダブルクリック(または右クリック > [移動(Goto)] を選択)すると、選択した関数を逆コンパイラと逆アセンブラの両画面で自動的に開けます。両画面の同期が有効であれば、逆アセンブラの画面で関数を選択しても 2 つの画面で開けます。
- 逆コンパイラ画面にコメントを追加可能:逆コンパイラ画面でデフォルトの IDA ショートカット(または右クリック > [コメントの追加(Add comment)] を選択して、コメントを挿入、編集できます。各コメントは選択した行の末尾に二重スラッシュで区切られて表示されます。逆アセンブラ画面ではコメントが追加されませんが、キャッシュ保存されて逆コンパイラ画面に表示されます(同じ関数を複数回、逆コンパイルしても同様です)。
- シンボル名の変更機能:逆コンパイラ画面でシンボルを選択して N キー(または右クリック > [名前を変更(Rename)])を押すとダイアログが表示され、名前を変更できます。新しいシンボル名は、逆コンパイラおよび逆アセンブラの両画面で反映されます。Ghidra 逆コンパイラと IDA では使用されるシンタックスが異なるため、名前を変更できるのはシンボルのサブセットに限られます。逆アセンブラ画面でシンボルの名前を変更する場合は、関数をキャッシュから削除して再度逆コンパイルし、逆コンパイラ画面からシンボル名を変更する必要があります。
- シンボルの強調表示:逆コンパイラ画面でシンボルをクリックすると、他の箇所で表示されている同じシンボルもすべて強調表示されます。逆アセンブラ画面でも該当シンボルが強調表示されますが、前述のように、選択可能なシンボルのサブセットに限定されます。
- 逆コンパイル コードとコメントの保存:設定で該当オプションが選択されている場合、GhIDA は 2 つの JSON ファイルに逆コンパイル コードを保存し、IDA が閉じられる際にコメントを残します。これらの JSON ファイルやコメントは次に IDB を開くときに自動で復元されます。
インストール
- GhIDA には IDA Pro 7.x が必要です
- 次の 2 つの Python2 ライブラリをインストールします
- pip2 install requests
- pip2 install pygments
- GitHub から GhIDA リポジトリを複製またはダウンロードし、「py」と「ghida_plugin」の各フォルダを IDA Pro インストール先の「plugins」フォルダにコピーします。
- GhIDA の初回起動時(Ctrl + Alt + D を押すか、または [編集(Edit)] > [プラグイン(Plugins)] > [GhIDA逆コンパイラ(GhIDA Decompiler)] を選択して起動)に、ローカルの Ghidra インストール先または Ghidraaas サーバのいずれかを選択して使用します。ローカルの Ghidra インストール先で GhIDA を使用する場合は、次のようにします。
- Ghidra をインストール
- インストール パスに「ghidra」フォルダを作成
- Ghidraaas サーバを使用する場合は、Docker コンテナ「Ghidraaas」を使用してサーバのローカル インスタンスを起動します。
クイック スタート
IDA のグラフ画面またはテキスト画面で関数を選択し、CTRL + ALT + D を押すか [編集(Edit)] > [プラグイン(Plugins)] > [GhIDA逆コンパイラ(GhIDA Decompiler)] を選択します。数秒すると新しいウィンドウが開き、関数の逆コンパイル コードが表示されます。
逆アセンブラと逆コンパイラの 2 画面間の同期を有効にした上で、2 つを開いて左右に並べて表示させると便利です。シンボル名は逆コンパイラ画面から変更することをお勧めします(逆アセンブラ画面に自動で変更が反映されます)。
技術的な詳細
GhIDA では、Ghidra に付属の Python ライブラリである idaxml.py を使用して IDA プロジェクトをエクスポートし、(ローカル インストール先から直接、または Ghidraaas サーバから)Ghidra をヘッドレス モードで呼び出せます。追加の分析なしで逆コンパイル コードを取得できます。
GhIDA が初めて呼び出される際は、idaxml ライブラリを使用して 2 つのファイルが作成されます。IDA 分析を基にプログラムの説明が埋め込まれる XML ファイル(関数、データ、シンボル、コメントなども含む)と、 分析対象のプログラムのバイナリ コードを含むバイト ファイルです。その際にバイナリ ファイルが変更されることはありませんが、プログラム分析における更新内容を反映するため、GhIDA キャッシュを削除するたびに XML ファイルが再構築されます。GhIDA では、Python の Ghidra プラグイン「FunctionDecompile.py」を使用して逆コンパイル コードを取得します。このプラグインは、選択した関数の逆コンパイル コードを JSON ファイルにエクスポートします。
Ghidra 逆コンパイラの解説
Ghidra 逆コンパイラはスタンドアロンの C++ プロジェクトです。デコンパイラとは、DecompileProcess クラスで指定されたバイナリ プロトコルにより stdin および stout を介して通信します。一方の DecompInterface Java クラスは通信のロジックを実装します。
コンパイル プロセスでは、次の手順を実行する必要があります。
- 逆コンパイラを初期化(プロセッサの仕様などが必要)
- Java クライアントが関数の逆コンパイルを要求
- 逆コンパイラが、関数の各命令に対して PCodePacked を要求
- 逆コンパイラがシンボルとコメントを要求
- 逆コンパイルの情報を含む XML が逆コンパイラから送信
この記事では、Ghidra 逆コンパイラと直接通信する最初のステップを解説しました。ただし、PCodePacked、シンボル、コメントを逆コンパイラに送信し、最終的に出力を C コードに変換するには、記事の説明を超える複雑なプロセスが必要です。
Ghidra では、バイナリを XML ファイルまたはバイト ファイルからインポートできます。これにより、IDA からエクスポートされた Ghidra プロジェクトをインポートできます。また、エクスポート処理を容易にするための Python ライブラリを備えた IDA プラグインも提供します。より重要な特徴は、IDA からエクスポートした XML およびバイト ファイルに対して Python コマンドを(コマンドラインベースの Analyze Headless を使用して)直接実行できることです。
IDA IDB をエクスポートし、Headless Analyzer を介して Ghidra デコンパイラを呼び出すことにより、(逆コンパイル プロセスにわずかなオーバーヘッドが追加されるのと引き換えに)Ghidra デコンパイラとの下層通信を抽象化して膨大な作業量を節約できます。
本稿は 2019年9月5日に Talos Group のブログに投稿された「GhIDA: Ghidra decompiler for IDA Pro」の抄訳です。