pwn-note(form brokenpoems)
pwn-note
gcc 编译的指令
- NX:
-z execstack
/-z noexecstack
(关闭 / 开启) - Canary:
-fno-stack-protector
/-fstack-protector
/-fstack-protector-all
(关闭 / 开启 / 全开启) - PIE:
-no-pie
/-pie
(关闭 / 开启) - RELRO:
-z norelro
/-z lazy
/-z now
(关闭 / 部分开启 / 完全开启)
plt got
plt
是寻址用的->作用就是去 got
表寻找最后调用 libc
中的函数got
可以理解为一个函数指针列表 函数一开始没调用时不是指向libc
指向一段init汇编
recv
interactive() : 在取得shell之后使用,直接进行交互,相当于回到shell的模式。
recv(numb=字节大小, timeout=default) : 接收指定字节数。
recvall() : 一直接收直到达到文件EOF。
recvline(keepends=True) : 接收一行,keepends为是否保留行尾的\n。
recvuntil(delims, drop=False) : 一直读到delims的pattern出现为止。
recvrepeat(timeout=default) : 持续接收直到EOF或timeout。
syscall和函数传参
arm 一般要具体情况具体分析
这里列举了常见的4种架构
- x86
- 返回值 :
eax
- syscall :
int 0x80
- syscall调用号:
eax
- syscall参数:
ebx
,ecx
,edx
,esi
,edi
,ebp
- 函数参数:
stack
- 返回值 :
- x86_64
- 返回值 :
rax
- syscall :
syscall
- syscall调用号:
rax
- syscall参数:
rdi
,rsi
,rdx
,r10
,r8
,r9
- 函数参数:
rdi
,rsi
,rdx
,rcx
,r8
,r9
,stack
- 返回值 :
- arm32(aarch32)
- 返回值 :
r7
- syscall :
svc 0
- syscall调用号:
r7
- syscall参数:
r0
,r1
,r2
,r3
,stack
- 函数参数:
r0
,r1
,r2
,r3
,stack
- 返回值 :
- arm64(aarch64)
- 返回值 :
x0
- syscall :
svc 0
- syscall调用号:
x8
- syscall参数:
x0
,x1
,x2
,x3
,x4
,x5
- 函数参数:
x0
,x1
,x2
,x3
,x4
,x5
,x6
,x7
,stack
- 返回值 :
ps:
- 这里注意Linux
syscall
函数^[int syscall(int syscall_id, ...);
使用函数形式传递系统调用号,所以传递到第一个函数参数所对应的存储位置,接下来的几个参数往后推] - x寄存器=w寄存器
- svc软中断=swi软中断
gdb 相关[转载自https://www.cnblogs.com/murkuo/p/15965270.html稍有改动]
基本指令
help
帮助i
info,查看一些信息,只输入 info 可以看可以接什么参数,下面几个比较常用i b
常用,info break 查看所有断点信息(编号、断点位置)i r
常用,info registers 查看各个寄存器当前的值i f
info function 查看所有函数名,需保留符号
show
和 info 类似,但是查看调试器的基本信息,如:show args
查看参数rdi
常用,+寄存器名代表一个寄存器内的值,用在地址上直接相当与一个十六进制变量
backtrace
查看调用栈q quit
退出,常用vmmap
内存分配情况
执行指令
s
单步步入,遇到调用跟进函数中,相当于 step into,源码层面的一步si
常用,同 s,汇编层面的一步
n
单步补过,遇到函数不跟进,相当于 step over,源码层面的一步ni
常用,同 n,汇编层面的一步
c continue
常用,继续执行到断点,没断点就一直执行下去r run
常用,重新开始执行start
类似于 run,停在 main 函数的开始
断点指令
下普通断点指令 b(break):
b *(0x123456)
常用,给 0x123456 地址处的指令下断点b *$rebase(0x123456)
$rebase 在调试开 PIE 的程序的时候可以直接加上程序的随机地址b func
常用,给函数 func 下断点b file_name:func_name
b \*func+47
常用,给地址 func+47 处下断点b file_name:15
给 file_name 的 15 行下断点,要有源码才行b 15
b +0x10
在程序当前停住的位置下 0x10 的位置下断点,同样可以-0x10,就是前 0x10break fun if $rdi==5
条件断点,rdi 值为 5 的时候才断
删除、禁用断点:
info breakpoints,i b
查看断点编号delete 5,d 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 breakpoints
catch 的断点可以通过 i b 查看
除syscall
外还可以使用的有:throw
: 抛出异常catch
: 捕获异常exec
: exec 被调用fork
: fork 被调用vfork
: vfork 被调用load
: 加载动态库load libname
: 加载名为 libname 的动态库unload
: 卸载动态库unload libname
: 卸载名为 libname 的动态库syscall [args]
: 调用系统调用,args 可以指定系统调用号,或者系统名称
打印指令
查看内存指令 x:
x /nuf 0x123456
常用,x 指令的格式是:x 空格/nfu,nfu 代表三个参数n
代表显示几个单元(而不是显示几个字节,后面的 u 表示一个单元多少个字节),放在/后面u
代表一个单元几个字节,b(一个字节),h(2 字节),w(四字节),g(八字节)f
代表显示数据的格式,f 和 u 的顺序可以互换,也可以只有一个或者不带 n,用的时候很灵活- x 按十六进制格式显示变量。
- d 按十进制格式显示变量。
- u 按十六进制格式显示无符号整型。
- o 按八进制格式显示变量。
- t 按二进制格式显示变量。
- a 按十六进制格式显示变量。
- c 按字符格式显示变量。
- f 按浮点数格式显示变量。
- s 按字符串显示。
- b 按字符显示。
- i 显示汇编指令。
x /10gx 0x123456
常用,从 0x123456 开始每个单元八个字节,十六进制显示 10 个单元的数据x /10xd $rdi
从 rdi 指向的地址向后打印 10 个单元,每个单元 4 字节的十进制数x /10i 0x123456
常用,从 0x123456 处向后显示十条汇编指令
打印指令 p(print):
p func
打印函数 func 的地址,需要保留符号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 指令
打印源代码指令 list:
list
查看当前附近 10 行代码,要有源码,list 指令 pwn 题中几乎不用,但为了完整性还是简单举几个例子list 38
查看 38 行附近 10 行代码list 1,10
查看 1-10 行list main
查看 main 函数开始 10 行
修改和查找指令
修改数据指令 set:
set $rdi=0x10
把 rdi 寄存器的值变为 0x10set *0x123456=0x10
0x123456 地址的值变为 0x10,注意带星号set args "abc" "def" "gh"
给参数 123 赋值set args "python -c 'printf("1234\x7f\xde")'"
使用 python 给参数赋值不可见字符
查找数据:
search rdi
从当前位置向后查包含 rdi 的指令,返回若干search -h
查看 search 帮助,我也不太长用这个指令find "hello"
查找 hello 字符串,pwndbg 独有ropgadget
查找 ropgadget,pwndbg 独有,没啥用,可以用其他工具
堆操作指令(pwndbg 插件独有)`
arena
显示 arena 的详细信息arenas
显示所有 arena 的基本信息arenainfo
好看的显示所有 arena 的信息bins
常用,查看所有种类的堆块的链表情况fastbins
单独查看 fastbins 的链表情况largebins
同上,单独查看 largebins 的链表情况smallbins
同上,单独查看 smallbins 的链表情况unsortedbin
同上,单独查看 unsortedbin 链表情况tcachebins
同上,单独查看 tcachebins 的链表情况tcache
查看 tcache 详细信息heap
数据结构的形式显示所有堆块,会显示一大堆heapbase
查看堆起始地址heapinfo heapinfoall
显示堆得信息,和 bins 的挺像的,没 bins 好用parseheap
显示堆结构,很好用tracemalloc
好用,会跟提示所有操作堆的地方
其他 pwndbg 插件独有指令
cyclic(cyc)
生成用来溢出的字符串,如cyc -l aaaa/0x6161616161616161
返回溢出的 aaaa 溢出前有多少个字符cyc 50
生成一个 50 长度的溢出字符串(根据不同平台不同)
$rebase
开启 PIE 的情况的地址偏移b *$rebase(0x123456)
断住 PIE 状态下的二进制文件中 0x123456 的地方codebase
打印 PIE 偏移,与 rebase 不同,这是打印,rebase 是使用
stack
查看栈retaddr
打印包含返回地址的栈地址canary
直接看 canary 的值plt
查看 plt 表got
查看 got 表hexdump
像 IDA 那样显示数据,带字符串
libc版本对应
1 | Ubuntu22.04: libc-2.35 |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 FOR DREAM!