检测堆栈粉碎

我正在执行我的a.out文件。 执行后程序运行一段时间,然后退出消息:

**** stack smashing detected ***: ./a.out terminated* *======= Backtrace: =========* */lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x48)Aborted* 

可能的原因是什么?如何纠正?

这里的堆栈碎片实际上是由于gcc使用保护机制来检测缓冲区溢出错误。 例如在以下代码片段中:

 #include <stdio.h> void func() { char array[10]; gets(array); } int main(int argc, char **argv) { func(); } 

编译器(在本例中为gcc)添加了具有已知值的保护variables(称为canaries)。 大于10的inputstring会导致此variables损坏,从而导致SIGABRT终止程序。

为了得到一些见解,可以尝试在编译时使用选项-fno-stack-protector来禁用gcc的这种保护。 在这种情况下,你会得到一个不同的错误,当你试图访问一个非法的内存位置时,很可能是一个分段错误。 请注意,因为这是一项安全function,因此应始终打开“ -fstack-protector以进行发布。

通过使用debugging器运行程序,可以获得关于溢出点的一些信息。 Valgrind不能很好地处理堆栈相关的错误,但是像debugging器一样,它可以帮助您确定崩溃的位置和原因。

请看下面的情况:

 ab@cd-x:$ cat test_overflow.c #include <stdio.h> #include <string.h> int check_password(char *password){ int flag = 0; char buffer[20]; strcpy(buffer, password); if(strcmp(buffer, "mypass") == 0){ flag = 1; } if(strcmp(buffer, "yourpass") == 0){ flag = 1; } return flag; } int main(int argc, char *argv[]){ if(argc >= 2){ if(check_password(argv[1])){ printf("%s", "Access granted\n"); }else{ printf("%s", "Access denied\n"); } }else{ printf("%s", "Please enter password!\n"); } } ab@cd-x:$ gcc -g -fno-stack-protector test_overflow.c ab@cd-x:$ ./a.out mypass Access granted ab@cd-x:$ ./a.out yourpass Access granted ab@cd-x:$ ./a.out wepass Access denied ab@cd-x:$ ./a.out wepassssssssssssssssss Access granted ab@cd-x:$ gcc -g -fstack-protector test_overflow.c ab@cd-x:$ ./a.out wepass Access denied ab@cd-x:$ ./a.out mypass Access granted ab@cd-x:$ ./a.out yourpass Access granted ab@cd-x:$ ./a.out wepassssssssssssssssss *** stack smashing detected ***: ./a.out terminated ======= Backtrace: ========= /lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x48)[0xce0ed8] /lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x0)[0xce0e90] ./a.out[0x8048524] ./a.out[0x8048545] /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0xc16b56] ./a.out[0x8048411] ======= Memory map: ======== 007d9000-007f5000 r-xp 00000000 08:06 5776 /lib/libgcc_s.so.1 007f5000-007f6000 r--p 0001b000 08:06 5776 /lib/libgcc_s.so.1 007f6000-007f7000 rw-p 0001c000 08:06 5776 /lib/libgcc_s.so.1 0090a000-0090b000 r-xp 00000000 00:00 0 [vdso] 00c00000-00d3e000 r-xp 00000000 08:06 1183 /lib/tls/i686/cmov/libc-2.10.1.so 00d3e000-00d3f000 ---p 0013e000 08:06 1183 /lib/tls/i686/cmov/libc-2.10.1.so 00d3f000-00d41000 r--p 0013e000 08:06 1183 /lib/tls/i686/cmov/libc-2.10.1.so 00d41000-00d42000 rw-p 00140000 08:06 1183 /lib/tls/i686/cmov/libc-2.10.1.so 00d42000-00d45000 rw-p 00000000 00:00 0 00e0c000-00e27000 r-xp 00000000 08:06 4213 /lib/ld-2.10.1.so 00e27000-00e28000 r--p 0001a000 08:06 4213 /lib/ld-2.10.1.so 00e28000-00e29000 rw-p 0001b000 08:06 4213 /lib/ld-2.10.1.so 08048000-08049000 r-xp 00000000 08:05 1056811 /dos/hacking/test/a.out 08049000-0804a000 r--p 00000000 08:05 1056811 /dos/hacking/test/a.out 0804a000-0804b000 rw-p 00001000 08:05 1056811 /dos/hacking/test/a.out 08675000-08696000 rw-p 00000000 00:00 0 [heap] b76fe000-b76ff000 rw-p 00000000 00:00 0 b7717000-b7719000 rw-p 00000000 00:00 0 bfc1c000-bfc31000 rw-p 00000000 00:00 0 [stack] Aborted ab@cd-x:$ 

当我禁用堆栈粉碎保护没有错误被发现,这应该发生在我使用“./a.out wepassssssssssssssssssss”

因此,要回答上面的问题,显示“** stack smashing detected:xxx”消息,因为您的堆栈粉碎保护器处于活动状态,并且发现程序中存在堆栈溢出。

只要找出发生的地方,并修复它。

你可以尝试使用valgrind来debugging问题:

Valgrind发行版目前包括六个产品质量工具:内存错误检测器,两个线程错误检测器,一个caching和分支预测分析器,一个调用图生成caching分析器和一个堆分析器。 它还包括两个实验工具: 堆/栈/全局数组溢出检测器 ,以及SimPoint基本块vector生成器。 它在以下平台上运行:X86 / Linux,AMD64 / Linux,PPC32 / Linux,PPC64 / Linux和X86 / Darwin(Mac OS X)。

这意味着你以非法的方式写入栈中的一些variables,很可能是由于缓冲区溢出 。

在使用malloc()将一些内存分配给一个struct *之后,我得到了这个错误,最后使用了free()函数释放分配的内存,然后错误信息消失:)