偵錯主要可分四大步驟:
- 中斷
- 檢測
- 控制
- 修改
小抄
一些用過 GDB 都應該要會的操作
disassemble <func>
disassemble *mem
run
start
starti
si
n
ni
fin (finish)
u (until)
c (continue)
b <func>
b *mem
info reg
bt # 顯示 Call Stack
up/down # 在堆疊中移動
print
print /x $<reg>
x/NT N=單位 T=資料類型 (x:hex, d:decimal, c:char, s:string, i:instruction)
quit
focus cmd / src
layout next
list # 顯示當前 Source Code環境設定
設定 Intel 格式
# ~/.gdbinit
set disassembly-flavor intel
如何學習
使用最實用的 Google Hacking 之一:

啟動
start # 啟動並在第一行暫停
starti # 啟動並在程式入口點(`_start`)暫停
run # 啟動程式直到斷點
中斷
info breakpoints
b main
b *main+42
b func if a == 10
delete <num>
檢測
- 語法:
x/<數量><格式><單位> <地址>- 數量 (n): 要看幾個單元。
- 格式 (f):
x(Hex),d(Decimal),i(Instruction/組語),s(String)。 - 單位 (u):
b(byte),h(halfword/2 bytes),w(word/4 bytes),g(giant word/8 bytes, 64-bit)。
暫存器
info reg (info registers) # 查看所有暫存器,除了浮點數、向量計算相關
info all-registers # 查看所有暫存器
p $rax # 以十進制顯示 $rax 的值
p/x $rax # 以十六進制顯示 $rax 的值
set $sp += 4記憶體
x/16gx $rsp # 查看 Stack 上的前 16 個 64-bit 數值 (以 Hex 顯示)
x/i $rip # 查看當前即將執行的組語指令
x/10i main # 查看 main 函數的前 10 行組語
x/gx $rbp-0x18 # 查看 Stack 中某個區域變數的值display
在每次輸入指令後自動顯示指定資料
display/8i $rip
display/4gx $rsp
Convenience variables and functions
define auto_get_val_and_cont
set $my_value = *(unsigned long long *)($rbp - 0x18)
printf "==="
printf "(Hex: 0x%lx\n)", $my_value
printf "(Dec: %llu\n)", $my_value
printf "==="
cont
end
控制
# 針對原始程式碼
n [count]
s [count]
# 針對組合語言
ni [count]
si [count]
c # continue
fin # finish, 執行直到當前 stack frame 回傳
u # until, 執行直到遇到下個 jump
call (void)func() # 呼叫 func
jump *0x400500 # 跳轉修改
set $rdi = 0 # 將 rdi 歸零
set *0x7fffffffe000 = 0x1337 # 修改記憶體內容
set *(unsigned long long*)($rbp-0x10) = $rax # 複雜的賦值
set $rip = func+47 # 修改 Instruction Pointer
其他
(gdb) alias lld = disable $_hit_bpnum.$_hit_locno
(gdb) alias lbd = disable $_hit_bpnum