GDB的常见用法

1. 编译文件

1
gcc -g test.c -o test

编译时默认不会把debug选项加进去,需要在编译时手动添加-g来加入debug。

运行GDB,用file来指定文件。

2.常见用法

  1. b(breakpoint)

    在函数下断点。

    b 行数

    在文件的第几行下断点。

  2. r (run)

run程序,在即将执行断点之前停下。

  1. n(next)

    不进入函数的单步执行。

  2. 回车

    执行上一步的命令。

  3. s(step)

    进函数的单步。

  4. k(kill)

    kill当前进程。

  5. info b

    查看当前断点。

  6. d 符号

    除去符号处断点。

  7. c

    直接执行到下一个断点。

  8. bt

    查看函数调用栈。

  9. watch point

    监视某一个变量,运行到变量变化的地方停下。

  10. info r

    查看所有寄存器的值。

  11. info variables

    打印所有符号。

  12. p(print) point

    查看变量值。

  13. /x

    以十六进制输出。

  14. layout src

    以图形化模式的c语言gdb。以ctrl+x,a退出。

  15. layout split

    显示源代码和汇编指令窗口

  16. layout reg

    显示寄存器窗口

  17. layout asm

    以汇编模式gdb,汇编单步是si和ni

  18. list

    查看源代码。

  19. q(quit)

    退出gdb。

  20. finish

    步出。

  21. set

    设置某个寄存器的值为多少

  22. *b $rebase(offset)

    需要使用pwndbg在开启PIE的地方下断点

显示内存数据

p系列

  1. p system/main

    显示某个函数地址

  2. p $esp

    显示寄存器

  3. p 0xff - 0xea

    计算器

  4. print &varName

    查看变量地址

  5. *p 0xffffebac

    查看某个地址处的值

x系列

命令格式:x/ <n/f/u>

n 是一个正整数,表示需要显示的内存单元个数,(默认为1)

f 表示显示格式(b字符,s字符串,i汇编指令,x十六进制,d十进制)默认为十六进制

u 表示从当前地址往后请求的字节数,默认为4byte ,b表示单字节,h表示双字节,w表示4字节,g表示8字节。

info系列

  1. info registers $ebp 查看寄存器ebp中的内容(简写为 i r ebp)
  2. i r eflags 查看状态寄存器
  3. i r ss 查看段寄存器
  4. i b 查看断点信息
  5. i function 看看所有函数

disas系列

  1. disassemble addr

    查看addr处前后的反汇编代码

  2. disassemble function

    查看function函数的反汇编代码

  3. disassemble

    反汇编从开始地址到结束地址的部分

peda带有

  1. stack 20

    查看栈内20个值

  2. show args

    查看参数

  3. **vmmp **

    查看映射状况

  4. **readelf **

    查看elf文件中各个段的起始地址

  5. parseheap

    显示堆状况

查找字符串

  1. find

    查找字符串

  2. searchmem

    查找字符串

  3. ropsearch “xor eax,eax;ret” 0x8048080 0x80050000

    查找某段的rop

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    Enhance the display of gdb: colorize and display disassembly codes, registers, memory information during debugging.
    Add commands to support debugging and exploit development (for a full list of commands use peda help):
    aslr -- Show/set ASLR setting of GDB
    checksec -- Check for various security options of binary
    dumpargs -- Display arguments passed to a function when stopped at a call instruction
    dumprop -- Dump all ROP gadgets in specific memory range
    elfheader -- Get headers information from debugged ELF file
    elfsymbol -- Get non-debugging symbol information from an ELF file
    lookup -- Search for all addresses/references to addresses which belong to a memory range
    patch -- Patch memory start at an address with string/hexstring/int
    pattern -- Generate, search, or write a cyclic pattern to memory
    procinfo -- Display various info from /proc/pid/
    pshow -- Show various PEDA options and other settings
    pset -- Set various PEDA options and other settings
    readelf -- Get headers information from an ELF file
    ropgadget -- Get common ROP gadgets of binary or library
    ropsearch -- Search for ROP gadgets in memory
    searchmem|find -- Search for a pattern in memory; support regex search
    shellcode -- Generate or download common shellcodes.
    skeleton -- Generate python exploit code template
    vmmap -- Get virtual mapping address ranges of section(s) in debugged process
    xormem -- XOR a memory region with a key
    Installation

3.GDB的小技巧

  1. shell
1
shell ls

通过shell调用终端命令。

  1. 日志模式
1
set logging on

断点分为breakpoint(断点)和watchpoint(观察点)和catchpoint(捕捉点)。

4.调试挂掉的文件(core文件)

1
2
3
4
5
6
7
8
#include<stdio.h>

int main(){
int* temp = NULL;
*temp = 10;
return 0;
}

core一般比较大,不会默认生成。要去更改权限。

用ulimit去查看限制。

1
ulimit -a

更改core文件生成权限。

1
ulimit -c unlimited

gdb 二进制文件 core文件。

1
gdb test.c core

5.调试一个正在运行的程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<stdio.h>


void test(){

}


void test1(){
int i = 0;
i++;
}

int main(){
for(;;){
test();
test1();
}
return 0;
}

ps:在运行一个程序时可以在后面加上&来让程序在后台执行。

1
2
./a.out &
gdb -p pid

6.堆操作指令

pwndbg插件独有

  • arena显示arena的详细信息
  • arenas显示所有arena的基本信息
  • arenainfo好看的显示所有arena的信息
  • bins常用,查看所有种类的堆块的链表情况
  • fastbins单独查看fastbins的链表情况
  • largebins单独查看largebins的链表情况
  • smallbins单独查看smallbins的链表情况
  • unsortedbin单独查看unsortedbin链表情况
  • tcachebins //同上,单独查看tcachebins的链表情况
  • tcache //查看tcache详细信息
  • heap //数据结构的形式显示所有堆块,会显示一大堆
  • heapbase //查看堆起始地址
  • heapinfoheapinfoall //显示堆得信息,和bins的挺像的,没bins好用
  • parseheap //显示堆结构,很好用
  • tracemalloc //好用,会跟提示所有操作堆的地方

7.其他pwndbg插件独有指令

  • cyclc 50 //生成50个用来溢出的字符

  • $reabse //开启PIE的情况的地址偏移

  • b *$reabse(0x123456) //断住PIE状态下的二进制文件中0x123456的地方

  • codebase //打印PIE偏移,与rebase不同,这是打印,rebase是使用

  • stack //查看栈

  • retaddr //打印包含返回地址的栈地址

  • canary //直接看canary的值

  • plt //查看plt表

  • got //查看got表

  • hexdump//想IDA那样显示数据,带字符串

  • ASLR//显示/设定GDB的ASLR(地址空间配置随机加载)设置

  • dumpargs//函数将要被调用时,显示将要被传入函数的所有参数(默认会在反汇编代码下方自动显示)

  • dumprop // 在给定内存范围中Dump出所有ROP gadgets

  • elfheader // Get headers information from debugged ELF file

  • elfsymbol // 获取non-debugging symbol信息(plt表)

  • lookup – Search for all addresses/references to addresses which belong to a memory range

  • patch – Patch memory start at an address with string/hexstring/int

  • pattern – 生成字符串模板 写入内存 用于定位溢出点

    • pattern create size 生成特定长度字符串
    • pattern offset value 定位字符串
  • procinfo – Display various info from /proc/pid/

  • pshow – Show various PEDA options and other settings

  • pset – Set various PEDA options and other settings

  • searchmem|find – 在内存中查找字符串,支持正则表达式

  • shellcode – 生成shellcode

8.调试多线程

(1)多线程调试命令

shell的命令:

(1)查看当前运行的进程:ps aux | grep book

(2)查看当前运行的轻量级进程:ps -aL | grep book

(3)查看主线程和子线程的关系:pstree -p 主线程id

gdb的命令:

(1)查看可切换调试的线程:info threads

(2)切换调试的线程:thread 线程id

(3)只运行当前线程:set scheduler-locking on

(4)运行全部的线程:set scheduler-locking off

(5)指定某线程执行某gdb命令:thread apply 线程id gdb_cmd

(6)全部的线程执行某gdb命令:thread apply all gdb_cmd

9.GDB多进程调试

使用 GDB 调试的时候,GDB 默认只能跟踪一个进程,可以在 fork 函数调用之前,通过指令设置 GDB 调试工具跟踪父进程或者是跟踪子进程,默认跟踪父进程。

①.设置调试进程

展示调试父进程或者子进程:

show follow-fork-mode [parent(默认)| child]

设置调试父进程或者子进程:

set follow-fork-mode [parent(默认)| child]

②.调试模式

展示调试模式:

show detach-on-fork [on | off]

设置调试模式:

set detach-on-fork [on | off]

认为 on,表示调试当前进程的时候,其它的进程继续运行,如果为 off,调试当前进程的时候,其它进程被 GDB 挂起。

查看调试的进程:

info inferiors

切换当前调试的进程:

inferior id

使进程脱离 GDB 调试:

detach inferiors id