マスタリングGhidra
基礎から学ぶリバースエンジニアリング完全マニュアル
- Chris Eagle、Kara Nance 著、石川 朝久 監訳、中島 将太、小竹 泰一、原 弘明 訳
- 2022年05月 発行
- 668ページ
- ISBN978-4-87311-992-2
- フォーマット Print PDF ePub
- 原書: The Ghidra Book: The Definitive Guide
5,280円
書籍のご注文はオーム社サイトへ
内容
本書は、NSA(米国家安全保障局)が公開したソフトウェアリバースエンジニアリングツール「Ghidra」の総合的な解説書です。ソフトウェア・ハードウェア製品の構造を分析し、動作やソースコードなどの技術情報を調査し明らかにするリバースエンジニアリングの基礎からGhidraの高度なテクニックまで紹介し、リバースエンジニアリングの初心者から経験豊富な実務者まで学ぶことができます。内容は大きく5部に分かれ、第I部はディスアセンブル、リバースエンジニアリング、およびGhidraプロジェクトについて、第II部はGhidraの基本的な使い方、第III部はGhidraをカスタマイズして自動化する方法、第IV部は特定のGhidraモジュールのより詳細な説明、第V部はリバースエンジニアが遭遇する可能性のある状況にGhidraをどのように適用できるかを紹介しています。
関連書籍
目次
目 次
謝辞
訳者まえがき
はじめに
第I部 リバースエンジニアリング入門
1章 ディスアセンブル入門
1.1 ディスアセンブルの原理
1.2 ディスアセンブルとは
1.3 なぜディスアセンブルが必要なのか
1.3.1 マルウェア解析
1.3.2 脆弱性の分析
1.3.3 ソフトウェアの相互運用性
1.3.4 コンパイラの検証
1.3.5 デバッグ時の表示
1.4 どのようにディスアセンブルするか
1.4.1 ディスアセンブルアルゴリズムの基礎
1.4.2 線形掃引ディスアセンブル
1.4.3 再帰下降ディスアセンブル
1.5 まとめ
2章 リバースエンジニアリングツール
2.1 ファイルの識別
2.1.1 file
2.1.2 PE Tools
2.1.3 PEiD
2.2 ファイルの概要把握
2.2.1 nm
2.2.2 ldd
2.2.3 objdump
2.2.4 otool
2.2.5 dumpbin
2.2.6 c++filt
2.3 ファイルの詳細分析
2.3.1 strings
2.3.2 ディスアセンブラ
2.4 まとめ
3章 Ghidraとの邂逅
3.1 ライセンス
3.2 対応 OS
3.3 公式ドキュメント
3.4 ダウンロード
3.5 インストール方法
3.5.1 ディレクトリ構成
3.5.2 起動方法
3.6 まとめ
第II部 Ghidraの基本的な使い方
4章 Ghidra入門
4.1 Ghidraを起動する
4.2 新しいプロジェクトの作成
4.2.1 ファイルの読み込み
4.2.2 Raw Binaryローダを使う
4.3 Ghidraによるファイル解析
4.3.1 Auto Analysis結果
4.4 初期解析時の Ghidraの挙動
4.4.1 作業内容の保存と終了
4.5 Ghidraを使うためのヒントとコツ
4.6 まとめ
5章 Ghidraによるデータ表示
5.1 CodeBrowser
5.2 CodeBrowserの各種ウィンドウ
5.2.1 Listingウィンドウ
5.2.2 Function Graphビュー
5.2.3 Program Treesウィンドウ
5.2.4 Symbol Treeウィンドウ
5.2.5 Data Type Managerウィンドウ
5.2.6 Consoleウィンドウ
5.2.7 Decompilerウィンドウ
5.3 その他のウィンドウ
5.3.1 Bytesウィンドウ
5.3.2 Defined Dataウィンドウ
5.3.3 Defined Stringsウィンドウ
5.3.4 Symbol Tableウィンドウと Symbol Referencesウィンドウ
5.3.5 Memory Mapウィンドウ
5.3.6 Function Call Graphウィンドウ
5.4 まとめ
6章 Ghidraによるディスアセンブルの理解
6.1 ディスアセンブル結果の調査
6.1.1 シンボルとラベル
6.1.2 ナビゲーション
6.1.3 Go To
6.1.4 ナビゲーションの履歴
6.2 スタックフレーム
6.2.1 関数呼び出しの仕組み
6.2.2 様々な呼び出し規約
6.2.3 その他の考慮事項
6.2.4 ローカル変数のレイアウト
6.2.5 スタックフレームの例
6.3 Ghidraでのスタックの表示
6.3.1 スタックフレームの解析
6.3.2 Listingビューでのスタックフレーム
6.3.3 デコンパイラを用いたスタックフレームの解析
6.3.4 オペランドでのローカル変数
6.3.5 Stack Frame Editor
6.4 検索
6.4.1 Search Program Text
6.4.2 Search Memory
6.5 まとめ
7章 ディスアセンブル結果の操作
7.1 名前とラベルの操作
7.1.1 引数名とローカル変数名の変更
7.1.2 ラベル名の変更
7.1.3 新しいラベル
7.1.4 ラベルの編集
7.1.5 ラベルの削除
7.1.6 ラベルによるナビゲーション
7.2 コメント
7.2.1 EOLコメント
7.2.2 プレコメントとポストコメント
7.2.3 プレートコメント
7.2.4 リピータブルコメント
7.2.5 引数とローカル変数へのコメント
7.2.6 アノテーション
7.3 基本的なコードの変換
7.3.1 コード表示設定の変更
7.3.2 オペランドのフォーマット
7.3.3 関数に対する操作
7.3.4 データからコードへの変換
7.4 基本的なデータの変換
7.4.1 データ型の変換
7.4.2 文字列の検索
7.4.3 配列の定義
7.5 まとめ
8章 データの型と構造
8.1 データを理解する
8.2 データ構造を理解する
8.2.1 配列のメンバへの参照
8.2.2 構造体メンバへの参照
8.3 構造体を Ghidraで作成する
8.3.1 新しい構造体の作成
8.3.2 構造体のメンバの編集
8.3.3 構造体のレイアウトの適用
8.4 C++で書かれたプログラムのリバースエンジニアリング
8.4.1 thisポインタ
8.4.2 仮想関数と Vftable
8.4.3 オブジェクトのライフサイクル
8.4.4 名前マングリング
8.4.5 ランタイムの認識
8.4.6 継承関係
8.4.7 有用なリファレンス
8.5 まとめ
9章 相互参照
9.1 参照の基礎
9.1.1 相互参照(後方参照)
9.1.2 参照の例
9.2 Reference Managementウィンドウ
9.2.1 Xrefsウィンドウ
9.3 まとめ
10章 グラフ
10.1 基本ブロック
10.2 Function Graph
10.3 Function Call Graph
10.4 Tree
10.5 まとめ
第III部 Ghidraを使いこなす方法
11章 コラボレーションSRE
11.1 チームワーク
11.2 Ghidra Serverのセットアップ
11.3 共有プロジェクト
11.3.1 共有プロジェクトの作成
11.3.2 プロジェクト管理
11.4 Projectウィンドウのメニュー
11.4.1 Fileメニュー
11.4.2 Editメニュー
11.4.3 Projectメニュー
11.5 プロジェクトとリポジトリ
11.5.1 バージョン管理
11.5.2 シナリオ例
11.6 まとめ
12章 Ghidraのカスタマイズ
12.1 CodeBrowser
12.1.1 ウィンドウの再配置
12.1.2 ツールオプションの編集
12.1.3 ツールの編集
12.1.4 ツールのカスタム設定
12.1.5 CodeBrowserのレイアウトを保存する
12.2 Ghidra Projectウィンドウ
12.3 ツール
12.4 ワークスペース
12.5 まとめ
13章 Ghidraの機能拡張
13.1 ファイルのインポート
13.2 アナライザ(Analyzer)
13.3 単語モデル
13.4 データタイプ
13.4.1 新規データ型アーカイブの作成
13.5 Function ID
13.6 Function IDプラグイン
13.6.1 Function IDプラグインの例:UPX
13.6.2 Function IDプラグインの例:静的ライブラリのプロファイリング
13.7 まとめ
14章 スクリプティングの基礎
14.1 Script Manager
14.1.1 Script Managerウィンドウ
14.2 スクリプトの開発
14.2.1 Javaスクリプトを書く(JavaScriptではありません!)
14.2.2 スクリプト編集例:正規表現を用いた検索
14.2.3 Pythonスクリプト
14.2.4 他言語のサポート
14.3 Ghidra API
14.3.1 Addressインタフェース
14.3.2 Symbolインタフェース
14.3.3 Referenceインタフェース
14.3.4 GhidraScriptクラス
14.3.5 Programクラス
14.3.6 Functionインタフェース
14.3.7 Instructionインタフェース
14.4 Ghidraスクリプトの作成例
14.4.1 例1:関数を列挙する
14.4.2 例2:命令を列挙する
14.4.3 例3:相互参照の列挙
14.4.4 例4:関数の呼び出し元を探す
14.4.5 例5:アセンブリ命令を模倣する
14.5 まとめ
15章 EclipseとGhidraDevプラグイン
15.1 Eclipse
15.1.1 Eclipseの統合
15.1.2 Eclipseを始めよう
15.1.3 Eclipseでスクリプトを編集する
15.2 GhidraDevメニュー
15.2.1 [GhidraDev] > [New]サブメニュー
15.2.2 Package Explorerを使う
15.3 例:Ghidraアナライザ・モジュール・プロジェクト
15.3.1 ステップ1:解決すべき課題を定義する
15.3.2 ステップ2:Eclipseでモジュールを作成する
15.3.3 ステップ3:アナライザを作成する
15.3.4 ステップ4:Eclipseを使ってアナライザをテストする
15.3.5 ステップ5:アナライザを Ghidraにインストールする
15.3.6 ステップ6:インストールしたアナライザをテストする
15.4 まとめ
16章 ヘッドレス・モード
16.1 実行してみよう
16.1.1 ステップ1:Ghidraを立ち上げる
16.1.2 ステップ2と3:新規 Ghidraプロジェクトを指定したパスに作成する
16.1.3 ステップ4:ファイルをプロジェクトにインポートする
16.1.4 ステップ5と6:ファイルを自動解析し、保存して終了する
16.1.5 オプションと引数
16.2 Ghidraスクリプトの作成
16.2.1 HeadlessSimpleROP
16.2.2 FidDb作成の自動化
16.3 まとめ
第IV部 さらなる深みへ
17章 Ghidraローダ
17.1 未知のファイル解析
17.2 Windows PEファイルの手動ロード
17.3 例1:シンプルなシェルコードローダモジュール
17.3.1 ステップ0:一歩引いてみる
17.3.2 ステップ1:問題の定義
17.3.3 ステップ2:Eclipseモジュールの作成
17.3.4 ステップ3:ローダの構築
17.3.5 ステップ4:Ghidraにローダを追加する
17.3.6 ステップ5:Ghidra内でローダをテストする
17.4 例2:シンプルなシェルコードソースローダ
17.4.1 更新1:インポータへの応答を変更する
17.4.2 更新2:ソースコードからシェルコードを探す
17.4.3 更新3:シェルコードをバイト値に変換する
17.4.4 更新4:変換されたバイト配列をロードする
17.4.5 結果
17.5 例3:シンプルな ELFシェルコードローダ
17.5.1 ハウスキーピング
17.5.2 ELFヘッダフォーマット
17.5.3 サポートされているロード仕様を探す
17.5.4 ファイルの内容を Ghidraに読み込む
17.5.5 データバイトフォーマットとエントリポイントの追加
17.5.6 言語定義ファイル
17.5.7 opinionファイル
17.5.8 結果
17.6 まとめ
18章 Ghidraプロセッサ
18.1 Ghidraプロセッサモジュールを理解する
18.1.1 Eclipseのプロセッサモジュール
18.1.2 SLEIGH
18.1.3 プロセッサマニュアル
18.2 Ghidraプロセッサモジュールの変更
18.2.1 問題提起
18.2.2 例1:プロセッサモジュールへの命令の追加
18.2.3 例2:プロセッサモジュール内の命令の修正
18.2.4 例3:プロセッサモジュールへのレジスタの追加
18.3 まとめ
19章 Ghidraデコンパイラ
19.1 デコンパイラ解析
19.1.1 Analysisオプション
19.2 Decompilerウィンドウ
19.2.1 例1:Decompilerウィンドウの編集
19.2.2 例2:リターンしない関数
19.2.3 例3:構造体の自動作成
19.3 まとめ
20章 コンパイラのバリエーション
20.1 ハイレベルな構成要素
20.1.1 switch文
20.1.2 例:gccと Microsoft C/C++コンパイラの比較
20.2 コンパイラのビルドオプション
20.2.1 例1:モジュロ演算子
20.2.2 例2:三項演算子
20.2.3 例3:関数のインライン化
20.3 コンパイラ固有のC++実装
20.3.1 関数のオーバーロード
20.3.2 RTTIの実装
20.3.3 main関数の位置
20.4 まとめ
第V部 実世界のアプリケーションへの応用
21章 難読化されたコードの解析
21.1 アンチリバースエンジニアリング
21.1.1 難読化
21.1.2 アンチ静的解析技術
21.1.3 インポート関数の難読化
21.1.4 アンチ動的解析技術
21.2 Ghidraによるバイナリの静的難読化解除
21.2.1 スクリプトを利用した難読化解除
21.2.2 エミュレータベースの難読化解除
21.2.3 ステップ1:問題の定義
21.2.4 ステップ2:Eclipseスクリプトプロジェクトの作成
21.2.5 ステップ3:エミュレータのビルド
21.2.6 ステップ4:Ghidraにスクリプトを追加する
21.2.7 ステップ5:Ghidraを使ったスクリプトのテスト
21.3 まとめ
22章 バイナリのパッチ
22.1 パッチの計画
22.2 変更するものを見つける
22.2.1 メモリの検索
22.2.2 直接参照の検索
22.2.3 命令パターンの検索
22.2.4 特定の動作を見つける
22.3 パッチの適用
22.3.1 基本的な変更方法
22.3.2 簡単でない変更
22.4 ファイルのエクスポート
22.4.1 Ghidraのエクスポートフォーマット
22.4.2 Binaryエクスポートフォーマット
22.4.3 スクリプト支援エクスポート
22.5 例:バイナリのパッチ
22.6 まとめ
23章 バイナリ差分とバージョントラッキング
23.1 バイナリ差分
23.1.1 Program Diffツール
23.2 関数の比較
23.2.1 Function Comparisonウィンドウ
23.2.2 例:暗号化ルーチンの比較
23.3 Version Trackingツール
23.3.1 Version Trackingの概念
23.4 まとめ
付録A IDAユーザ向けのGhidra
A.1 基礎編
A.1.1 データベース作成
A.2 基本的なウィンドウとナビゲーション
A.2.1 Listingウィンドウ
A.2.2 Graphウィンドウ
A.2.3 Decompilerウィンドウ
A.2.4 Symbol Treeウィンドウ
A.2.5 Data Type Managerウィンドウ
A.3 スクリプト
A.4 まとめ
付録B デバッガ
B.1 デバッグオプション
B.2 各ウィンドウ
B.2.1 Targetウィンドウ
B.2.2 Consoleウィンドウ
B.2.3 Objectsウィンドウ
B.2.4 Interpreterウィンドウ
B.2.5 Threadsウィンドウ
B.2.6 Registersウィンドウ
B.2.7 Dynamic Listingウィンドウ
B.2.8 Stackウィンドウ
B.2.9 Breakpointsウィンドウ
B.2.10 Regionsウィンドウ
B.2.11 Timeウィンドウ
B.2.12 Modulesウィンドウ
B.2.13 Static Mappingsウィンドウ
B.2.14 Watchesウィンドウ
B.2.15 Memviewウィンドウ
B.3 デバッガの使用方法
B.4 おわりに
索引
コラム目次
x86アセンブリ構文:AT&T記法 VS Intel記法
Windows Subsystem for Linux
バイナリ内のシンボルの削除
バイナリの難読化
ツールを使う際の注意事項
なぜ stringsは変わったのか?
Auto Analysisによる警告
ツールバー・ホットキー・ボタンについて
内側に表示されるウィンドウと外側に表示されるウィンドウ
私のウィンドウはどこにあるの?
お気に入りのバーは?
Listingウィンドウの設定
Satelliteビュー
ツール間の接続
グラフのカスタマイズ
プログラム内を自由に移動するには
誰が関数を呼び出したのか?
ラベル名を変更してみよう
スタック上のデータは本当に消えるのか?
レジスタによる引数の指定
Searchウィンドウの名前を変えることによる作業効率化
各種操作の取り消し方
禁止された名前
どのような名前をつけるべきか
FUN_接頭辞
バグか機能か
下部の3つのボタン
C言語が本当に期待すること
シンボルを削られたバイナリ
コメントによるシンボル情報の更新
共用体の役割
コンストラクタとは?
new演算子とは?
オーバーロードされた関数の発見
XREFの表示形式
余計な XREF?
基本ブロックとは
グラフ表示を調整する
Interaction Thresholdについて
「Graph is stale」メッセージについて
Function Graphの操作
thunk関数について
Ghidra Serverのカスタムインストール
プロジェクトリポジトリ
Ghidra Serverにおける管理者の種類
Ghidra Serverをプライベート用として使う
バージョン管理と Version Tracking
バージョン管理におけるコメント
ファイルが乗っ取られた!助けて!
ファイル読み込み時の言語とコンパイラの指定について
Ghidraにおける Python
危険な関数
またそのスクリプトを作るの?
ROPガジェットとは何か?なぜ特定する必要があるのか?
スラッシュかバックスラッシュか?
ワイルドカード!
シェルコードとは何か?なぜ気にするのか?
Eclipseでモジュールをテストする
Ghidraの拡張に貢献しているのはどんな人ですか?
Ghidraの SLEIGHエディタ
P-CODE:どこまで低レイヤーになる?
サンドボックス環境
プロセスのトレース
CRACKME, CRACK YOURSELF