在前幾天的文章中,我們學會了用 strings、.pyc 反編譯與 Ghidra 靜態分析。然而,當程式碼經過複雜的動態計算、混淆或需要確認記憶體當下的真實數值時,動態分析 (Dynamic Analysis) 就不可或缺。
在 Linux 平台下,GDB (GNU Debugger) 是最具權威的除錯神器。透過 GDB,我們能夠:
在正式除錯前,先記住以下最常使用的 GDB 互動指令:
gdb ./target_binary
break main(在 main 函數開頭下中斷點)break *0x401122(在指定記憶體位址下中斷點)run (簡寫 r)ni (Next Instruction):執行下一條組譯指令,遇到函數直接跳過。si (Step Instruction):執行下一條組譯指令,若遇到函數會跟進去。continue (簡寫 c),讓程式繼續跑到下一個中斷點。info registers(查看所有暫存器數值)print variable_name(查看變數內容)x/10xw $rsp(以十六進位檢視堆疊指標 $rsp 開始的 10 個 dword 內容)我們在 WSL 中透過一個簡單的 C 程式,示範如何用 GDB 設定中斷點並觀察暫存器變化。
在 WSL 終端機執行以下命令:
# 1. 建立簡單的測試 C 原始碼
cat << 'EOF' > gdb_demo.c
#include <stdio.h>
int add(int a, int b) {
int result = a + b;
return result;
}
int main() {
int x = 10;
int y = 20;
int sum = add(x, y);
printf("The sum is: %d\n", sum);
return 0;
}
EOF
# 2. 編譯時加上 -g 參數以保留 Symbol 符號表,方便 GDB 識別函數名稱
gcc -g gdb_demo.c -o gdb_demo
執行 GDB 載入二進位檔:
gdb ./gdb_demo

進入 GDB 提示字元 ((gdb)) 後,依序輸入以下指令:
程式碼片段
# 1. 在 main 函數設定中斷點
(gdb) break main
# 2. 開始執行程式
(gdb) run
# 3. 程式會暫停在 main 函數開頭,此時檢視暫存器狀態
(gdb) info registers

繼續在 GDB 中執行以下指令,觀察 add 函數的呼叫與暫存器數值:
# 單步執行下一條彙編指令
(gdb) ni
# 查看當前暫存器數值(如 rip 指令指標)
(gdb) info registers rip
# 繼續執行到程式結束
(gdb) continue
# 退出 GDB
(gdb) quit

透過 GDB 的中斷點與暫存器觀察,我們不再只是「猜測」程式如何運作,而是能夠親眼看見 CPU 暫存器(如 RAX、RSP、RIP)在每一個指令週期中的精確數值。
在後續的 Pwn 挑戰中(例如控制暫存器跳轉、撰寫 Shellcode),GDB 絕對是排查錯誤(Debugging)與驗證 Payload 是否精準覆蓋返回地址的最佳左右手!