所以我尝试在这段代码上应用缓冲区溢出,
#include <stdio.h>
#include <string.h>
void hello()
{
printf("WELCOME TO THE SYSTEM");
}
int main(){
char passwd[10];
printf("ENTER THE PASSWORD: ");
scanf("%s", passwd);
if (strcmp(passwd,"pass")==0)
hello();
else
printf("WRONG PASSWORD");
}
我将用函数 hello 的地址溢出缓冲区 passwd,我希望看到“欢迎来到服务器”,但我得到的只是一个分段错误。我使用 gdb 进行进一步调查,
(gdb) print &hello
$1 = (void (*)()) 0x555555555159 <hello>
(gdb) run
Starting program: /home/reader/server
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
ENTER THE PASSWORD: aaaaaaaaa\x59\x51\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x59\x51\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x59\x51\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x59\x51\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x59\x51\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x59\x51\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x59\x51\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x59\x51\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x59\x51\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x59\x51\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x59\x51\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x59\x51\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55
Program received signal SIGSEGV, Segmentation fault.
0x00005555555551eb in main () at server.c:17
warning: Source file is more recent than executable.
hello函数的地址执行后没有改变。这是信息寄存器
rax 0x0 0
rbx 0x7fffffffe188 140737488347528
rcx 0x0 0
rdx 0x0 0
rsi 0x415020474e4f5257 4706297101230756439
rdi 0x7fffffffde80 140737488346752
rbp 0x5c3135785c393578 0x5c3135785c393578
rsp 0x7fffffffe078 0x7fffffffe078
r8 0xffff 65535
r9 0x0 0
r10 0x7ffff7f4d210 140737353404944
r11 0x7ffff7f4c800 140737353402368
r12 0x0 0
r13 0x7fffffffe198 140737488347544
r14 0x555555557dd8 93824992247256
r15 0x7ffff7ffd000 140737354125312
rip 0x5555555551eb 0x5555555551eb <main+119>
eflags 0x10202 [ IF RF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
如你所见,rbp 被覆盖了。
分析 gdb 输出表明您的堆栈溢出确实设法将控制转移到函数
hello()
,该函数调用 printf。但是,从函数 hello 返回并干净地终止程序(刷新输出缓冲区)将不起作用,因为您的堆栈已完全损坏。由于 printf()
默认情况下是行缓冲的,因此在程序崩溃发生之前不会打印字符串。
因此,尝试在
printf()
字符串末尾添加换行符,然后您应该观察该消息。