gdb使用教程(一)
摘要:复现缓冲区溢出的时候所使用的gdb命令及其解释
编译shi1.c
gcc -g shi1.c -o shi111 //一定要带-g选项,不然不能使用list列出源代码
调试shi111
(1)开始调试
gdb -q shi111 //-q不会显示gdb版本信息比较简洁
b a //在a函数定义断点
run //运行
(2)list列出源码
(3)backtrace打印堆栈
(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变量的值
以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函数的汇编代码:
打印a函数的汇编代码(因为打断点是在a函数打的,还没运行到a函数,所以不能用a必须用a函数的地址):
实验代码
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。