🐷

Ghidraのデコンパイル結果をGDBから使いたい

2022/12/04に公開

これはCTF tools/tips Advent Calendar 2022の四日目の記事です。

モチベーション

  • CTFでpwnの問題が渡されたが、シンボル情報もソースコードも無い
  • Ghidraでデコンパイルした情報を他でも使いたい。
  • デバッグする時にデータ構造などがわかったら自明に嬉しい

というときに、デコンパイルしたソースをバイナリにくっつけたい。

方針

Ghidraで解析した後、ghidra2dwarfを使ってバイナリにdwarf情報をくっつける。

手順

例として、手元のgccでコンパイルし、さらにstripしたバイナリを使います。

ghidra2dwarfを入れる

ghidra2dwarfはghidraの拡張機能で、コパンパイルしたソースコードや型情報などをまとめ、バイナリとして出力する機能を追加してくれます。
今回の場合、拡張機能はPythonで書かれており、スクリプトが存在するディレクトリをGhidraの拡張機能パスに追加することで使用可能になります。

まず、リポジトリをクローンしてきて、内部で使われる動的オブジェクトの準備をします。

$ git clone https://github.com/cesena/ghidra2dwarf
$ cd ghidra2dwarf/
$ cp ./lib/target/libdwarf.jar ./src

次に、Ghidraを起動し、Window->Script Managerを開き、右上の Manage Script Directories を押します。

更に、表示されたウィンドウ右上の追加ボタンで、先程用意したディレクトリ中のsrcを指定します。

Script Managerまで戻り、ghidra2dwarfを検索して、ちゃんと認識されていることを確認してください。

出力する

実際にstripされたバイナリmain_binaryを解析し、デバッグシンボルをつけてみます。
いつも通りに解析し関数名や型付けが一通り終わったタイミングで、先程と同じ様に Script Managerを開きます。
ghidra2dwarf.py を検索し、上の再生ボタンを押して起動します。

すると、プロジェクトファイルの下に、main_binary_dbgmain_binary_dbg.c が生成されます。
前者がデバッグ情報の付いたバイナリで、その内部で後者のソースコードへ対応がつけられています。

バイナリとして main_binary を実行しつつ、シンボル情報として main_binary_dbg を使うため、次のようなコマンドを使って gdb を起動します。

$ gdb -exec=./main_binary -s=./main_binary_dbg

起動すると、main_binary_dbg からデバッグ情報を読み込んだという旨のログが出力され、実際に break main とすると main 関数にブレイクポイントを設置することができることがわかります。

(余談)exploit書く時のpwntoolsで使う

Pwnの問題を解く時に使うライブラリである pwntools には、内部で gdb を起動し、デバッグしながら攻撃の状況を得る関数 gdb.debug が用意されています。
この関数に先程作成したデバッグ情報を認識させるためには、次の様に書く必要があります。

io = gdb.debug("./main_binary", exe="./main_binary_dbg")

実際に実行すると、起動したgdbからデバッグ情報が使える事がわかります。

終わりに

誤字・脱字・間違い等があればご指摘いただければ修正します。
コメントでもTwitter(@iwancof_ptr)でも

Discussion