Currently attempting to get this program to use multithreading using pthread_create, pthread_join, pthread_exit, and pthread_self. I then intend to use crypt_r in place of crypt in my code.

It will only be able to go up to 8 threads, but I don't even know how to get started with two. I just have one line that declares pthread_t t1,t2,t3,t4,t5,t6,t7,t8.

The plan with these is to put them in to pthread_create but besides initializing these values, I don't know where to go from here.

I know that pthread_create's input would be something like pthread_create(t1, NULL, ... , ...) but I do not know how to go about making the 3rd input or what the 4th input even is. I then have to make sure to split up the range of letters that each thread is checking based on the number of threads specified by a command line arg. I've designed this so far to work on one thread only, planning on moving it to crypt_r with multithreading...

Really confused as to how I could get to make this work.. If possible.

I know some sort of void function is the third entry in to pthread_create.. but does that function have to be what my passwordChecker is? Or what?

/*
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;
}

With malloc'd structs

/*
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;
}
有帮助吗?

解决方案

Well, here's the prototype for pthread_create:

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

It shows that the 3rd arg is a pointer to a function that returns a pointer to void and takes a pointer to void as its sole argument. I see you have a prototype for:

void *threadFunction(void *threads);

which meets those specifications, but it's not actually written? The 4th argument in pthread_create is just a pointer to void, which can essentially contain anything you want it to.

I'm guessing that the function you want to thread is actually passwordLooper, which takes 3 arguments.. but pthread_create specifies a function that takes only 1. You have to find a workaround so that you can only accept a single argument to your passwordLooper function yet still pass all 3 variables that you care about. There are a few ways this can be done:

  1. Global variables (yuck, not thread safe, don't really do this)
  2. malloc() some memory, memcpy() your arguments into it (or pointers to them), and pass that newly malloc()ed memory to pthread_create(). In your called function you'll have to parse the 3 variables back out of the void * (hacky, but works in theory)
  3. Define a struct that contains your 3 arguments, malloc a copy of that struct, copy your variables into the newly malloced struct, and pass it as your 4th argument. This greatly simplifies parsing the values back out and is the general way to accomplish passing multiple variables as pthread_create's 4th argument
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top