【问题标题】:stack smashing detected..while sending ICMP packet检测到堆栈粉碎..在发送 ICMP 数据包时
【发布时间】:2013-03-09 08:41:54
【问题描述】:

我编写了一个C 程序来发送一个ICMP 数据包。这是对应的代码..

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <netdb.h>

int Seq_Num = 1;
struct icmp_header
{
unsigned char type;
unsigned char code;
unsigned short check_sum;
unsigned short id;
unsigned short seq_num;
 char msg[20];
   };

void make_icmp( struct icmp_header *I, char *msg_to_snd, int m_len )
{
I->type = 13;   //for timestamp 
I->code = 0;    // request..
I->id   = htons(713);   //some unique ID..
I->seq_num= htons(Seq_Num);
Seq_Num++;
/*computing the check sum..*/
unsigned int Sum = 0;
memset(I->msg, 0, 100);
unsigned short *ptr = (unsigned short*)I;
Sum += *ptr++;
ptr++;
Sum += *ptr++;
Sum += *ptr++;
strcpy(I->msg, msg_to_snd);

ptr = ( unsigned short*)I->msg;

int len = m_len;
if(len & 1)
    len++;

while(len >=0)
{
    Sum += *ptr++;  
    len -=2;
}   

Sum = (Sum >>16) + Sum& 0x0000ffff; /*add the carries..*/

Sum += (Sum>>16);   /*add the newly generated carries..*/

I->check_sum = ~Sum;    
}

int main(int argc, char* argv[])
{
if(argc ==1)
{
    perror("ip addr. required..\n");
    exit(1);
}


    int sock = socket(AF_INET, SOCK_RAW, 1);

    if(sock==-1)
    {
        perror("sock():");
        exit(1);
    }

    struct sockaddr_in Sk;
    bzero(&Sk, sizeof(Sk));
    Sk.sin_family = AF_INET;
    inet_pton(AF_INET, argv[1], &Sk.sin_addr);
    struct icmp_header Q;


        char buf[20];
        scanf("%s", buf);
        make_icmp(&Q, buf, strlen(buf));    

        if(sendto( sock, &Q, sizeof(Q), 0, (struct sockaddr*)&Sk, sizeof(Sk))<0)
        {
            perror("sendto..");
            exit(1);
        } 
        sleep(1);
    printf("sent successfully\n");


return 0;
}

代码的问题是当我运行它时,icmp 数据包已成功发送,我可以在wire shark 中看到。但最后在显示sent successfully 后我得到以下错误..

*** stack smashing detected ***: ./a.out terminated

请告诉我我错过了什么......谢谢。

【问题讨论】:

  • 你在哪里看到icmp_header *I这样的命名约定?

标签: c icmp stack-smash


【解决方案1】:

I-&gt;msg 的大小只是20,但您设置的超出了它的容量:

memset(I->msg, 0, 100); // 100 > 20 and it exceeds the array boundaries 

【讨论】:

  • 那么为什么它不显示在该指令本身?怎么执行成功了?
  • 这是未定义的行为,有时运行正常,有时崩溃。
  • 也许 stack smasing 检查仅在函数退出时运行 - 在每条指令后检查会非常昂贵。如果您可以在 valgrind 下运行它,它可能会确认确切的行。
  • @Useless 那么为什么不在make_icmp 函数调用之后呢?为什么在main() 函数调用之后?
  • 被破坏的特定堆栈帧不是 make_icmp 的,即使该函数造成了损害。 Q 是您写到末尾的对象,它位于 main 的堆栈帧上。因此,如果make_icmp 在退出时检查自己的堆栈帧,它不会看到任何损坏。当main 对其框架执行相同的检查时,它意识到make_icmp 粉碎了它。注意。这是所有(堆栈框架布局、运行时堆栈粉碎检查等)非常平台特定的。未定义的行为是您得到保证的全部。
猜你喜欢
  • 2012-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-12
  • 2015-12-21
相关资源
最近更新 更多