我在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;
}
这里的问题是我可以正确编译但是我遇到了Segmentation错误。我看不出我错在哪里。我想这是关于处理缓冲区或堆栈溢出的事情。
所以我在这个函数中所做的就是获取argv并将其发送到arguments_handle函数。 这样做的是查看参数“-p”和“-h”以及“存储”在char数组中的正确顺序。 喜欢这个char: “指向包含字符数组的数组的char指针”
pointer pointer pointer
pointer to this-> ["firstarg","secondarg","etc"]
在这种情况下,“指针指针指针”将是字符串的第一个字符。
总结:我想创建一个字符串数组,并将其从arguments_handle返回到main函数。
有什么想法吗? :)
此致
INT3
答案 0 :(得分:1)
问题是您没有为从命令行获取的字符串分配正确的内存空间。
char* ret[2]= {"NULL","NULL"};
这将创建一个包含两个大小为4 +结束字符('\ 0')的字符串的数组。这是你想要的吗?或者你想创建两个NULL
指针。
如果输入字符串的大小大于4会发生什么?您可能会访问错误的内存,从而导致分段错误。此外,您不应使用strcpy
或strcmp
,而应使用strncpy
和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;
}
答案 1 :(得分:1)
我解决了这个问题!
非常感谢Giuseppe Pes! 我不习惯malloc和memset等东西。 但这解决了这个问题。我知道它试图把数据放在不应该的地方:D
这是我的最终代码:
#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.
//well i didnt edit strcpy and strcmp to strncpy yet but I will :D
char* ret[2]; //GLOBAL ofc.
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)
{
//tested on windows we need to put a cast before malloc
//in linux it works fine on my raspberrypi !! :D
ret[0] = (char*)malloc(20); //some compilers maybe will throw here an error
ret[1] = (char*)malloc(20); //because malloc returns a void pointer and ret is a char*
memset(ret[0],0,20);
memset(ret[1],0,20);
char** ipnport;
ipnport = arguments_handle(argc,argv);
printf("IP is :%s port range is %s\n",ipnport[1],ipnport[0]);
//the rest of the code about port scan goes here. I'm just cutting
return 0x0;
}
再次感谢,我希望此代码可以帮助其他人看到这篇文章:)
此致
INT3