0

編集: 解決策はおそらくページの下部にあります。私は解決策で私の質問に答えました。これが他の人に役立つことを願っています。

ここLinuxで少し問題があります。単純なポート スキャンをプログラミングしていますが、引数を取る関数に問題があります。

コードで説明します:

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

//this function handle the arguments.

char* ret[2]= {"NULL","NULL"}; //declaring this in global because of segmention fault?

char** arguments_handle(int argc,char **arg)
{
    if(argc!=5)
    {
        printf("Usage:./file -p PORT-RAGE -h HOST.IP\n");
        exit(1);
    }
    //make sure the user type the correct arguments. in this case just -h and -p
    if(strcmp(arg[1],"-p")==0 || strcmp(arg[1],"-h")==0 && strcmp(arg[3],"-p")==0 || strcmp(arg[3],"-h")==0)
    {
        //if in the arguments we got -h or -p run this
        //if is -p
        if(strcmp(arg[1],"-p")==0)
        {
            //take the next argument in this case is the port range and put in our array
            strcpy(ret[0],arg[2]);
        }
        else
        {
            strcpy(ret[1],arg[2]);
        }
        if(strcmp(arg[3],"-h")==0)
        {
            //now for the -h
            strcpy(ret[1],arg[4]);
        }
        else
        {
            strcpy(ret[0],arg[4]);
        }
    }
    return ret;
}
int main(int argc, char **argv)
{
    char** ipnport;
    ipnport = arguments_handle(argc,argv);
    printf("IP is :%s port range is %s\n",ipnport[0],ipnport[1]);
    //the rest of the code about port scan goes here. I'm just cutting
    return 0x0;
}

ここでの問題は、正しくコンパイルできますが、セグメンテーション違反が発生することです。どこが間違っているのかわかりません。バッファやスタックのオーバーフローに対処するためのものだと思います。

したがって、この関数でここで行っていることは、argv を取得して、arguments_handle 関数に送信することです。それが行うことは、引数 "-p" と "-h" と "store" が char の配列の正しい順序でどこにあるかを確認することです。この char のように: 「char の配列を含むこの配列への char ポインター」

                    pointer     pointer    pointer
pointer to this-> ["firstarg","secondarg","etc"]

その場合、「ポインター ポインター ポインター」は文字列の最初の文字になります。

要約: 文字列配列を作成し、arguments_handle から main の関数に返したいと考えています。

何か案は?:)

心から、

int3

4

2 に答える 2

1

問題は、コマンド ラインから取得する文字列に正しいメモリ空間を割り当てていないことです。

char* ret[2]= {"NULL","NULL"};

これにより、サイズ 4 + 終了文字 ('\0') の 2 つの文字列を含む配列が作成されます。これはあなたが望んでいたものですか?または、2 つのNULLポインターを作成します。入力文字列のサイズが 4 より大きい場合はどうなりますか? セグメンテーション違反の原因となる間違ったメモリにアクセスする可能性があります。また、 strcpyor strcmpbut strncpyandは使用しないでくださいstrncmp

コードは次のように変更する必要があります。

    char * ret[2];

    if(strncmp(arg[3],"-h", 3)==0)
    {   
        string_size = strlen(arg[4]) + 1; 
        ret[1]= malloc(sting_size); 
        memset(ret[1], 0, string_size); 
        strncpy(ret[1],arg[4], string_size);
        // or ret[1]=arg[4] as suggested by Roland
    }

ただし、関数getoptがこれを行うため、入力パラメーター用のパーサーを作成する必要はありません。これは、最後に良い例を含むマニュアルです: http://man7.org/linux/man-pages/man3/getopt.3.html

コードの簡単な例:

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>

#define NUMBER_ARGUMENTS 2 
#define IP 1
#define PORT 0

char* ret[NUMBER_ARGUMENTS];  

int main(int argc, char **argv)
{
    int opt; 

    while ((opt = getopt(argc, argv, "p:h:")) != -1) {
               switch (opt) {
               case 'p':
                    ret[PORT]=optarg; 
                   break;
               case 'h':
                    ret[IP]=optarg; 
                   break;
               default: /* '?' */
                   fprintf(stderr, "Usage: %s -p PORT -h HOST\n",
                           argv[0]);
                   exit(EXIT_FAILURE);
               }
    } 
    printf("IP is :%s port range is %s\n",ret[IP],ret[PORT]);
    //the rest of the code about port scan goes here. I'm just cutting
    return 0x0;
}
于 2013-11-04T23:08:18.810 に答える