-1

UDPを使用してある種のVoIPアプリケーションを実行しようとしています。安全のためにRSAアルゴリズムを追加しましたが、その結果とセグメンテーション違反が発生します。

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <stdio.h>
#include <linux/soundcard.h>
#include <stdlib.h>
#define LENGTH 3    /* how many seconds of speech to store */
#define RATE 8000   /* the sampling rate */
#define FILE_INPUT "/dev/dsp" /* Path to the sound card. */
#define FILE_OUTPUT "/dev/dsp"


/*-RSA-*/
//Her is gcd function
int gcd(int a,int b)
{
    while(a!=b){

        if(a>b)
            a-=b;
        else
            b-=a;
    }
    return a;
}


//This is called  Extended Euclid’s Algorithm to find d.

int findD(int e,int n)
{

    int f=e;
    int d=n;

    int x1, x2, x3, y1, y2, y3;
    x1 = 1; x2 = 0; x3 = f; //p
    y1 = 0; y2 = 1; y3 = d; //d



    int q = 0, i = 1;
    int t1 = 0, t2 = 0, t3 = 0;
    do
    {
        if (i == 1)
        {
            q = x3 / y3;
            t1 = x1 - (q * y1);
            t2 = x2 - (q * y2);
            t3 = x3 - (q * y3);
        }
        else
        {
            x1 = y1; x2 = y2; x3 = y3;
            y1 = t1; y2 = t2; y3 = t3;
            q = x3 / y3;
            t1 = x1 - (q * y1);
            t2 = x2 - (q * y2);
            t3 = x3 - (q * y3);
        }
        i++;


        if (y3 == 0)
        {
            break;
        }

    } while (y3 != 1);

    if (y3 == 0)
    {
        //printf("Sayinin tersi yoktur!!!!");
    }
    else
    {
        // printf("\nSayinin tersi : %d" , y2);
    }

    if(y2<=0)
    {

        y2=e+y2;

    }
    return y2;

}

//Instead of using pow function,I have choose to write square and multiply method which is faster and
//more suitable for big integers.Because we have no such a change to find 104^30 such like that
//Here computes pow(a,b)%n
int squareMul(int a,int b,int n)
{

    int y = 1;

    /*  Compute pow(a, b) % n using the binary square and multiply method. */
    while (b != 0)
    {
        /*  For each 1 in b, accumulate y. */
        if (b & 1)
        {
            y = (y * a) % n;
        }

        /* Square a for each bit in b. */
        a = (a * a) % n;

        /*  Prepare for the next bit in b. */
        b = b >> 1;
    }

    return y;

}
//Encyrption function
//Assume our plain-text is M
int *encyrpt(int text[],int e,int n)
{

    int t=0;
    int *s=(int *)malloc(100);

    for(t=0;t<sizeof(text);t++)
    {
        int gec=(int)text[t];

        //Here computes E(M)=M^e mod n;
        s[t]=squareMul(gec,e,n);

    }


    return s;


}

//Here is decyrption
//Assume our chipher-text is C
int *decyrpt(int enc[],int d,int e,int n)
{
    int i=0;
    int *s=(int *)malloc(100);

    for(i=0;i<sizeof(enc);i++)
    {
        int gelenEnc=(int)enc[i];
        //Here computes D(C)=C^d mod n;
        s[i]=squareMul(gelenEnc,d,n);


    }
    return s;

}



//Here is totient function to find prime to  m.
int totient(int m)
{

    int i;
    int ph=1;
    for(i=2;i<m;i++){

        if(gcd(i,m)==1)
        {
            ph=i;
            break;

        }
    }
    return ph;

}
/*-RSA-*/


int main()
{
    int sock,bytes_recv;
    struct sockaddr_in server_addr;
    struct hostent *host;
    char send_data[LENGTH*RATE];
    char recv_data[LENGTH*RATE];
    int addr_len, bytes_read;
    struct client_addr;


    /* this buffer holds the digitized audio */
    unsigned char buf[LENGTH*RATE];

    /*----------RSA-----------------------*/    

    //Here are some variables that I used for RSA ALGORİTHM
    //str is our plain-text
    char *plainText;
    int *ascii;
    int *enc;
    int *dec;
    int p,q;
    int k=0;
    int n;
    int e;
    int c;
    int phi;
    int d;

    plainText="Merhaba";

    //Here enter 2 relatively prime number
    //I have chose the p=73 and q=151

    p=73;
    q=151;

    printf("\n\ p :%d and q :%d \t \n",p,q);
    //Here computes n
    n = p*q;
    //Here computes phi func simply
    phi=(p-1)*(q-1);

    printf("\n\ n :\t= %d \n",n);
    printf("\n\ Phi :\t= %d \n",phi);

    //Here Euilers Totient function.It finds a number 'e' which is relatively prime with phi.
    e=totient(phi);
    //Here computes d,which is multiplicative inverse of e modula phi.
    d=findD(phi,e);

    printf("\n\ e :\t= %d  \n",e);

    printf("\n\ d :\t= %d which is multiplicative inverse of e modula phi \n",d);


    //Here is the ascii values for plainText.I have created new array in order to store plainText's ascii for simplicty
    ascii=(int *)malloc(sizeof(int)*sizeof(plainText)/sizeof(char));


/*---------------RSA------------*/


    int sound_device;

    /* open sound device */
    //I defined sound card both read and write mode for simplicity
    sound_device = open("/dev/dsp", O_RDWR);
    if (sound_device < 0) {
        perror("Open sound card failed");
        exit(1);
    }


    host= (struct hostent *) gethostbyname((char *)"127.0.0.1");


    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
    {
        perror("socket");
        exit(1);
    }

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(5000);
    server_addr.sin_addr = *((struct in_addr *)host->h_addr);
    bzero(&(server_addr.sin_zero),8);


    while(1){

        read(sound_device, buf, sizeof(buf)); /* record some sound */

          printf("\n Size of buff: %d",sizeof(buf));
          ascii=malloc(LENGTH*RATE);
          buf=malloc(LENGTH*RATE);

                  printf("\n Size of ascii: %d",sizeof(ascii));

          //Here ascii stores plaintText's ascii number.
        for(c=0;c<LENGTH*RATE;c++)
        {

        int k=(int)buf[c];

        ascii[c]=k;
        printf("\n\t Ascii's of %c  \t= %d  \n",buf[c],ascii[c]);
            printf("\n\t C: %c  \t= %d  \n",c);
        }

         enc=encyrpt(ascii,e,n);


        //Send function to server
        sendto(sock, enc, LENGTH*RATE, 0,(struct sockaddr *)&server_addr, sizeof(struct sockaddr));

        //Listen from server for 3 seconds
        ioctl(sound_device, SOUND_PCM_SYNC, 0);
        bytes_recv = recvfrom(sock,buf,LENGTH*RATE,0,(struct sockaddr *)&server_addr, &addr_len);

        printf("\n Sended:");
        if(bytes_recv==LENGTH*RATE){

            printf("\nMessage received from server,listen:");
            //Here is decyription
            dec=decyrpt(buf,d,e,n);
            write(sound_device, dec, sizeof(dec));


            ioctl(sound_device, SOUND_PCM_SYNC, 0);
            }
    }

}


 Ascii's of �   = 131  

 C: �   = 10989  

セグメンテーション違反

ただし、私のRSAアルゴリズムは、他のchar配列で個別に正しく機能します。ありがとう

4

2 に答える 2

2

As people in the comments have pointed out, you should be using a debugger to find out where the segmentation fault is happening exactly.

However, a cursory analysis (which is something a developer should always do, before digging out debuggers) shows a number of pointers that are being used without care.

Any time you make a call to malloc, you should be confirming that it was successful. If it wasn't and you try to use the pointer that you malloced to, you can get a segfault.

You also assign a string to an unmalloced pointer (plainText)... BOOM: segfaults, ahoy!

A bunch of your functions do unchecked mallocs as well.

So, there are a few places you should look.

于 2012-06-06T15:17:47.217 に答える
2

通常、セグメンテーション違反は、プロセスに割り当てられていないメモリにアクセスしようとした場合に発生します。これは、配列 (特に動的に作成されたもの) にインデックスを付けているときによく発生します。

malloc()コードでは、関数encypt()と関数に固定サイズdecrypt()がありますが、入力配列のサイズに基づいてその要素にアクセスするため、seg.fault の原因になる可能性があります。

確かに、デバッガーを使用して、オーバー/アンダー インデックス作成が発生する場所を確認する必要があります。他の配列へのアクセスも確認してください(動的に割り当てられているかどうか)

また、sizeof(plainText)文字列の長さではなく、文字へのポインタのサイズを返します。plaintextスタックベースの配列として宣言するか、strlen()関数を使用する必要があります。

于 2012-06-06T15:20:16.657 に答える