在写前面代码的时候,搞出了个 数组越界的问题,
直接报了*** stack smashing detected ***: ./main terminated
Aborted (core dumped)
这一章就记录在C++中怎么排查这种错误
“Stack smashing detect”
“Stack smashing detect” 是指在程序运行过程中检测到栈溢出的情况。栈溢出是一种常见的安全漏洞,发生在程序尝试往栈空间写入超过其边界范围的数据时。
通常,导致 “Stack smashing detect” 错误的原因可能包括:
- 缓冲区溢出:当向一个缓冲区写入超过其分配大小的数据时,会覆盖到相邻的内存地址,导致栈被破坏。
- 函数调用错误:函数调用时参数传递错误或者返回值处理不当,可能引起栈结构被破坏。
- 格式化字符串漏洞:使用不当的格式化字符串函数(如printf)可能造成栈溢出。
- 递归深度过大:如果递归调用层数过多,可能导致栈空间耗尽而触发 stack smashing detect。
为了解决这个问题,可以采取以下措施:
- 对于缓冲区操作,请确保输入数据不会超过缓冲区边界,并进行输入验证和长度检查。
- 确保正确处理函数调用时传递的参数和返回值。
- 避免使用不受信任或未经验证的格式化字符串。
- 如果需要使用递归,请确保控制递归深度,并设置适当的终止条件。
总之,”Stack smashing detect” 错误是一个指示栈溢出问题的警告,需要检查代码中可能导致栈溢出的地方并进行修复。
一、Linux开发环境
OS:Ubuntu 16.04.1
编译工具:gcc 5.4.0
调试工具:gdb
二、关键词
栈保护
栈溢出
*** stack smashing detected ***
-fstack-protector
-fno-stack-protector
三、背景
gcc提供栈溢出保护机制,即默认编译时-fstack-protector选项为开。
在该保护机制下,如果程序中有栈溢出,会有以下报错信息,程序异常终止:
*** stack smashing detected ***: ./test terminated
Aborted (core dumped)
若要关闭栈溢出保护,在gcc编译选项中增加-fno-stack-protector即可。
关闭后,如果程序中有栈溢出,仍可能会成功执行完,没有任何报错。
但实际上,栈溢出会导致程序中定义的变量被篡改。
如果你的程序出现上面提到的两种异常:变量被篡改、或者栈溢出导致的异常终止,希望本文会对你有帮助。
四、定位分析
1)第一种情况:变量的值被篡改。
a)源代码(可不看)
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "math.h"
#include <ctype.h>
int c2i(char ch)
{
//如果是数字,则用ascii 减去48
//isdight 判断数字函数
if(isdigit(ch))
{
return ch-48;
}
//判断字母
if(ch<'A'||(ch>'F'&&ch<'a')||ch>'z')
{
return -1;
}
//大写字母减去55,小写字母减去87
if(isalpha(ch))
{
return isupper(ch)?ch-55:ch-87;
}
}
int hex2dec(char *hex)
{
int len, num,temp,bits,i;
num = 0;
len = strlen(hex);
//printf("len = %d\n",len);
for(i=0,temp=0;i<len;i++,temp=0)
{
//printf("hex = %c\n",hex[i]);
//printf("num = %d\n",num);
temp = c2i(*(hex+i));
//printf("temp = %d\n",temp);
bits = (len-i-1)*4;
//printf("bits = %d\n",bits);
temp = temp << bits;
//printf("temp = %d\n",temp);
num = num|temp;
}
return num;
}
char* itoa(long int num,char *str,int radix)
{
char index[] = "0123456789ABCDEF";
long unsigned unum;
int i=0,j,k;
if(radix==10&&num<0)
{
unum = (unsigned) -num;
str[i++] = '-';
}
else
unum = (unsigned)num;
do
{
str[i++] = index[unum%(unsigned)radix];
unum/=radix;
}while(unum);
//printf("str = %s\n",str);
str[i] = '\0';
if(str[0]=='-')
{
k = 1;
}
else
k = 0;
for(j = k;j<=(i-1)/2;j++)
{
char temp;
temp = str[j];
str[j] = str[i-1+k-j];
str[i-1+k-j] = temp;
}
//printf("str = %s\n",str);
return str;
}
/******************************************************
生成command 的chksum函数
*******************************************************/
char *creatChksum(char *Commandinfo,char* chkstr)
{
int temp = 0;
int chksum = 0;
for(int i=1;i<