Ghidra是美國國家安全局(NSA)開發(fā)的免費和開源的逆向工程工具,已于2019年的RSA正式發(fā)布,包含了一整套功能齊全的高級軟件分析工具,可以幫助廣大研究人員在Windows、macOS和Linux各大常見系統(tǒng)平臺上進(jìn)行源代碼分析。目前已在技術(shù)安全社區(qū)掀起一股學(xué)習(xí)熱潮。
Chris Eagle從事逆向工程工作已有40年。他是《IDA Pro權(quán)威指南》的作者,以及非常受歡迎的逆向工程培訓(xùn)專家。他開發(fā)了許多逆向工程工具,并在Blackhat、Defcon和Shmoocon等會議上發(fā)表演講。Kara Nance是一名私人安全顧問。多年來一直是計算機(jī)科學(xué)教授。她曾在Honeynet Project董事會任職,并在世界各地的會議上發(fā)表過多次演講。她喜歡構(gòu)建Ghidra擴(kuò)展并定期提供Ghidra培訓(xùn)。
楊超,畢業(yè)于西安電子科技大學(xué),L-Team成員,CISP,CISSP,《CTF競賽權(quán)威指南(Pwn篇)》作者。目前就職于某頭部造車新勢力,從事車聯(lián)網(wǎng)安全研究和攻防測試工作,擁有多個CVE。活躍在開源社區(qū),項目star數(shù)6000+,https://github.com/firmianay。
第一部分 簡介
第1章 反匯編簡介 1
1.1 反匯編理論 1
1.2 何為反匯編 2
1.3 為何反匯編 2
1.3.1 惡意軟件分析 3
1.3.2 漏洞分析 3
1.3.3 軟件互操作性 3
1.3.4 編譯器驗證 3
1.3.5 顯示調(diào)試信息 4
1.4 如何反匯編 4
1.4.1 基礎(chǔ)反匯編算法 4
1.4.2 線性掃描反匯編 5
1.4.3 遞歸下降反匯編 6
1.5 小結(jié) 9
第2章 逆向與反匯編工具 10
2.1 分類工具 10
2.1.1 file 10
2.1.2 PE Tools 12
2.1.3 PEiD 13
2.2 摘要工具 14
2.2.1 nm 14
2.2.2 ldd 16
2.2.3 objdump 17
2.2.4 otool 18
2.2.5 dumpbin 18
2.2.6 c++filt 19
2.3 深度檢測工具 20
2.3.1 strings 20
2.3.2 反匯編器 21
2.4 小結(jié) 23
第3章 初識Ghidra 24
3.1 Ghidra許可證 24
3.2 Ghidra版本 24
3.3 Ghidra支持資源 24
3.4 下載Ghidra 25
3.5 安裝Ghidra 25
3.5.1 Ghidra的目錄結(jié)構(gòu) 26
3.5.2 啟動Ghidra 27
3.6 小結(jié) 27
第二部分 Ghidra的基本用法
第4章 開始使用Ghidra 28
4.1 啟動Ghidra 28
4.2 創(chuàng)建新項目 29
4.2.1 Ghidra文件加載 30
4.2.2 使用原始二進(jìn)制加載器 32
4.3 使用Ghidra分析文件 33
4.4 初始分析期間的桌面行為 36
4.5 Ghidra桌面提示和技巧 37
4.6 小結(jié) 38
第5章 Ghidra數(shù)據(jù)顯示 39
5.1 CodeBrowser 39
5.2 CodeBrowser窗口 41
5.2.1 清單窗口 42
5.2.2 創(chuàng)建額外的反匯編窗口 45
5.2.3 函數(shù)圖形化視圖 46
5.2.4 程序樹窗口 49
5.2.5 符號樹窗口 50
5.2.6 數(shù)據(jù)類型管理器窗口 53
5.2.7 控制臺窗口 53
5.2.8 反編譯器窗口 53
5.3 其他窗口 55
5.3.1 字節(jié)窗口 55
5.3.2 數(shù)據(jù)定義窗口 56
5.3.3 字符串定義窗口 58
5.3.4 符號表和符號引用窗口 58
5.3.5 內(nèi)存映射窗口 60
5.3.6 函數(shù)調(diào)用圖窗口 61
5.4 小結(jié) 62
第6章 理解Ghidra反匯編 63
6.1 反匯編導(dǎo)航 63
6.1.1 名稱和標(biāo)簽 63
6.1.2 在Ghidra中導(dǎo)航 64
6.1.3 Go To對話框 65
6.1.4 導(dǎo)航歷史 65
6.2 棧幀 66
6.2.1 函數(shù)調(diào)用機(jī)制 66
6.2.2 調(diào)用約定 68
6.2.3 棧幀的其他思考 71
6.2.4 局部變量布局 72
6.2.5 棧幀示例 72
6.3 Ghidra棧視圖 75
6.3.1 Ghidra棧幀分析 75
6.3.2 清單視圖中的棧幀 76
6.3.3 反編譯輔助棧幀分析 78
6.3.4 局部變量作為操作數(shù) 79
6.3.5 Ghidra棧編輯器 80
6.4 搜索 82
6.4.1 搜索程序文本 82
6.4.2 搜索內(nèi)存 83
6.5 小結(jié) 84
第7章 反匯編操作 85
7.1 操作名稱和標(biāo)簽 85
7.1.1 重命名參數(shù)和局部變量 86
7.1.2 重命名標(biāo)簽 89
7.1.3 添加新標(biāo)簽 89
7.1.4 編輯標(biāo)簽 90
7.1.5 刪除標(biāo)簽 91
7.1.6 導(dǎo)航標(biāo)簽 91
7.2 注釋 91
7.2.1 行末注釋 92
7.2.2 前注釋與后注釋 92
7.2.3 塊注釋 93
7.2.4 可重復(fù)注釋 94
7.2.5 參數(shù)和局部變量注釋 94
7.2.6 注解 95
7.3 基本的代碼轉(zhuǎn)換 95
7.3.1 更改代碼顯示選項 95
7.3.2 格式化指令操作數(shù) 96
7.3.3 操縱函數(shù) 98
7.3.4 數(shù)據(jù)與代碼的轉(zhuǎn)換 100
7.4 基本的數(shù)據(jù)轉(zhuǎn)換 100
7.4.1 指定數(shù)據(jù)類型 101
7.4.2 處理字符串 102
7.4.3 定義數(shù)組 103
7.5 小結(jié) 104
第8章 數(shù)據(jù)類型和數(shù)據(jù)結(jié)構(gòu) 105
8.1 理解數(shù)據(jù) 105
8.2 識別數(shù)據(jù)結(jié)構(gòu)的使用 106
8.2.1 數(shù)組成員訪問 107
8.2.2 結(jié)構(gòu)體成員訪問 114
8.3 用Ghidra創(chuàng)建結(jié)構(gòu)體 120
8.3.1 創(chuàng)建結(jié)構(gòu)體 120
8.3.2 編輯結(jié)構(gòu)體成員 122
8.3.3 應(yīng)用結(jié)構(gòu)體布局 124
8.4 C++逆向入門 125
8.4.1 this指針 125
8.4.2 虛函數(shù)和虛表 126
8.4.3 對象生命周期 129
8.4.4 名稱改編 130
8.4.5 運行時類型識別 131
8.4.6 繼承關(guān)系 132
8.4.7 C++逆向參考資料 133
8.5 小結(jié) 133
第9章 交叉引用 134
9.1 引用基礎(chǔ) 134
9.1.1 交叉引用(反向引用) 135
9.1.2 引用示例 137
9.2 引用管理窗口 141
9.2.1 XRefs窗口 142
9.2.2 References To窗口 142
9.2.3 符號引用窗口 143
9.2.4 高級引用操作 143
9.3 小結(jié) 144
第10章 圖形 145
10.1 基本塊 145
10.2 函數(shù)圖 146
10.3 函數(shù)調(diào)用圖 152
10.4 樹 157
10.5 小結(jié) 157
第三部分 讓Ghidra為您工作
第11章 協(xié)作逆向工程 158
11.1 團(tuán)隊協(xié)作 158
11.2 Ghidra Server設(shè)置 158
11.3 共享項目 161
11.3.1 創(chuàng)建共享項目 161
11.3.2 項目管理 162
11.4 項目窗口菜單 163
11.4.1 文件菜單 163
11.4.2 編輯菜單 165
11.4.3 項目菜單 166
11.5 項目倉庫 169
11.5.1 版本控制 169
11.5.2 示例場景 171
11.6 小結(jié) 175
第12章 自定義Ghidra 176
12.1 CodeBrowser窗口 176
12.1.1 重新排列窗口 177
12.1.2 編輯工具選項 177
12.1.3 編輯工具 179
12.1.4 特殊工具編輯功能 180
12.1.5 保存CodeBrowser布局 181
12.2 Ghidra項目窗口 182
12.3 工具菜單 185
12.4 工作區(qū) 189
12.5 小結(jié) 189
第13章 Ghidra功能擴(kuò)展 190
13.1 導(dǎo)入文件 190
13.2 分析器 192
13.3 詞模型 193
13.4 數(shù)據(jù)類型 195
13.5 Function ID分析器 198
13.6 Function ID插件 199
13.6.1 插件示例:UPX 200
13.6.2 插件示例:分析靜態(tài)庫 204
13.7 小結(jié) 207
第14章 Ghidra腳本開發(fā) 208
14.1 腳本管理器 208
14.1.1 腳本管理器窗口 209
14.1.2 腳本管理器工具欄 210
14.2 腳本開發(fā) 210
14.2.1 編寫Java腳本 210
14.2.2 編輯腳本示例:正則搜索 212
14.2.3 編寫Python腳本 215
14.2.4 支持其他語言 217
14.3 Ghidra API簡介 217
14.3.1 地址接口 218
14.3.2 符號接口 218
14.3.3 引用接口 218
14.3.4 GhidraScript類 218
14.3.5 Program類 224
14.3.6 函數(shù)接口 225
14.3.7 指令接口 225
14.4 Ghidra腳本開發(fā)示例 226
14.4.1 示例1:枚舉函數(shù) 226
14.4.2 示例2:枚舉指令 226
14.4.3 示例3:枚舉交叉引用 227
14.4.4 示例4:尋找函數(shù)調(diào)用 228
14.4.5 示例5:模擬匯編語言行為 229
14.5 小結(jié) 231
第15章 Eclipse和GhidraDev 232
15.1 Eclipse 232
15.1.1 Eclipse集成 232
15.1.2 啟動Eclipse 233
15.1.3 使用Eclipse編輯腳本 233
15.2 GhidraDev菜單 234
15.2.1 GhidraDev→New 234
15.2.2 瀏覽包資源管理器 238
15.3 示例:Ghidra分析器模塊項目 243
15.3.1 步驟1:定義問題 243
15.3.2 步驟2:創(chuàng)建Eclipse模塊 244
15.3.3 步驟3:構(gòu)建分析器 244
15.3.4 步驟4:使用Eclipse測試
分析器 249
15.3.5 步驟5:添加分析器到Ghidra
安裝中 250
15.3.6 步驟6:使用Ghidra測試
分析器 250
15.4 小結(jié) 252
第16章 Ghidra無頭模式 253
16.1 入門 253
16.1.1 步驟1:啟動Ghidra 254
16.1.2 步驟2和3:在指定位新建
Ghidra項目 254
16.1.3 步驟4:將文件導(dǎo)入項目 255
16.1.4 步驟5和6:自動分析文件、
保存并退出 255
16.1.5 選項和參數(shù) 257
16.2 編寫腳本 263
16.2.1 HeadlessSimpleROP 263
16.2.2 自動創(chuàng)建FidDb 267
16.3 小結(jié) 268
第四部分 深入探索
第17章 Ghidra加載器 269
17.1 未知文件分析 270
17.2 手動加載 Windows PE 文件 271
17.3 示例一:簡易Shellcode加載器 279
17.3.1 步驟0:準(zhǔn)備工作 280
17.3.2 步驟1:定義問題 282
17.3.3 步驟2:創(chuàng)建Eclipse模塊 282
17.3.4 步驟3:構(gòu)建加載器 283
17.3.5 步驟4:添加加載器到
Ghidra中 287
17.3.6 步驟5:在Ghidra中測試
加載器 288
17.4 示例二:簡易Shellcode源代碼
加載器 289
17.4.1 更新1:修改導(dǎo)入查詢的
響應(yīng) 289
17.4.2 更新2:在源代碼中定位
Shellcode 290
17.4.3 更新3:將Shellcode轉(zhuǎn)化為
二進(jìn)制數(shù)組 290
17.4.4 更新4:導(dǎo)入二進(jìn)制數(shù)組 291
17.4.5 生成結(jié)果 291
17.5 示例三:簡易ELF加載器 292
17.5.1 統(tǒng)一代碼規(guī)范 293
17.5.2 ELF頭部格式 293
17.5.3 明確支持的加載規(guī)格 294
17.5.4 將文件內(nèi)容加載到Ghidra中 295
17.5.5 數(shù)據(jù)格式化與添加入口點 296
17.5.6 語言定義文件 297
17.5.7 選項文件 297
17.5.8 結(jié)果 298
17.6 小結(jié) 300
第18章 Ghidra處理器 301
18.1 理解Ghidra處理器模塊 302
18.1.1 Eclipse處理器模塊 302
18.1.2 SLEIGH 303
18.1.3 處理器手冊 304
18.2 修改Ghidra處理器模塊 305
18.2.1 問題陳述 306
18.2.2 示例1:在處理器模塊中添加
指令 306
18.2.3 示例2:修改處理器模塊中的
指令 312
18.2.4 示例3:在處理器模塊中添加
寄存器 319
18.3 小結(jié) 321
第19章 Ghidra反編譯器 322
19.1 反編譯器分析 322
19.2 反編譯器窗口 324
19.2.1 示例1:在反編譯器窗口中
編輯 325
19.2.2 示例2:無返回值函數(shù) 329
19.2.3 示例3:自動創(chuàng)建結(jié)構(gòu)體 331
19.3 小結(jié) 334
第20章 編譯器變體 336
20.1 高級結(jié)構(gòu) 336
20.1.1 switch語句 336
20.1.2 示例:比較gcc與Microsoft C/
C++編譯器 341
20.2 編譯器構(gòu)建選項 342
20.2.1 示例1:模運算符 343
20.2.2 示例2:三元運算符 345
20.2.3 示例3:函數(shù)內(nèi)聯(lián) 347
20.3 編譯器特定的C++實現(xiàn) 348
20.3.1 函數(shù)重載 348
20.3.2 RTTI實現(xiàn) 349
20.4 定位main函數(shù) 352
20.4.1 示例1:gcc Linux x86-64從
_start到main 352
20.4.2 示例2:clang FreeBSD x86-64
從_start到main 353
20.4.3 示例3:Microsoft C/C++從
_start到main 354
20.5 小結(jié) 354
第五部分 實際應(yīng)用
第21章 混淆代碼分析 356
21.1 反逆向工程 356
21.1.1 混淆 356
21.1.2 反靜態(tài)分析技術(shù) 357
21.1.3 導(dǎo)入函數(shù)混淆 366
21.1.4 反動態(tài)分析技術(shù) 370
21.2 使用Ghidra靜態(tài)去混淆二進(jìn)制文件 372
21.2.1 基于腳本的去混淆 373
21.2.2 基于模擬的去混淆 377
21.2.3 步驟1:定義問題 379
21.2.4 步驟2:創(chuàng)建Eclipse腳本
項目 379
21.2.5 步驟3:構(gòu)建模擬器 379
21.2.6 步驟4:添加腳本到Ghidra
安裝中 382
21.2.7 步驟5:使用Ghidra測試
腳本 382
21.3 小結(jié) 383
第22章 修補(bǔ)二進(jìn)制文件 384
22.1 規(guī)劃你的補(bǔ)丁 384
22.2 尋找需要修改的東西 385
22.2.1 搜索內(nèi)存 385
22.2.2 搜索直接引用 386
22.2.3 搜索指令模式 386
22.2.4 尋找特定行為 389
22.3 應(yīng)用你的補(bǔ)丁 390
22.3.1 做基本的修改 390
22.3.2 做重要的修改 394
22.4 導(dǎo)出文件 397
22.4.1 Ghidra導(dǎo)出格式 398
22.4.2 二進(jìn)制導(dǎo)出格式 398
22.4.3 腳本輔助的導(dǎo)出 398
22.5 示例:修補(bǔ)二進(jìn)制文件 400
22.6 小結(jié) 403
第23章 二進(jìn)制差分和版本跟蹤 404
23.1 二進(jìn)制差分 404
23.1.1 程序差分工具 406
23.1.2 示例:合并兩個已分析的
文件 408
23.2 比較函數(shù) 411
23.2.1 函數(shù)比較窗口 412
23.2.2 示例:比較加密例程 413
23.3 版本跟蹤 417
23.4 小結(jié) 419
附錄A IDA用戶的Ghidra使用指南 420