【问题标题】:Multithreading a password checker in CC中的多线程密码检查器
【发布时间】:2013-09-29 01:11:51
【问题描述】:

目前正在尝试使用pthread_createpthread_joinpthread_exitpthread_self 使该程序使用多线程。然后我打算在我的代码中使用crypt_r 代替crypt

它最多只能有 8 个线程,但我什至不知道如何开始使用两个。我只有一行声明pthread_t t1,t2,t3,t4,t5,t6,t7,t8

计划将它们放入pthread_create,但除了初始化这些值之外,我不知道从哪里开始。

我知道 pthread_create 的输入类似于pthread_create(t1, NULL, ... , ...),但我不知道如何进行第三个输入或者第四个输入是什么。 然后,我必须确保根据命令行 arg 指定的线程数拆分每个线程正在检查的字母范围。到目前为止,我已将其设计为仅在一个线程上工作,并计划通过多线程将其移至 crypt_r...

我真的很困惑如何才能完成这项工作。如果可能的话。

我知道某种 void 函数是 pthread_create.. 的第三个条目,但该函数必须是我的 passwordChecker 吗?还是什么?

/*
crack.exe
*/
/*  g++ -o crack crack.c -lcrypt -lpthread */
//#define _GNU_SOURCE
#include <crypt.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#include <string.h>
#include <math.h>

void *passwordLooper(int ks, char target[9], char s[10]);
void *threadFunction(void *threads);

int main(int argc, char *argv[]){           /* usage = crack threads keysize target */
    int i = 0;
    /*  arg[0] = crack, arg[1] = #of threads arg[2] = size of password, arg[3] = hashed password being cracked */

    if (argc !=  4) {
        fprintf(stderr, "Too few/many arguements give.\n");
        fprintf(stderr, "Proper usage: ./crack threads keysize target\n");
        exit(0);
    }

    int threads = *argv[1]-'0';         // threads is now equal to the second command line argument number
    int keysize = *argv[2]-'0';         // keysize is now equal to the third command line argument number
    char target[9]; 
    strcpy(target, argv[3]);
    char salt[10];

    while ( i < 2 ){            //Takes first two characters of the hashed password and assigns them to the salt variable
        salt[i] = target[i];
        i++;
    }


    printf("threads = %d\n", threads);      /*used for testing */
    printf("keysize = %d\n", keysize);
    printf("target = %s\n", target);        
    printf("salt = %s\n", salt);        


    if (threads < 1 || threads > 8){
        fprintf(stderr, "0 < threads <= 8\n");
        exit(0);
    }                                               /*Checks to be sure that threads and keysize are*/
    if (keysize < 1 || keysize > 8){                                                /*of the correct size   */
        fprintf(stderr, "0 < keysize <= 8\n");
        exit(0);
    }

    pthread_t t1,t2,t3,t4,t5,t6,t7,t8;

    if ( threads = 1 ){
        pthread_create(&t1, NULL, *threadFunction, threads);
    }


    char unSalted[30];
    int j = 0;
    for (i = 2; target[i] != '\0'; i++){        /*generates variable from target that does not include salt*/
        unSalted[j] = target[i];
        j++;
    }
    printf("unSalted = %s\n", unSalted); //unSalted is the variable target without the first two characters (the salt)

    char password[9] = {0};
    passwordLooper(keysize, target, salt);


}




/*_____________________________________________________________________________________________________________*/
/*_____________________________________________________________________________________________________________*/
void *passwordLooper(int ks, char target[9], char s[10]){
    char password[9] = {0};
    struct crypt_data cd;   
    cd.initialized = 0;
    int result;

    for (;;){
        int level = 0; 
        while (level < ks && strcmp( crypt(password, s), target ) != 0) {
            if (password[level] == 0){
                password[level] = 'a';
                break;
            }
            if (password[level] >= 'a' && password[level] < 'z'){
                password[level]++;
                break;
            }
            if (password[level] == 'z'){
                password[level] = 'a';
                level++;
            }
        }

        char *cryptPW = crypt(password, s);
        result = strcmp(cryptPW, target);

        if (result == 0){               //if result is zero, cryptPW and target are the same
            printf("result = %d\n", result);
            printf ("Password found: %s\n", password);
            printf("Hashed version of password is %s\n", cryptPW);
            break;  
        }
        if (level >= ks){           //if level ends up bigger than the keysize, break, no longer checking for passwords
            printf("Password not found\n");
            break;
        }



    }
    return 0;
}

使用 malloc 结构

/*
crack.exe
By: Zach Corse
*/
/*  g++ -o crack crack.c -lcrypt -lpthread */
//#define _GNU_SOURCE
#include <crypt.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#include <string.h>
#include <math.h>
#include <malloc.h>


void *passwordLooper(void *passwordData);
//void *threadFunction(void *threads);
typedef struct{
    int keysize;
    char *target;
    char *salt;
}passwordData;

int main(int argc, char *argv[]){           /* usage = crack threads keysize target */
    int i = 0;
    /*  arg[0] = crack, arg[1] = #of threads arg[2] = size of password, arg[3] = hashed password being cracked */

    if (argc !=  4) {
        fprintf(stderr, "Too few/many arguements give.\n");
        fprintf(stderr, "Proper usage: ./crack threads keysize target\n");
        exit(0);
    }

    int threads = *argv[1]-'0';         // threads is now equal to the second command line argument number
    int keysize = *argv[2]-'0';         // keysize is now equal to the third command line argument number
    char target[9]; 
    strcpy(target, argv[3]);
    char salt[10];

    while ( i < 2 ){            //Takes first two characters of the hashed password and assigns them to the salt variable
        salt[i] = target[i];
        i++;
    }


    printf("threads = %d\n", threads);      /*used for testing */
    printf("keysize = %d\n", keysize);
    printf("target = %s\n", target);        
    printf("salt = %s\n", salt);        


    if (threads < 1 || threads > 8){
        fprintf(stderr, "0 < threads <= 8\n");
        exit(0);
    }                                               /*Checks to be sure that threads and keysize are*/
    if (keysize < 1 || keysize > 8){                                                /*of the correct size   */
        fprintf(stderr, "0 < keysize <= 8\n");
        exit(0);
    }

    pthread_t t1,t2,t3,t4,t5,t6,t7,t8;

    struct crypt_data data;
    data.initialized = 0;
    //~ passwordData.keysize = keysize;
    //~ passwordData.target = target;
    //~ passwordData.salt = salt;

    passwordData *pwd = (passwordData *) malloc(sizeof(pwd));
    pwd->keysize = keysize;
    pwd->target = target;
    pwd->salt = salt;


    //~ if ( threads = 1 ){
        //~ pthread_create(&t1, NULL, *threadFunction, threads);
    //~ }


    char unSalted[30];
    int j = 0;
    for (i = 2; target[i] != '\0'; i++){        /*generates variable from target that does not include salt*/
        unSalted[j] = target[i];
        j++;
    }
    printf("unSalted = %s\n", unSalted); //unSalted is the variable target without the first two characters (the salt)

    char password[9] = {0};
    passwordLooper(pwd);


}




/*_____________________________________________________________________________________________________________*/
/*_____________________________________________________________________________________________________________*/
void *passwordLooper(passwordData pwd){
    char password[9] = {0};
    int result;

    int ks = pwd.keysize;
    char *target = pwd.target;
    char *s = pwd.salt;

    for (;;){
        int level = 0; 
        while (level < ks && strcmp( crypt(password, s), target ) != 0) {
            if (password[level] == 0){
                password[level] = 'a';
                break;
            }
            if (password[level] >= 'a' && password[level] < 'z'){
                password[level]++;
                break;
            }
            if (password[level] == 'z'){
                password[level] = 'a';
                level++;
            }
        }

        char *cryptPW = crypt(password, s);
        result = strcmp(cryptPW, target);

        if (result == 0){               //if result is zero, cryptPW and target are the same
            printf("result = %d\n", result);
            printf ("Password found: %s\n", password);
            printf("Hashed version of password is %s\n", cryptPW);
            break;  
        }
        if (level >= ks){           //if level ends up bigger than the keysize, break, no longer checking for passwords
            printf("Password not found\n");
            break;
        }
    }
    return 0;
}

【问题讨论】:

    标签: c multithreading pthreads pthread-join


    【解决方案1】:

    嗯,这是 pthread_create 的原型:

    int pthread_create(pthread_t *restrict thread, const pthread_attr_t *restrict attr, void *(*start_routine)(void *), void *restrict arg);

    它表明第三个参数是一个指向函数的指针,该函数返回一个指向 void 的指针,并将指向 void 的指针作为其唯一参数。我看到你有一个原型:

    void *threadFunction(void *threads);

    符合这些规范,但实际上并未编写? pthread_create 中的第 4 个参数只是一个指向 void 的指针,它基本上可以包含您想要的任何内容。

    我猜你想线程化的函数实际上是passwordLooper,它需要3个参数。但是pthread_create指定的函数只需要1个。你必须找到一个解决方法,这样你就只能接受一个参数您的 passwordLooper 函数仍然传递您关心的所有 3 个变量。有几种方法可以做到这一点:

    1. 全局变量(糟糕,不是线程安全的,不要真的这样做)
    2. malloc() 一些内存,memcpy() 将您的参数放入其中(或指向它们的指针),然后将新的 malloc() 内存传递给 pthread_create()。在您调用的函数中,您必须将 3 个变量从 void * 中解析出来(hacky,但理论上可行)
    3. 定义一个包含 3 个参数的结构,分配该结构的副本,将变量复制到新分配的结构中,并将其作为第四个参数传递。这大大简化了对值的解析,并且是完成将多个变量作为 pthread_create 的第四个参数传递的一般方法

    【讨论】:

    • 糟糕!并不是要把threadFunction 留在那儿。知道那一定是错的。是的,我想线程passwordLooper。我相信我的教授提出了类似于#3 的建议。我只是不知道该怎么做。
    • 你做过结构体吗?我假设如果你正在做线程......所以它只是一个引用传递,就像你对其他类型所做的那样。结构神秘 *a; -> a = malloc(sizeof(struct mystuff)); -> pthread_create(x, y z, (void *)a);而在你的被调用函数中则相反
    • 我可能有,但我不记得了。这是我学习 C 的第一个学期。只使用过 C++ 和几种不同的语言。做了一些搜索,我想我发现了如何做到这一点。现在我得到的唯一错误是/usr/bin/ld: cannot find -lmalloc collect2: error: ld returned 1 exit status有什么想法吗?我觉得我已经很接近这个了,减去实际工作的拆分和告诉哪个线程做什么,哈哈。
    • 这只是一个链接器错误,告诉您它找不到 libmalloc.so,请尝试从您的 makefile 或 IDE 配置中的链接器参数中删除 -lmalloc .. 如果您在 linux 上,malloc 是libc 的一部分,不需要单独链接。
    • 我目前正在使用g++ -o crack crack.c -lcrypt -lpthread,但仍然遇到同样的错误。我尝试在其中放入 -lmalloc 并尝试摆脱 #include &lt;malloc.h&gt; 但这些都不起作用。当我尝试在命令行中输入-lmalloc 和其他所有内容时,它会显示cannot find -lmalloc
    猜你喜欢
    • 1970-01-01
    • 2014-11-08
    • 2017-02-24
    • 1970-01-01
    • 2017-06-03
    • 1970-01-01
    • 1970-01-01
    • 2015-08-05
    • 1970-01-01
    相关资源
    最近更新 更多