考完试了,来填坑
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 | b* 0x4009D8 |
输入以上的命令,在出现的菜单输入1
就会断在这个地方
就是我们下断点的地方
我们再下一个断点
1 | b* 0x400A1A |
然后输入c,继续运行
这个时候是不是什么都没显示?
这是因为我们上一个断点停在了call read这里,程序还在等待我们的输入
我们随便输入1234,按下回车
这个时候就断在了这个地方了
接下来我们介绍下如何调试开了pie的程序
我们先下载一个程序
将其复制到虚拟机中,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的教程或者基本用法