daisukeの技術ブログ

AI、機械学習、最適化、Pythonなどについて、技術調査、技術書の理解した内容、ソフトウェア/ツール作成について書いていきます

Ghidraで始めるリバースエンジニアリング(使い方編)

前回は、リバースエンジニアリングツールである Ghidra を使って、STM32 の ELFファイルを解析してみました。

今回も、書籍「リバースエンジニアリングツールGhidra実践ガイド (Compass Booksシリーズ)」を読みながら、さらに、STM32 の ELFファイルの解析を進めていきます。

それでは、やっていきます。

参考文献

はじめに

まず、書籍「リバースエンジニアリングツールGhidra実践ガイド (Compass Booksシリーズ)」のサポートサイトは以下です。

ここからサンプルプログラムがダウンロードできます。

book.mynavi.jp

今回は、前回に引き続き、STM32 の ELFファイルの解析を進めていきます。

Ghidraの設定

Ghidra の設定、というか、使いやすいようにカスタマイズする方法が、書籍「リバースエンジニアリングツールGhidra実践ガイド (Compass Booksシリーズ)」に書かれています。その中で、私が設定した内容を書いておきます。

ハイライトの設定

Edit → Tool Options を開きます。

Listing Fields の Cursor Text Hightlight を開きます。

対象とする文字列を、マウスの真ん中ボタンを押すと、それと同じ文字列がハイライトする機能です。真ん中ボタンだと使いにくいので、左クリックに変更します。

Mouse Button To Active を MIDDLE から LEFT に変更して、Apply をクリックします。

ハイライトのボタン設定
ハイライトのボタン設定

キーバインドの設定

Edit → Tool Options を開きます。

Key Bindings を開きます。

私の設定した内容を書いておきます。また、変更はしてませんが、便利なキーバインドも書いておきます。

  • Previous Location in History(ALT-LEFT):関数の中に入った後、元の位置に戻りたいときがありますが、そのときに使える機能です、Altキーを押しながら←と→で行き来できます、今のところ、キーバインドは変更してません
  • Find References To(Ctrl-Shift-F):アドレスなどにカーソルを置いた状態で、このキーバインドを押すと、そのアドレスを参照している箇所が一覧で表示される、関数の先頭アドレスにカーソルを置いて、このキーバインドを押すと、関数の呼び出し元の一覧が表示される機能です、Ctrl+Shift+Fキーで起動できます、今のところ、キーバインドは変更してません
  • Find References to Symbol(Ctrl-Shift-F):上のFind References Toと同じ機能で、デコンパイルウィンドウで同じ機能が使えるようにする機能です、デフォルトではキーが割り当てられていませんので、Find References Toと同じ、Ctrl+Shift+Fを割り当てました

使っていくうちに、また必要なキーバインドがあれば、追記していきます。

Ghidraの機能

Function Call Graph

Window → Function Call Graph で起動します。

現在のカーソル位置にある関数を起点に Function Call Graph が起動します。

各関数をダブルクリックすると、その関数の中に入っていきます。

Function Call Graph
Function Call Graph

ちなみに、マウスのホイールを回すと、ズームイン、ズームアウトします。Ctrlキーを押しながらホイールを回すと、移動できます。

Function Graph

Window → Function Graph で起動します。

現在のカーソル位置にある関数の分岐が表示されます。

マウスのホイールの動きは、Function Call Graph と同じです。

矢印にマウスを置くと、その分岐のコードが表示されます。関数の構造が可視化されて、理解が進みます。

Function Graph
Function Graph

デバッグ情報の無いファイルを使う

これまで使ってきた、STM32 の通常の ELFファイルは、デバッグ情報を含んでいるので、ソースコードが無くても、それなりに解析が可能でした。

一方、デバッグ情報の無いファイルを試してみます。

以前(STM32(ARM Cortex-M)のELFファイル⇔バイナリの変換を行う - daisukeの技術ブログ)、以下のコマンドで、ELFファイルをバイナリファイルに変換しました。

$ arm-none-eabi-objcopy -O binary stm32f4discovery_sample.elf stm32f4discovery_sample_objcopy.bin

このバイナリファイルを読み込ませてみます。

手順で異なるところだけ示します。

Import File... で、stm32f4discovery_sample_objcopy.bin を選択すると、Language を指定してください、と出ます。

STM32F4 は、Arm v7-M のはずです。ARM v7 32bit little endian は2つあります。Compiler が default と Visual Studio です。default を選んでおきます。

Languageの選択画面
Languageの選択画面

そういえば、前回は自動認識されましたが、v7 ではなく、v8 になっていました。

解析させて、Code Browser を開きます。

うーん、undefined がいっぱい出てます。命令が認識できていません。

v7で認識させて結果
v7で認識させて結果

前回にならって、v8 を選択してみます。ダメでした。v8-m や、v8T なども選んでみましたが、うまくいきません。

仕方ないので、以前(STM32(ARM Cortex-M)のELFファイル⇔バイナリの変換を行う - daisukeの技術ブログ)、bin2elf.sh を使って、バイナリファイルから ELFファイルを再構築したもの(stm32f4discovery_sample_bin2elf_entry.elf)を使ってみます。

通常の ELFファイルと同様に、自動でファイルを認識してくれました。解析が完了すると、通常の ELFファイルと同じように認識しました。成功です。

bin2elf.shを使って再構築したELFファイルの解析結果
bin2elf.shを使って再構築したELFファイルの解析結果

デバッグ情報が無いと、プログラムの構造を理解するだけでも大変そうです。

今回はここまでにします。

おわりに

今回は、Ghidra の具体的な使い方と、機能について理解しました。

次回からは、書籍「リバースエンジニアリングツールGhidra実践ガイド (Compass Booksシリーズ)」に沿って、リバースエンジニアリングを理解していきたいと思います。

最後になりましたが、エンジニアグループのランキングに参加中です。

気楽にポチッとよろしくお願いいたします🙇

今回は以上です!

最後までお読みいただき、ありがとうございました。