gdb/peda

gdb 的組成架構

image.png

gdb 基本工作原理

gdb 通過系統(tǒng)調用 ptrace 來接管一個進程的執(zhí)行。ptrace 系統(tǒng)調用提供了一種方法使得父進程可以觀察和控制其它進程的執(zhí)行,檢查和改變其核心映像以及寄存器。它主要用來實現斷點調試和系統(tǒng)調用跟蹤。ptrace 系統(tǒng)調用的原型如下:

#include <sys/ptrace.h>
long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);

- pid_t pid:指示 ptrace 要跟蹤的進程。 - void *addr:指示要監(jiān)控的內存地址。 - void *data:存放讀取出的或者要寫入的數據。 - enum __ptrace_request request:決定了系統(tǒng)調用的功能,幾個主要的選項: - PTRACE_TRACEME:表示此進程將被父進程跟蹤,任何信號(除了 SIGKILL)都會暫停子進程,接著阻塞于 wait() 等待的父進程被喚醒。子進程內部對 exec() 的調用將發(fā)出 SIGTRAP 信號,這可以讓父進程在子進程新程序開始運行之前就完全控制它。 - PTRACE_ATTACH:attach 到一個指定的進程,使其成為當前進程跟蹤的子進程,而子進程的行為等同于它進行了一次 PTRACE_TRACEME 操作。但需要注意的是,雖然當前進程成為被跟蹤進程的父進程,但是子進程使用 getppid() 的到的仍將是其原始父進程的 pid。 - PTRACE_CONT:繼續(xù)運行之前停止的子進程。可同時向子進程交付指定的信號。

gdb 的三種調試方式

  • 運行并調試一個新進程
  • 運行 gdb,通過命令行或 file 命令指定目標程序。
  • 輸入 run 命令, gdb 執(zhí)行下面的操作:
    • 通過 fork() 系統(tǒng)調用創(chuàng)建一個新進程
    • 在新創(chuàng)建的子進程中執(zhí)行操作:ptrace(PTRACE_TRACEME, 0, 0, 0)
    • 在子進程中通過 execv() 系統(tǒng)調用加載用戶指定的可執(zhí)行文件
  • attach 并調試一個已經運行的進程
  • 用戶確定需要進行調試的進程 PID
  • 運行 gdb,輸入 attach <pid>,gdb 將對指定進程執(zhí)行操作:ptrace(PTRACE_ATTACH, pid, 0, 0)
  • 遠程調試目標機上新創(chuàng)建的進程
  • gdb 運行在調試機上,gdbserver 運行在目標機上,兩者之間的通信數據格式由 gdb 遠程串行協(xié)議(Remote Serial Protocol)定義
  • RSP 協(xié)議數據的基本格式為: $..........#xx
  • gdbserver 的啟動方式相當于運行并調試一個新創(chuàng)建的進程
    注意,在你將 gdb attach 到一個進程時,可能會出現這樣的問題:
gdb-peda$ attach 9091
Attaching to process 9091
ptrace: Operation not permitted.

這是因為開啟了內核參數 ptrace_scope:

$ cat /proc/sys/kernel/yama/ptrace_scope
1

1 表示 True,此時普通用戶進程是不能對其他進程進行 attach 操作的,當然你可以用 root 權限啟動 gdb,但最好的辦法還是關掉它:

# echo 0 > /proc/sys/kernel/yama/ptrace_scope

斷點的實現

斷點的功能是通過內核信號實現的,在 x86 架構上,內核向某個地址打入斷點,實際上就是往該地址寫入斷點指令 INT 3,即 0xCC。目標程序運行到這條指令之后會觸發(fā) SIGTRAP 信號,gdb 捕獲這個信號,并根據目標程序當前停止的位置查詢 gdb 維護的斷點鏈表,若發(fā)現在該地址確實存在斷點,則可判定為斷點命中。

gdb 基本操作

使用 -tui 選項可以將代碼顯示在一個漂亮的交互式窗口中。

break -- b

  • break 當不帶參數時,在所選棧幀中執(zhí)行的下一條指令處設置斷點。
  • break <function> 在函數體入口處打斷點。
  • break <line> 在當前源碼文件指定行的開始處打斷點。
  • break -N break +N 在當前源碼行前面或后面的 N 行開始處打斷點,N 為正整數。
  • break <filename:line> 在源碼文件 filenameline 行處打斷點。
  • break <filename:function> 在源碼文件 filenamefunction 函數入口處打斷點。
  • break <address> 在程序指令的地址處打斷點。
  • break ... if <cond> 設置條件斷點,... 代表上述參數之一(或無參數),cond 為條件表達式,僅在 cond 值非零時停住程序。

info breakpoints -- i b

查看斷點,觀察點和捕獲點的列表。用法: - info breakpoints [list…] - info break [list…]

list… 用來指定若干個斷點的編號(可省略),可以是 2, 1-3, 2 5 等。

disable -- dis

禁用斷點,參數使用空格分隔。不帶參數時禁用所有斷點。 - disable [breakpoints] [list…] breakpointsdisable 的子命令(可省略),list…info breakpoints 中的描述。

enable

啟用斷點,參數使用空格分隔。不帶參數時啟用所有斷點。 - enable [breakpoints] [list…] 啟用指定的斷點(或所有定義的斷點)。 - enable [breakpoints] once list… 臨時啟用指定的斷點。GDB 在停止您的程序后立即禁用這些斷點。 - enable [breakpoints] delete list… 使指定的斷點啟用一次,然后刪除。一旦您的程序停止,GDB 就會刪除這些斷點。等效于用 tbreak 設置的斷點。

breakpointsdisable 中的描述。

clear

在指定行或函數處清除斷點。參數可以是行號,函數名稱或 * 跟一個地址。 - clear 當不帶參數時,清除所選棧幀在執(zhí)行的源碼行中的所有斷點。 - clear <function>, clear <filename:function> 刪除在命名函數的入口處設置的任何斷點。 - clear <line>, clear <filename:line> 刪除在指定的文件指定的行號的代碼中設置的任何斷點。 - clear <address> 清除指定程序指令的地址處的斷點。

delete -- d

刪除斷點。參數使用空格分隔。不帶參數時刪除所有斷點。 - delete [breakpoints] [list…]

tbreak

設置臨時斷點。參數形式同 break 一樣。當第一次命中時被刪除。

watch

為表達式設置觀察點。每當一個表達式的值改變時,觀察點就會停止執(zhí)行您的程序。 - watch [-l|-location] <expr> 如果給出了 -l 或者 -location,則它會對 expr 求值并觀察它所指向的內存。

step -- s

單步執(zhí)行程序,直到到達不同的源碼行。 - step [N] 參數 N 表示執(zhí)行 N 次(或由于另一個原因直到程序停止)。

reverse-step

反向步進程序,直到到達另一個源碼行的開頭。 - reverse-step [N] 參數 N 表示執(zhí)行 N 次(或由于另一個原因直到程序停止)。

next -- n

單步執(zhí)行程序,執(zhí)行完子程序調用。 - next [N]

step 不同,如果當前的源代碼行調用子程序,則此命令不會進入子程序,而是繼續(xù)執(zhí)行,將其視為單個源代碼行。

reverse-next

反向步進程序,執(zhí)行完子程序調用。 - reverse-next [N]

如果要執(zhí)行的源代碼行調用子程序,則此命令不會進入子程序,調用被視為一個指令。

return

您可以使用 return 命令取消函數調用的執(zhí)行。如果你給出一個表達式參數,它的值被用作函數的返回值。 - return <expression>expression 的值作為函數的返回值并使函數直接返回。

finish -- fin

執(zhí)行直到選定的棧幀返回。 - finish

until -- u

執(zhí)行程序直到大于當前棧幀或當前棧幀中的指定位置(與 break 命令相同的參數)的源碼行。此命令常用于通過一個循環(huán),以避免單步執(zhí)行。 - until <location> 繼續(xù)運行程序,直到達到指定的位置,或者當前棧幀返回。

continue -- c

在信號或斷點之后,繼續(xù)運行被調試的程序。 - continue [N]

如果從斷點開始,可以使用數字 N 作為參數,這意味著將該斷點的忽略計數設置為 N - 1(以便斷點在第 N 次到達之前不會中斷)。

print -- p

求表達式 expr 的值并打印。可訪問的變量是所選棧幀的詞法環(huán)境,以及范圍為全局或整個文件的所有變量。 - print [expr] - print /f [expr] 通過指定 /f 來選擇不同的打印格式,其中 f 是一個指定格式的字母

x

檢查內存。 - x/nfu <addr> - x <addr>

n, f, 和 u 都是可選參數,用于指定要顯示的內存以及如何格式化。 addr 是要開始顯示內存的地址的表達式。 n 重復次數(默認值是 1),指定要顯示多少個單位(由 u 指定)的內存值。 f 顯示格式(初始默認值是 x),顯示格式是 print('x','d','u','o','t','a','c','f','s') 使用的格式之一,再加 i(機器指令)。 u 單位大小,b 表示單字節(jié),h 表示雙字節(jié),w 表示四字節(jié),g 表示八字節(jié)。

display

每次程序停止時打印表達式 expr 的值。 - display <expr> - display/fmt <expr> - display/fmt <addr>

fmt 用于指定顯示格式。對于格式 is,或者包括單位大小或單位數量,將表達式 addr 添加為每次程序停止時要檢查的內存地址。

info display

打印自動顯示的表達式列表,每個表達式都帶有項目編號,但不顯示其值。

undisplay

取消某些表達式在程序停止時自動顯示。參數是表達式的編號(使用 info display 查詢編號)。不帶參數表示取消所有自動顯示表達式。

disable display

禁用某些表達式在程序停止時自動顯示。禁用的顯示項目被再次啟用。參數是表達式的編號(使用 info display 查詢編號)。不帶參數表示禁用所有自動顯示表達式。

enable display

啟用某些表達式在程序停止時自動顯示。參數是重新顯示的表達式的編號(使用 info display 查詢編號)。不帶參數表示啟用所有自動顯示表達式。

help -- h

打印命令列表。 - help <class> 您可以獲取該類中各個命令的列表。 - help <command> 顯示如何使用該命令的簡述。

attach

掛接到 GDB 之外的進程或文件。將進程 ID 或設備文件作為參數。 - attach <process-id>

run -- r

啟動被調試的程序??梢灾苯又付▍?,也可以用 set args 設置(啟動所需的)參數。還允許使用 >, <, 或 >> 進行輸入和輸出重定向。

甚至可以運行一個腳本,如:

run `python2 -c 'print "A"*100'`

backtrace -- bt

打印整個棧的回溯。

  • bt 打印整個棧的回溯,每個棧幀一行。
  • bt n 類似于上,但只打印最內層的 n 個棧幀。
  • bt -n 類似于上,但只打印最外層的 n 個棧幀。
  • bt full n 類似于 bt n,還打印局部變量的值。

注意:使用 gdb 調試時,會自動關閉 ASLR,所以可能每次看到的棧地址都不變。

ptype

打印類型 TYPE 的定義。 - ptype[/FLAGS] TYPE-NAME | EXPRESSION

參數可以是由 typedef 定義的類型名, 或者 struct STRUCT-TAG 或者 class CLASS-NAME 或者 union UNION-TAG 或者 enum ENUM-TAG。

set follow-fork-mode

當程序 fork 出一個子進程的時候,gdb 默認會追蹤父進程(set follow-fork-mode parent),但也可以使用命令 set follow-fork-mode child 讓其追蹤子進程。

另外,如果想要同時追蹤父進程和子進程,可以使用命令 set detach-on-fork off(默認為on),這樣就可以同時調試父子進程,在調試其中一個進程時,另一個進程被掛起。如果想讓父子進程同時運行,可以使用 set schedule-multiple on(默認為off)。

但如果程序是使用 exec 來啟動了一個新的程序,可以使用 set follow-exec-mode new(默認為same) 來新建一個 inferior 給新程序,而父進程的 inferior 仍然保留。

info threads

打印出所有線程的信息,包含 Thread ID、Target ID 和 Frame。

thread apply all bt

打印出所有線程的堆棧信息。

gdb-peda

當 gdb 啟動時,它會在當前用戶的主目錄中尋找一個名為 .gdbinit 的文件;如果該文件存在,則 gdb 就執(zhí)行該文件中的所有命令。通常,該文件用于簡單的配置命令。但是 .gdbinit 的配置十分繁瑣,因此對 gdb 的擴展通常用插件的方式來實現,通過 python 的腳本可以很方便的實現需要的功能。

PEDA(Python Exploit Development Assistance for GDB)是一個強大的 gdb 插件。它提供了高亮顯示反匯編代碼、寄存器、內存信息等人性化的功能。同時,PEDA 還有一些實用的新命令,比如 checksec 可以查看程序開啟了哪些安全機制等等。

安裝

安裝 peda 需要的軟件包:

$ sudo apt-get install nasm micro-inetd
$ sudo apt-get install libc6-dbg vim ssh

安裝 peda:

$ git clone https://github.com/longld/peda.git ~/peda
$ echo "source ~/peda/peda.py" >> ~/.gdbinit
$ echo "DONE! debug your program with gdb and enjoy"

如果系統(tǒng)為 Arch Linux,則可以直接安裝:

$ yaourt -S peda

peda命令?

  • aslr -- 顯示/設置 gdb 的 ASLR
  • asmsearch -- Search for ASM instructions in memory
  • asmsearch "int 0x80"
  • asmsearch "add esp, ?" libc
  • assemble -- On the fly assemble and execute instructions using NASM
  • assemble
  • assemble $pc > mov al, 0xb > int 0x80 > end
  • checksec -- 檢查二進制文件的安全選項
  • cmpmem -- Compare content of a memory region with a file
  • cmpmem 0x08049000 0x0804a000 data.mem
  • context -- Display various information of current execution context
  • context_code -- Display nearby disassembly at $PC of current execution context
  • context_register -- Display register information of current execution context
  • context_stack -- Display stack of current execution context
    • context reg
    • context code
    • context stack
  • crashdump -- Display crashdump info and save to file
  • deactive -- Bypass a function by ignoring its execution (eg sleep/alarm)
  • deactive setresuid
  • deactive chdir
  • distance -- Calculate distance between two addresses
  • dumpargs -- 在調用指令停止時顯示傳遞給函數的參數
  • dumpmem -- Dump content of a memory region to raw binary file
  • dumpmem libc.mem libc
  • dumprop -- 在特定的內存范圍顯示 ROP gadgets
  • dumprop
  • dumprop binary "pop"
  • eflags -- Display/set/clear/toggle value of eflags register
  • elfheader -- 獲取正在調試的 ELF 文件的頭信息
  • elfheader
  • elfheader .got
  • elfsymbol -- 從 ELF 文件中獲取沒有調試信息的符號信息
  • elfsymbol
  • elfsymbol printf
  • gennop -- Generate abitrary length NOP sled using given characters
  • gennop 500
  • gennop 500 "\x90"
  • getfile -- Get exec filename of current debugged process
  • getpid -- Get PID of current debugged process
  • goto -- Continue execution at an address
  • help -- Print the usage manual for PEDA commands
  • hexdump -- Display hex/ascii dump of data in memory
  • hexdump $sp 64
  • hexdump $sp /20
  • hexprint -- Display hexified of data in memory
  • hexprint $sp 64
  • hexprint $sp /20
  • jmpcall -- Search for JMP/CALL instructions in memory
  • jmpcall
  • jmpcall eax
  • jmpcall esp libc
  • loadmem -- Load contents of a raw binary file to memory
  • loadmem stack.mem 0xbffdf000
  • lookup -- 搜索屬于內存范圍的地址的所有地址/引用
  • lookup address stack libc
  • lookup pointer stack ld-2
  • nearpc -- Disassemble instructions nearby current PC or given address
  • nearpc 20
  • nearpc 0x08048484
  • nextcall -- Step until next 'call' instruction in specific memory range
  • nextcall cpy
  • nextjmp -- Step until next 'j*' instruction in specific memory range
  • nextjmp
  • nxtest -- Perform real NX test to see if it is enabled/supported by OS
  • patch -- 使用字符串/十六進制字符串/整形數
  • patch $esp 0xdeadbeef
  • patch $eax "the long string"
  • patch (multiple lines)
  • pattern -- 生成,搜索或寫入循環(huán) pattern 到內存
  • pattern_arg -- Set argument list with cyclic pattern
  • pattern_create -- Generate a cyclic pattern
  • pattern_env -- Set environment variable with a cyclic pattern
  • pattern_offset -- Search for offset of a value in cyclic pattern
  • pattern_patch -- Write a cyclic pattern to memory
  • pattern_search -- Search a cyclic pattern in registers and memory
    • pattern create 2000
    • pattern create 2000 input
    • pattern offset $pc
    • pattern search
    • pattern patch 0xdeadbeef 100
  • payload -- Generate various type of ROP payload using ret2plt
  • payload copybytes
  • payload copybytes target "/bin/sh"
  • payload copybytes 0x0804a010 offset
  • pdisass -- Format output of gdb disassemble command with colors
  • pdisass $pc /20
  • pltbreak -- Set breakpoint at PLT functions match name regex
  • pltbreak cpy
  • procinfo -- 顯示調試進程的 /proc/pid/
  • procinfo
  • procinfo fd
  • profile -- Simple profiling to count executed instructions in the program
  • pyhelp -- Wrapper for python built-in help
  • pyhelp peda
  • pyhelp hex2str
  • pshow -- 顯示各種 PEDA 選項和其他設置
  • pshow
  • pshow option context
  • pset -- 設置各種 PEDA 選項和其他設置
  • pset arg '"A"*200'
  • pset arg 'cyclic_pattern(200)'
  • pset env EGG 'cyclic_pattern(200)'
  • pset option context "code,stack"
  • pset option badchars "\r\n"
  • readelf -- 獲取 ELF 的文件頭信息
  • readelf libc .text
  • refsearch -- Search for all references to a value in memory ranges
  • refsearch "/bin/sh"
  • refsearch 0xdeadbeef
  • reload -- Reload PEDA sources, keep current options untouch
  • ropgadget -- 獲取二進制或庫的常見 ROP gadgets
  • ropgadget
  • ropgadget libc
  • ropsearch -- 搜索內存中的 ROP gadgets
  • ropsearch "pop eax"
  • ropsearch "xchg eax, esp" libc
  • searchmem|find -- 搜索內存中的 pattern; 支持正則表達式搜索
  • find "/bin/sh" libc
  • find 0xdeadbeef all
  • find "..\x04\x08" 0x08048000 0x08049000
  • searchmem -- Search for a pattern in memory; support regex search
  • session -- Save/restore a working gdb session to file as a script
  • set -- Set various PEDA options and other settings
  • set exec-wrapper ./exploit.py
  • sgrep -- Search for full strings contain the given pattern
  • shellcode -- 生成或下載常見的 shellcode
  • shellcode x86/linux exec
  • show -- Show various PEDA options and other settings
  • skeleton -- 生成 python exploit 代碼模板
  • skeleton argv exploit.py
  • skipi -- Skip execution of next count instructions
  • snapshot -- Save/restore process's snapshot to/from file
  • snapshot save
  • snapshot restore
  • start -- Start debugged program and stop at most convenient entry
  • stepuntil -- Step until a desired instruction in specific memory range
  • stepuntil cmp
  • stepuntil xor
  • strings -- Display printable strings in memory
  • strings
  • strings binary 4
  • substr -- Search for substrings of a given string/number in memory
  • telescope -- Display memory content at an address with smart dereferences
  • telescope 40
  • telescope 0xb7d88000 40
  • tracecall -- Trace function calls made by the program
  • tracecall
  • tracecall "cpy,printf"
  • tracecall "-puts,fflush"
  • traceinst -- Trace specific instructions executed by the program
  • traceinst 20
  • traceinst "cmp,xor"
  • unptrace -- Disable anti-ptrace detection
  • unptrace
  • utils -- Miscelaneous utilities from utils module
  • vmmap -- 在調試過程中獲取段的虛擬映射地址范圍
  • cmmap
  • vmmap binary / libc
  • vmmap 0xb7d88000
  • waitfor -- Try to attach to new forked process; mimic "attach -waitfor"
  • waitfor
  • waitfor myprog -c
  • xinfo -- Display detail information of address/registers
  • xinfo register eax
  • xinfo 0xb7d88000
  • xormem -- 用一個 key 來對一個內存區(qū)域執(zhí)行 XOR 操作
  • xormem 0x08049000 0x0804a000 “thekey”
  • xprint -- Extra support to GDB's print command
  • xrefs -- Search for all call/data access references to a function/variable
  • xuntil -- Continue execution until an address or function

使用 PEDA 和 Python 編寫 gdb 腳本

  • 全局類
  • pedacmd
    • 交互式命令
    • 沒有返回值
    • 例如:pedacmd.context_register()
  • peda
    • 與 gdb 交互的后端功能
    • 有返回值
    • 例如:peda.getreg("eax")
  • 小工具
    • 例如:to_int()、format_address()
    • 獲得幫助
    • pyhelp peda
    • pyhelp hex2str
  • 單行/交互式使用
  • gdb-peda$ python print peda.get_vmmap()
  • gdb-peda$ python > status = peda.get_status() > while status == "BREAKPOINT": > peda.execute("continue") > end
  • 外部腳本
  • # myscript.py def myrun(size): argv = cyclic_pattern(size) peda.execute("set arg %s" % argv) peda.execute("run") ?wzxhzdk:8? gdb-peda$ source myscript.py gdb-peda$ python myrun(100)

更多資料

http://ropshell.com/peda/

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 官方文檔 http://sourceware.org/gdb/current/onlinedocs/gdb/[ht...
    wayyyy閱讀 14,023評論 0 3
  • GDB的命令操作十分強大,下面將介紹一些常用命令。使用-tui選項可以將代碼顯示在一個漂亮的交互式窗口中;通過命令...
    追隨清居的誓言閱讀 1,064評論 0 0
  • 整理一下在linux下C/C++用gdb工具debug一些提高效率的操作?;镜膅db操作就不在這里贅述了。 打印...
    DayDayUpppppp閱讀 2,142評論 0 2
  • 1.gcc編譯,首先使用編譯選項-g(在編譯的時候產生調試信息)。 2.進入gdb的方法: (1)gdb a.ou...
    小餅干_7270閱讀 932評論 0 1
  • 概述 GDB是一個由GNU開源組織發(fā)布的、UNIX/Linux操作系統(tǒng)下的、基于命令行的、功能強大的程序調試工具。...
    咕咕鷄閱讀 21,125評論 0 8

友情鏈接更多精彩內容