1、相关知识
gdb
汇编
2、例子
include
int main(int argc, char** argv)
{
int modified;
char buffer[64];
modified = 0;
gets(buffer); // 引发缓冲区溢出
if (modified != 0)
{
printf("Congratulations, you pwned it.\n");
}
else
{
printf("Please try again.\n");
}
return 0;
}
对该程序进行gdb调试
gdb 程序名进入调试状态
使用 disas main获取程序汇编代码
0x080482a0 <+0>: push %ebp
0x080482a1 <+1>: mov %esp,%ebp
0x080482a3 <+3>: and $0xfffffff0,%esp
; esp = esp - 0x60,即在栈上分配0x60)字节的空间
0x080482a6 <+6>: sub $0x60,%esp
; modified变量位于esp + 0x5C处,将其初始化为0
0x080482a9 <+9>: movl $0x0,0x5c(%esp)
; buffer位于esp + 0x1C处
0x080482b1 <+17>: lea 0x1c(%esp),%eax
0x080482b5 <+21>: mov %eax,(%esp)
; 调用gets(buffer)读取输入数据
0x080482b8 <+24>: call 0x8049360
; 判断modified变量的值是否是0
0x080482bd <+29>: cmpl $0x0,0x5c(%esp)
; 如果modified的值等于0,就跳转到 0x080482d2
0x080482c2 <+34>: je 0x80482d2
; modified不为0,打印成功提示
0x080482c4 <+36>: movl $0x80b3eec,(%esp)
0x080482cb <+43>: call 0x8049500
0x080482d0 <+48>: jmp 0x80482de
; modified为0,打印失败提示
0x080482d2 <+50>: movl $0x80b3f0b,(%esp)
0x080482d9 <+57>: call 0x8049500
0x080482de <+62>: mov $0x0,%eax
0x080482e3 <+67>: leave
0x080482e4 <+68>: ret
在gdb中执行b *0x080482bd命令对gets的下一条指令下一个断点:
设置完断点执行r命令,运行至断点处停止
在gdb中输入x $esp+0x5C,查看modified变量的值
执行ni命令,可以继续单步执行
执行c命令,让程序执行完