pwn从入门到放弃第三章——gdb的基本使用教程

考完试了,来填坑

gdb在做题中经常用到,熟练掌握gdb会事半功倍

我们继续用第二章中的程序来讲解gdb的使用

将程序直接拖进vmware中,因为我们下的vmware专用版本的kali,所以已经安装好vmware tool之类的,直接拖进去或者复制粘贴进去就可以了

打开terminal,cd到Desktop

先给程序加可执行权限,在terminal输入

1
chmod 777 babystack

然后输入

1
gdb ./babystack

然后就会出现如下图一样的界面

接下面介绍gdb比较实用的两个功能

checksec

在gdb的termial中输入

1
checksec

checksec是用来显示程序保护机制的开启情况

我们来解释下显示的东西

  • Arch,很明显就是程序是多少位的,这里是64位的
  • RELRO,这里是Full RELRO,RELRO的全程是RELocation Read-Only,重定位只读(渣翻译不要吐槽,开启了这个之后got表是只读的,不能往里面写东西,got表这个概念会在后面介绍,这里先知道这个名词就可以了,除此之外还有其他东西改变了,深入下去可以完全当一章来写
  • Stack: 这里是栈溢出保护,保护的机制也暂时先不谈
  • NX: 这里是堆栈不可执行,也就是堆和栈没有执行权限,这个也会在后面ret2shellcode那章解释
  • PIE:地址重定位,开启了PIE和没有开启PIE是两种不同的难度,而且开启了PIE会使程序调试起来比较麻烦

vmmap

vmmap是用来查看程序各种段的地址和范围的,会经常用到

在gdb的terminal中输入

1
vmmap

然后就会提示这个….好吧,我们再输入r,运行程序,r是run的缩写

之后按下ctrl+c

就会出现这个界面,不用担心,这个是正常的,gdb接收到信号,让程序停在那里而已,这个时候再输入vmmap

我们来解释下怎么看显示的东西

这里显示说明了哪个颜色是哪个段的,为了让没学过操作系统的也明白,我简单解释下各个名词

  • STACK:栈,用来保存函数运行时的临时变量等
  • HEAP:堆,一般是主动编写代码来分配和回收堆内存
  • CODE: 代码段,是用来存放代码的
  • DATA:数据段,一般用来存放全局变量

除此之外还有白色的,一般是用来存放各种不可修改的数据的,如这里的0x600000 - 0x601000,是用来存放程序的静态变量,大部分是各种字符串

这里是各个段的开始和结束位置

这里是各个段的权限

  • r 可读
  • w 可写
  • x 可执行

这里是各个段的来源或者标识,例如前三个段就来自babystack,[stack] 就说明这是栈

下面来介绍下gdb的基本操作

  • r = run 运行程序,如果你当前已经在运行程序了,再输入r会重新运行程序
  • b = break 下断点,在调试pwn中,一般是 b 0xabcde ,abcde是在ida中看到的地址,如b 0x400908
  • c = continue 继续运行程序直到停在下一个断点
  • n = next 下一行,一般装了pwndbg之后下一行指的是下一条汇编,但是如果调试的程序是带调试信息的,一般会跳几行汇编
  • ni = nexti 下一条指令,这个就是真正的下一条汇编指令
  • s = step 继续运行程序直到跳到不同的函数,一般是调用call之后会停在call那个函数的开始位置
  • d = delete 删除断点,后面可带数字,说明删除第几个断点,如果不带参数,说明删除全部断点
  • x 查看内存

这些指令的具体用法都可以用help来查看,如

1
help x

而且一般c,n,ni这几个程序都可以带一个数字,用来代表连续运行这个指令多少次,如

1
ni 10

就代表下10行指令

其中x的用法要熟练掌握!

我们用help来查看x的用法,基本的格式是

1
x/格式  地址


1
x/10xw 0x601020

这里就代表以16进制的格式显示0x601020开始的10个字,这里的字是4个字节

运行的结果

还有一个例子就是

1
s/10s 0x400ABD

这里是显示从0x400ABD开始的10条字符串

这里还要介绍一个就是,在调试32位和64位的程序的时候,要用不同的大小,在64位程序上一般用

1
x/40xg 0x601020

而在32位程序上一般是

1
x/40xw 0x601020

这个是因为64位程序的一个地址一般用两个字来表示,而32位只用一个字

我们来练习下下断点

1
2
b* 0x4009D8
r

输入以上的命令,在出现的菜单输入1

就会断在这个地方

就是我们下断点的地方

我们再下一个断点

1
b* 0x400A1A

然后输入c,继续运行

这个时候是不是什么都没显示?

这是因为我们上一个断点停在了call read这里,程序还在等待我们的输入

我们随便输入1234,按下回车

这个时候就断在了这个地方了

接下来我们介绍下如何调试开了pie的程序

我们先下载一个程序

babyheap

将其复制到虚拟机中,chmod 777 babyheap加权限,gdb ./babyheap调试

先输入r,运行程序,然后按ctrl+c,输入vmmap,查看程序的基址

这里我的基址是0x555555554000,每个人的可能有些不同

在ida中看到的地址不像没开pie的,这里只有很短的4位,所以假如说我要在1063这个地址下个断点,在gdb中是

1
b* 0x1063+0x555555554000

后面的基址如果是gdb attach来调试的话,每次都会改变,但是像这样用gdb来调试的话,不会每次都改变

我们来练习一下,假如要下个断点在0xB9C


1
b* 0xB9C+0x555555554000

然后再输入c,然后再随便输入个数字

可以看到程序断在了

这里就是gdb的基本操作,如果想了解gdb的更多骚操作,可以去百度或者谷歌搜下gdb的教程或者基本用法