1、相关知识
gdb
汇编
2、例子
include <stdio.h>
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 <gets>
; 判断modified变量的值是否是0
0x080482bd <+29>: cmpl $0x0,0x5c(%esp)
; 如果modified的值等于0,就跳转到 0x080482d2
0x080482c2 <+34>: je 0x80482d2 <main+50>
; modified不为0,打印成功提示
0x080482c4 <+36>: movl $0x80b3eec,(%esp)
0x080482cb <+43>: call 0x8049500 <puts>
0x080482d0 <+48>: jmp 0x80482de <main+62>
; modified为0,打印失败提示
0x080482d2 <+50>: movl $0x80b3f0b,(%esp)
0x080482d9 <+57>: call 0x8049500 <puts>
0x080482de <+62>: mov $0x0,%eax
0x080482e3 <+67>: leave
0x080482e4 <+68>: ret
在gdb中执行b *0x080482bd命令对gets的下一条指令下一个断点:
设置完断点执行r命令,运行至断点处停止
在gdb中输入x $esp+0x5C,查看modified变量的值
执行ni命令,可以继续单步执行
执行c命令,让程序执行完