gdb除錯快速上手

开宝特攻發表於2024-06-16

gdb

命令

通用命令

📖GDB Reference 🔗偵錯程式 GDB 常用功能

  • x / [Length][Format: t o d x f a c s] [Address expression b-8 h-16 w-32 g-64\ ] 📎GDB Command Reference : x

  • p/t-2 o-8 d-10 x-16 f-loat a-ddress c-har s-tring [var]

    1. ⚠️ 要注意區分,x 是掃描記憶體,因此後面跟的直接是記憶體地址, 而 p 是輸出變數的值,因此後面想跟地址的話,需要取其內容,即加上*
    2. 關於 *,很多命令地址前面都要加星號,因為不加星號的一個地址,是被當成函式來看待的
  • s n :C 語言級別的單步執行; si ni彙編級別的單步執行

  • i [line] / [locals] / [vtbl] / [args] / [checkpoints] / [breakpoints]

    1. info line [line] / [function] / [*addr]:顯示原始碼對應的記憶體中的起始結束地址

    2. info vtbl [objs]:直接檢視物件的虛擬函式表(也可以型別轉換的形式列印出來,參考C++類的記憶體分配,基本思想就是:物件的第一塊記憶體放的就是虛表,虛表是一個函式指標陣列,因此可以先將物件地址轉換為指向指標的指標,然後對其取內容,就得到了虛表指標。把這個值轉換為指向指標的指標,即得虛表)

  • set print array-indexes on:列印陣列的時候顯示 index

  • set disassemble next-line ondisassemble

  • set [args] / [register] / [*address] = [val]:設定引數、暫存器值、記憶體處值

  • jump [*address]:跳轉到指定地址處執行,return [val]:直接返回。都可以改變程式走向。

  • shell [cmd]:執行 shell 命令

  • rbreak [regex]:在所有滿足正規表示式的函式處打斷點

多程序/執行緒除錯

  • gdb [pid]:除錯正在執行的程序,或者進去後 attch [pip]

例子

  • 列印棧內容(你打陣列肯定也行):不妨設 $rsp 中存放的是 0x1234 p $rsp => (void*)0x1234
    1. x/10dw $rspx/10dw 0x1234,即用 x 命令直接把棧那一塊記憶體掃描出來
    2. p *(int (*)[10])0x1234 把棧頂地址型別轉換為一個指向陣列的指標,然後 print 這個陣列 val 的值(所以要加*),即棧的內容
    3. p (int [10])*0x1234 把棧頂的內容直接變成一個陣列,然後輸出
    4. p *0x1234@6 注意@的用法,其左邊必須是你想檢視記憶體處的,可以直接輸出後面的六個變數
      類似的 p *argv@argc,也是先取內容轉換為變數,再輸出
    5. 總結一下,用 x 就是直接掃描記憶體了,簡單粗暴;用 p 則是要把你想看的記憶體區域轉化成一個變數,一個 val,不管是 int 還是 int 陣列,不管是怎麼型別轉換,反正基本思想是把記憶體當成一個變數進行輸出。最好還是用 x ,因為效果一樣,用 p 你還需要先得到 rsp 裡面的值
  • 檢視虛表
  • 運用 core 檔案gdb debug core進入之後,disassemble,可以看到 => 指向的就是執行出錯的地方

相關文章