GDB调试

这篇文章用于记录gdb调试的学习

常用指令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
gdb pwn #开始调试
b 函数名 #在指定函数处打断点
b* 地址 #在指定位置处设置断点
b* $rebase(要下断点的偏移) #有PIE时这样下断点得先run起来
n #c语言级的断点定位(走得快一点)
ni #汇编级别的断点定位(走得精细一点)
s/si #s与si的区别和n/ni相同,不同点在于s/si会进入函数内部
fibi #跳出函数
r #运行
c #让程序继续运行
stack 30 #查看此时栈中的内容
x/gx #计算偏移
x/1gx $rsp+0x10 #查看rsp+0x10处的值
start #开始程序

给exp加gdb调试

1
2
context.terminal = ["tmux","splitw","-h"]#左右分屏
gdb.attach(io)#放到想要在exp中停止的位置,程序在运行时候会停止在该处进行调试

此处加了一个小插件tmux可以双栏显示调试,更方便查看。

1
2
3
4
sudo apt update 
#确保包管理器是最新的
sudo apt install tmux
#安装tmux

终端输入tmux即可启动

在gdb调试中一般要注意三个区域

区域1:当前状态下各个寄存器中存储的值(可称之为寄存器区)

区域2:当前执行步骤所执行的汇编指令以及该指令附近的汇编语句(可称为程序汇编区)

区域3:从rsp往下部分栈中的情况(可称为栈区)

1

利用GDB计算偏移量

32位:返回地址的偏移为 ebp地址-esp地址-esp距起始位置的距离+4(ebp)

以这题为例

1
2
3
.text:08048E8F 8D 44 24 1C                   lea     eax, [esp+1Ch]
.text:08048E93 89 04 24 mov [esp], eax
.text:08048E96 E8 B5 67 00 00 call gets

1

使用x/gx计算0xffffd1d8-0xfffd150-0x1C+4=112

64位同理但是是+8

下断点

无PIE时

1
2
b main #main可换成任意函数
b* 地址

有PIE时

1
b* $rebase(要下断点的偏移)

使用这个指令前得先让程序跑起来,gdb才能知道elf的基地址,偏移可以在IDA中查看,IDA中此时看到的地址即为偏移

GDB放置在函数里时如何使用

gdb放置在exp里时通常可以查看我们的payload传输进去之后程序执行流的变化或调试寄存器的信息

可以以下几种形式进行调试

1
2
gdb.attach(io)  #放在哪里断点就下在哪里一般放在发送payload之前
gdb.attach(io,"b *0xaaaaa") #在程序的0xaaaaa处下断点

注意有时我们还没启动gdb程序执行流就已经关闭就会报错这样的信息

1

显示没有那个进程,debug输出可以看到我们的payload是被发送出去了的,这种情况就是脚本执行太快了gdb还没来得及启动就运行结束了,加上sleep(1)在发送或接收脚本之前即可解决