gdb
持续更新
前言
本文指令是建立在安装了 pwndbg 插件的 gdb 上的。
基本指令
s
(step)单步步入,遇到函数调用会进入函数内部si
汇编层面执行单步操作
n
(next)单步步过,遇到函数不进入ni
常用,同n,汇编层面的一步
c
(continue)继续执行到断点,没断点就一直执行下去r
重新开始执行start
重新运行程序暂停到_start
函数finish
步出函数q
quit 退出调试
查看调试信息
context
查看调试器上下文argc
查看命令行参数的数量argv
查看命令行参数args
查看程序参数i
(info)查看一些信息,只输入info可以看可以接什么参数,下面几个比较常用i b
//常用,info break 查看所有断点信息(编号、断点位置)i r
//常用,info registers 查看各个寄存器当前的值i f
//info function 查看所有函数名,需保留符号
show
用于查看调试器的基本信息show directories
查看gdb的源码搜索路径show environment
查看环境变量
backtrace
查看调用栈vmmap
内存分配情况jump
命令可以用来跳转到指定的代码行或函数地址。- 跳转到指定的代码行:
jump <line_number>
- 跳转到指定的函数:
jump <function_name>
- 跳转到指定的内存:
jump *<address>
- 跳转到指定的代码行:
dir
命令用于设置或显示源代码文件的搜索路径。具体来说,dir
命令可以用来告诉 GDB 在哪里查找源代码文件,以便在调试时能够正确显示源码。tls
查看线程telescope
解引用info variables
查看所有的变量信息p &__bss_start
查看bss段起始位置info functions
显示函数i frame
打印函数堆栈帧信息info sharedlibrary
显示共享链接库cyclic 50
生成 50 个用来溢出的字符,默认生成 100 个magic
查看常用的漏洞利用点$reabse
开启PIE的情况的地址偏移b *$reabse(0x123456)
//断住PIE状态下的二进制文件中0x123456的地方codebase
//打印PIE偏移,与rebase不同,这是打印,rebase是使用
stack
查看栈retaddr
//打印包含返回地址的栈地址canary
//直接看canary的值plt
//查看plt表got
//查看got表hexdump
显示十六进制数据并显示ASCII字符`environ
ld
elf
显示elf段表的头部信息info files
显示有关elf文件的信息,包括加载的段信息xinfo
以结构体的方式输出内存地址的详细信息
断点指令
下普通断点指令b(break):
b 函数名
b 行号
b *地址
b *(0x123456)
//常用,给0x123456地址处的指令下断点b *$ rebase(0x123456)
//$rebase 在调试开PIE的程序的时候可以直接加上程序的随机地址
b fun_name
//常用,给函数fun_name下断点,目标文件要保留符号才行b file_name:fun_name
b file_name:15
//给file_name的15行下断点,要有源码才行b 15
b +0x10
//在程序当前停住的位置下0x10的位置下断点,同样可以-0x10,就是前0x10break fun if $rdi==5
//条件断点,rdi值为5的时候才断
删除、禁用断点:
info break
(简写:i b
) //查看断点编号delete 5
//常用,删除5号断点,直接delete不接数字删除所有disable 5
//常用,禁用5号断点enable 5
//启用5号断点clear
//清除下面的所有断点
内存断点指令watch:
watch 0x123456
//0x123456地址的数据改变的时候会断watch a
//变量a改变的时候会断info watchpoints
//查看watch断点信息
捕获断点catch:
catch syscall
//syscall系统调用的时候断住tcatch syscall
//syscall系统调用的时候断住,只断一次info break
//catch的断点可以通过i b查看
1 |
|
打印指令
打印指令p
(print):
p fun_name
打印fun_name的地址,需要保留符号p 0x10-0x08
计算0x10-0x08的结果p &a
查看变量a的地址p *(0x123456)
//查看0x123456地址的值,注意和x指令的区别,x指令查看地址的值不用星号p $rdi
显示rdi寄存器的值,注意和x的区别,这只是显示rdi的值,而不是rdi指向的值p *($rdi)
显示rdi指向的值
打印汇编指令disass(disassemble):
disass 0x123456
//显示0x123456前后的汇编指令x /10i
//我一般喜欢用x显示指令
查看和修改数据
查看内存指令
x /nuf 0x123456
//常用,x指令的格式是:x空格/nfu,nfu代表三个参数n
代表显示几个单元(而不是显示几个字节,后面的u表示一个单元多少个字节),放在/
后面u
代表一个单元几个字节,b(一个字节),h(2字节),w(四字节),g(八字节)f
代表显示数据的格式,f和u的顺序可以互换,也可以只有一个或者不带n,用的时候很灵活
1 |
|
x /10gx 0x123456
//常用,从0x123456开始每个单元八个字节,十六进制显示10个单元的数据x /10xd $rdi
//从rdi指向的地址向后打印10个单元,每个单元4字节的十进制数x /10i 0x123456
//常用,从0x123456处向后显示十条汇编指令
修改数据指令
set $rdi=0x10
//把rdi寄存器的值变为0x10set *(0x123456)=0x10
//0x123456地址的值变为0x10,注意带星号set *(short *)(0x123456)=0x1234
设置2字节的值set *(int *)(0x123456)=0x12345678
设置4个字节的值set *(long long *)(0x123456)=0x12345678
设置8个字节的值
set args "abc" "def" "gh"
//给参数123赋值set args "python -c 'print "1234\x7f\xde"'"'
//使用python给参数赋值不可见字符- 使用
set $pc
命令- 使用
set $pc=0x8048400
直接设置程序计数器的值,来达到跳转到指定地址的目的
- 使用
查找数据
search rdi
//从当前位置向后查包含rdi的指令,返回若干find "hello"
//查找hello字符串,pwndbg独有ropgadget
//查找ropgadget,pwndbg独有,没啥用,可以用其他工具search -p canary
搜索canary位置
堆操作指令
arena
//显示arena的详细信息arenas
//显示所有arena的基本信息arenainfo
//好看的显示所有arena的信息x/32gx &main_arena
查看main_arena的内存分配情况x/32gx &main_arena
查看main_arena上的值call malloc_stats()
打印malloc分配的内存p malloc(0x100)
打印分配的堆块info threads
多线程调试bins
fastbins
//单独查看fastbins的链表情况largebins
//同上,单独查看largebins的链表情况smallbins
//同上,单独查看smallbins的链表情况unsortedbin
//同上,单独查看unsortedbin链表情况tcachebins
//同上,单独查看tcachebins的链表情况tcache
//查看tcache详细信息
heap
显示堆信息heap -v
查看堆块的详细信息heapbase
查看堆起始地址heapinfo
、heapinfoall
//显示堆得信息,和bins的挺像的,没bins好用parseheap
//显示堆结构,很好用vis
可视化堆
tracemalloc
//好用,会跟提示所有操作堆的地方
内存转储命令
- 使用
dump
命令dump binary memory <filename> <start_address> <end_address>
<filename>
:要保存内存转储的文件名<start_address>
:要转储的内存区域的起始地址<end_address>
:要转储的内存区域的结束地址
- 查看转储的文件
hexdump -C dump.bin
- 从文件加载内存
restore <filename> binary memory <start_address> <end_address>
<filename>
:包含内存内容的文件名<start_address>
:要恢复到的内存区域的其实地址<end_address>
:要恢复到的内存区域的结束地址
源码调试
list
默认查看附近10行代码list 38
查看38行附近10行代码list 1,10
查看1-10行list main
查看main函数开始10行
远程调试
- 在目标机器上运行
gdbserver
1 |
|
- 连接
gdbserver
1 |
|
gdbserver
附加现有进程
1 |
|
内核调试
待施工