摘要:复现缓冲区溢出的时候所使用的gdb命令及其解释

编译shi1.c

gcc -g shi1.c -o shi111  //一定要带-g选项,不然不能使用list列出源代码

调试shi111

(1)开始调试

gdb -q shi111  //-q不会显示gdb版本信息比较简洁
b a  //在a函数定义断点
run  //运行

(2)list列出源码

gdb使用教程(一)1.jpg

(3)backtrace打印堆栈

gdb使用教程(一)2.jpg

(4)info -f 数字显示堆栈的详细信息

Stack frame at //当前栈的起始地址
eip //表示当前的eip寄存器的值,表示的是即将执行的指令的地址
saved eip //表示调用当前指令的指令地址
called by frame at //上一个栈的起始地址
caller of frame at //下一个栈的起始地址
Arglist at //参数列表的地址
Locals at //存放函数局部变量的地址
Previous frame's sp is //上一个栈帧的最后的ESP的值
Saved registers //寄存器的值在栈中的地址

Saved registers保存的是寄存器的
举个例子:
push ebp
mov ebp,esp
压栈的就是这个值,表示的是上个栈帧的ebp。压栈的值在栈中的地址就是ebp at

调用函数之前函数的下一条指令(eip)会被压入堆栈。压栈的值在栈中的地址就是eip at

可能用到的命令:

x/1x 地址    以0x形式打印地址中的内容
x/1s 地址    以字符串的形式打印地址中的内容
x/1i 地址    以指令的形式打印地址中的内容
p a 打印a变量的值
p system 打印system()的地址
set variable a=66 设置a变量的值

gdb使用教程(一)3.jpg

gdb使用教程(一)4.jpg

以info f 0 为例

Stack frame at 0xbfffed80:  //0栈帧从0xbfffed80开始
eip = 0x8048441 in a (shi1.c:5); saved eip = 0x8048488  //下一条要执行的指令在0x8048441处,这条指令被0x8048488处的指令所调用
called by frame at 0xbfffedb0  //上一个栈的起始地址为0xbfffedb0
source language c.
Arglist at 0xbfffed78, args: a=0x4, b=0x5 //参数的地址在0xbfffed78,参数为4,5
Locals at 0xbfffed78, Previous frame's sp is 0xbfffed80 
//Locals局部变量的值,鬼知道为啥等于Arglist的地址。
//Previous frame's sp是上个栈帧的esp值,等于这个栈帧的起始地址0xbfffed80
Saved registers:
  ebp at 0xbfffed78, eip at 0xbfffed7c
// ebp at上个栈帧的ebp被保存在0xbfffed78,
// a函数的下一条指令(eip)被保存在0xbfffed78

(5)disassemble打印指定函数的汇编代码

disassemble 地址/函数名  //打印指定函数的汇编代码
disassemble /m 地址/函数名 //上面显示代码,下面显示代码对应的汇编代码

打印main函数的汇编代码:

gdb使用教程(一)5.jpg

打印a函数的汇编代码(因为打断点是在a函数打的,还没运行到a函数,所以不能用a必须用a函数的地址):

gdb使用教程(一)6.jpg

实验代码

实验代码.rar

文章目录