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 命令,让程序执行完