我已经学习了大约 2 周的 C 语言,并决定尝试使用简单的端口扫描器。我可以毫无错误地编译代码,但每当我尝试执行它时,我都会遇到段错误。
#include<stdio.h>
#include<sys/socket.h>
#include<errno.h>
#include<netdb.h>
#include<string.h>
#include<stdlib.h>
int scanPort(char hostaddr[], int port) {
struct hostent *host;
int err, i, sock;
struct sockaddr_in sa;
strncpy((char*)&sa , "" , sizeof sa);
sa.sin_family = AF_INET;
if (isdigit(hostaddr[0])) {
sa.sin_addr.s_addr = inet_addr(hostaddr);
} else if ((host = gethostbyname(hostaddr)) != 0) {
strncpy((char*)&sa.sin_addr , (char*)host->h_addr , sizeof sa.sin_addr);
} else {
printf("\n[!] Failed to resolve host!\n");
exit(1);
}
sa.sin_port = htons(port);
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
printf("\n[!] Failed to create socket!\n");
exit(1);
}
err = connect(sock, (struct sockaddr*)&sa , sizeof sa);
close(sock);
if (err < 0) {
return 0;
} else {
return 1;
}
}
int main(int argc, char *argv[]) {
if (argc != 4) {
printf("usage: ./portscan [TARGET] [START PORT] [STOP PORT]\n");
exit(0);
}
char host[20];
strcpy(host, argv[1]);
int beginport;
int endport;
if (isdigit(argv[2]) && isdigit(argv[3])) {
beginport = atoi(argv[2]);
endport = atoi(argv[3]);
} else {
printf("[!] Invalid port range given\n");
}
printf("[*] Beginning Scan...\n\n");
int i = beginport;
for (i; i<=endport; i++) {
if (scanPort(host, i)) {
printf("Port %d: Open\n", i);
}
}
printf("\n[*] Scan complete!");
return 0;
}
我知道代码中有一些不正确/不安全的函数使用,但我只是想让这个程序正常运行。这只是一个测试,不是实际使用的程序。
更新 2:我添加了几行来评估 argc
感谢您的宝贵时间。
-默认
最佳答案
崩溃发生在这里:
if (isdigit(argv[2]) && isdigit(argv[3])) {
isdigit
函数需要一个 int
(实际上是一个 char
转换为一个 int
),但是你通过在 char *
中。这会调用未定义的行为,在这种情况下(幸运的是)表现为崩溃。
您可能想检查每个字符串的第一个字符,因此将 argv[2][0]
和 argv[3][0]
传递给此函数.
此外,这是不正确的:
strncpy((char*)&sa.sin_addr , (char*)host->h_addr , sizeof sa.sin_addr);
strncpy
函数用于复制字符串,而不是任意字节。如果正在复制的字节中有一个空字节,则不会复制该字节之后的其他字节。请改用 memcpy
,它会复制精确的字节数:
memcpy((char*)&sa.sin_addr , (char*)host->h_addr , sizeof sa.sin_addr);
关于c - 给出了段错误,为什么? (C),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42798316/