2011-12-18 2 views
2

Я занимаюсь физическими упражнениями. Цель состоит в том, чтобы сделать программу на C, чтобы взломать зашифрованный пароль DES. Прямо сейчас у меня есть следующий исполнитель:Ошибка шины pthread

  1. Загрузить словарь.
  2. Поиск по словарю.
  3. Грубая сила поиска первых 4 символов.
  4. Словарь поиска в сочетании с грубой силой (для поиска комбинаций). Только словарные слова из 7-6 символов.
  5. Грубая сила поиска первых 5 символов.
  6. Словарь поиска в сочетании с грубой силой (для поиска комбинаций). Только словарные слова 5-4 символов.
  7. Поиск грубой силы до 8 символов.

Программа работает нормально, но я хочу, чтобы улучшить его за счет использования нескольких резьб: 1-й нити - главный второй нитки - словарь и словарь в сочетании с грубой силой поиска 3-й нитки - поиск грубой силы

Я начал с создания основной функции поиска словарных словарей, но с ошибкой шины (Mac OS X), где он должен начинать читать слова из файла словаря. Тот же код работает отлично в обычной не- функции нить ...

Вот код:

#include <pthread.h> 
#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 

#define _XOPEN_SOURCE 
#define MAXLINE 40 
#define MAXPASS 9 

/* dictionary search thread function */ 
void * dictionary(void * argv) 
{ 
    /* initializing SALT */ 
    char salt[3];    // defining salt (length is always 2 chars + "\0") 
    strncpy(salt, argv, 2);  // copying the first 2 characters from encrypted password to salt 
    salt[2] = '\0';    // placing null character to make salt a string 

    /* defining and initializing password */ 
    char password[14]; 
    strcpy(password, argv); 
    /* defining candidate */ 
    char candidate[MAXPASS]; 

    /* opening file */ 
    FILE *fp; 
    if ((fp = fopen("/usr/share/dict/words", "r")) == NULL) 
    { 
     printf("Error: Can not open file.\n"); 
     return (void *) -1; 
    } 
    printf("Open file: Ok\n"); 
    char line[MAXLINE]; 
    printf("Counting words: "); 
    /* counting words the file contains */ 
    int ctr = 0; // words counter variable 
    int len;  // store length of the current line 
    while (fgets(line, MAXLINE, fp) != NULL && line[0] != '\n') 
    { 
     if ((len = strlen(line)) <= MAXPASS && len >= 4) 
      ctr++; // will be real+1 when the loop ends 
    } 
    ctr--;   // adjusting to real words count 
    rewind(fp);  // go back to the beginning of file 
    printf("%d words\n", ctr); 

    /* create an array of strings and fill it with the words from the dictionary */ 
    printf("Creating array for file contents: "); 
    char words[ctr][MAXPASS]; 
    int i = 0;  // loop counter variable 
    printf("Ok\n"); 
    /************************************* BUS ERROR *********************************************/ 
    printf("Reading file contents: "); 
    while (fgets(line, MAXLINE, fp) != NULL && line[0] != '\n') 
    { 
     if ((len = strlen(line)) <= MAXPASS && len >= 4) 
     { 
      line[len-1] = '\0'; 
      strcpy(words[i], line); 
      printf("%d: %s\n", i, words[i]); 
      i++; 
     } 
    } 
    printf("Ok\n"); 
    printf("Loaded %d words...\n", ctr); 

    /* closing file */ 
    printf("Close file: "); 
    if (fclose(fp) != 0) 
    { 
     fprintf(stderr, "Error: Can not close file\n"); 
     return (void *) -2; 
    } 
    printf("Ok\n"); 

    /* starting search dictionary search */ 
    printf("Starting Dictionary Search...\n"); 
    int match = 0; 
    char * encrypted; 
    int n; 
    for (i = 0; i <= ctr && !match; i++) 
    { 
     encrypted = crypt(words[i], salt); 
     if ((strcmp(encrypted, password)) == 0)    // if candidate == password 
     { 
      match = 1; 
      strcpy(candidate, words[i]); 
      printf("Password: %s\n", candidate); 
      return (void *) 1; 
     } 
    } 

    return (void *) 0; 
} 
int main(int argc, char * argv[]) 
{ 
    /* if there are less/more than 1 argument, notify the user and exit with an error code 1 */ 
    if (argc != 2)  // first argument is always the name of the program 
    { 
     printf("Error 1: Wrong number of arguments\n");    
     return 1; 
    } 
    /* if the length of the argument is less/more than 13 characters, notify the user and exit with an error code 2 */ 
    int length = strlen(argv[1]); 
    if (length != 13) 
    { 
     printf("Error 2: The length of an encrypted password should be 13 characters\n"); 
     return 2; 
    } 

    pthread_t dct;  // dictionary thread identifier 
    void *status;  // thread return value 

    /* creating dictionary thread */ 
    pthread_create(&dct,NULL,dictionary,argv[1]); 

    printf("Waiting for thread to terminate...\n"); 
    pthread_join(dct,&status); 

    //printf("Return Value: %d\n",(int)status); 

    return 0; 
} 
+0

Пожалуйста, вставьте свой код здесь, а не на другой сайт. http://stackoverflow.com/ - это хранилище высококачественных вопросов и ответов; что происходит, когда ваш хост кода закрывает свои двери или истекает старые сообщения? Это станет (более) бесполезным и не поможет другим в будущем. Благодаря! – sarnold

+0

Гораздо лучше, спасибо @ Коди. – sarnold

+0

Извините за размещение кода на pastebin, но я новичок в stackoverflow и возникли проблемы с форматированием кода ... – user903673

ответ

2

Я собираюсь догадаться, что это ваша проблема:

char words[ctr][MAXPASS]; 

Когда вы используете однопоточную программу, у вас есть много адресного пространства для стека, чтобы расти, библиотеки и исполняемое пространство программы выросли и куча посередине.

Но когда вы работаете с многопоточными программами, каждый поток получает свой собственный стек, и я не удивлюсь, если пространство стека, доступное для потоков, значительно меньше размера словаря. (См. Справочную страницу pthread_attr_getstack() в вашей системе для получения подробных сведений о размере стека по потокам по умолчанию.)

Выделите этот массив с помощью malloc(3) и посмотрите, будет ли ваша программа дальше.

char *words; 
words = malloc(ctr * sizeof(char)); 
int i; // loop counter variable 
for (i = ; i < ctr; i++) 
    words[i] = malloc(MAXPASS * sizeof(char)); 

Если вы обнаружили множественные malloc(3) вызов ввести достаточно фрагментацию памяти, вы можете использовать некоторую слегка грубую отливку, чтобы выделить один большой блок памяти и обращаться с ней одинаково многомерным массивом:

$ cat multidimensional.c 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define NWORDS 1000 
#define WORDLEN 10 

void fun(char words[NWORDS][WORDLEN]) { 
    int i, j; 
    for (i=0; i<NWORDS; i++) { 
     strcpy(words[i], "test"); 
    } 

    for (i=0; i<NWORDS; i++) { 
     printf("%s\n", words[i]); 
    } 
    return; 
} 


int main(int argc, char* argv[]) { 
    char *w = malloc(NWORDS * WORDLEN * sizeof(char)); 
    memset(w, 0, NWORDS * WORDLEN * sizeof(char)); 
    fun((char (*)[WORDLEN]) w); 

    return 0; 
} 

вы должны были бы использовать другую функцию, потому что вы не можете назначить на массив, но когда вы пишете функцию, которая должна быть передана массив в качестве аргумента фактически распадается на указатель, переданный в вызове функции: char (*)[WORDLEN]. (Возможно, это было написано: void fun(char (*)[WORDLEN]), но я не думаю, что это так отчетливо.)

Я всегда немного волнуюсь, когда я замолчу предупреждение с актером, как я это сделал, но это делает одно большое выделение вместо тысяч небольших крошечных распределений, что может иметь огромную разницу в производительности. (Проверьте оба и посмотрите.)

+0

Я знаю, как выделить 2d массив int, однако у меня возникают проблемы с символами. Я пытаюсь сделать это так, но все равно не получается: char * words [ctr]; \t int i; \t для (i = 0; i user903673

+0

Спасибо. Сделал это и работает :) char ** words; \t words = malloc (ctr * sizeof (char *)); \t int i; \t \t // счетчик цикла переменной \t для (я = 0; я user903673

Смежные вопросы