Exemplo n.º 1
0
int Track::is_synthesis(int64_t position, 
	int direction)
{
	int is_synthesis = 0;
	for(int i = 0; i < plugin_set.total; i++)
	{
		Plugin *plugin = get_current_plugin(position,
			i,
			direction,
			0,
			0);
		if(plugin)
		{
// Assume data from a shared track is synthesized
			if(plugin->plugin_type == PLUGIN_SHAREDMODULE) 
				is_synthesis = 1;
			else
				is_synthesis = plugin->is_synthesis(position, 
					direction);

//printf("Track::is_synthesis %d %d\n", __LINE__, is_synthesis);
			if(is_synthesis) break;
		}
	}
	return is_synthesis;
}
Exemplo n.º 2
0
int Track::plugin_used(int64_t position, int64_t direction)
{
//printf("Track::plugin_used 1 %d\n", this->plugin_set.total);
	for(int i = 0; i < this->plugin_set.total; i++)
	{
		Plugin *current_plugin = get_current_plugin(position, 
			i, 
			direction, 
			0,
			0);

//printf("Track::plugin_used 2 %p %d %d\n", current_plugin, current_plugin->on, current_plugin->plugin_type);
		if(current_plugin && 
			current_plugin->on && 
			current_plugin->plugin_type != PLUGIN_NONE)
		{
			return 1;
		}
	}
//printf("Track::plugin_used 3 %p\n", current_plugin);
	return 0;
}
Exemplo n.º 3
0
/* Load plugin */
hash_stat load_plugin(void)
{
    char soname[1024];

    snprintf(soname,1024,"%s/hashkill/plugins/%s.so", DATADIR, get_current_plugin());
    dlhandle=dlopen(soname,RTLD_LAZY);
    if (dlhandle)
    {
        *(hash_stat **) (&hash_plugin_parse_hash) = dlsym(dlhandle, "hash_plugin_parse_hash");
        *(hash_stat **) (&hash_plugin_check_hash) = dlsym(dlhandle, "hash_plugin_check_hash");
        *(hash_stat **) (&hash_plugin_check_hash_dictionary) = dlsym(dlhandle, "hash_plugin_check_hash_dictionary");
        /* no special dictionary function? */
        if (hash_plugin_check_hash_dictionary==NULL)
        {
    	    *(hash_stat **) (&hash_plugin_check_hash_dictionary) = dlsym(dlhandle, "hash_plugin_check_hash");
        }

        *(int **) (&hash_plugin_hash_length) = dlsym(dlhandle, "hash_plugin_hash_length");
        *(int **) (&hash_plugin_is_raw) = dlsym(dlhandle, "hash_plugin_is_raw");
        *(int **) (&hash_plugin_is_special) = dlsym(dlhandle, "hash_plugin_is_special");
        *(void **) (&get_vector_size) = dlsym(dlhandle, "get_vector_size");
        *(int **) (&get_salt_size) = dlsym(dlhandle, "get_salt_size");
	
	if ( (!hash_plugin_parse_hash) || (!hash_plugin_check_hash) || (!hash_plugin_hash_length) || (!get_vector_size) || (!get_salt_size))
	{
	    if (!detecting) elog("Plugin %s does not export all the necessary functions!\n", get_current_plugin());
	    return hash_err;
	}
	salt_size = get_salt_size();

	/* import register functions */
	void(*register_add_username)(void (*add_username)(const char *username)) = dlsym(dlhandle, "register_add_username");
	void(*register_add_hash)(void (*add_hash)(const char *hash, int len)) = dlsym(dlhandle, "register_add_hash");
	void(*register_add_salt)(void (*add_salt)(const char *salt)) = dlsym(dlhandle, "register_add_salt");
	void(*register_add_salt2)(void (*add_salt2)(const char *salt2)) = dlsym(dlhandle, "register_add_salt2");
	void(*register_md5)(hash_stat  (*md5)(char *plaintext[VECTORSIZE], char *hash[VECTORSIZE], int len, int threadid)) = dlsym(dlhandle, "register_md5");
	void(*register_md5_unicode)(void (*md5_unicode)(char *plaintext[VECTORSIZE], char *hash[VECTORSIZE], int len[VECTORSIZE])) = dlsym(dlhandle, "register_md5_unicode");
	void(*register_md5_unicode_slow)(void (*md5_unicode_slow)(char *plaintext[VECTORSIZE], char *hash[VECTORSIZE], int len[VECTORSIZE])) = dlsym(dlhandle, "register_md5_unicode_slow");
	void(*register_md5_slow)(void (*md5_slow)(char *plaintext[VECTORSIZE], char *hash[VECTORSIZE], int len, int threadid)) = dlsym(dlhandle, "register_md5_slow");
	void(*register_md4)(hash_stat (*md4)(char *plaintext[VECTORSIZE], char *hash[VECTORSIZE], int len[VECTORSIZE],int threadid)) = dlsym(dlhandle, "register_md4");
	void(*register_md4_unicode)(hash_stat (*md4)(char *plaintext[VECTORSIZE], char *hash[VECTORSIZE], int len,int threadid)) = dlsym(dlhandle, "register_md4_unicode");
	void(*register_md4_slow)(void (*md4_slow)(char *plaintext[VECTORSIZE], char *hash[VECTORSIZE], int len[VECTORSIZE],int threadid)) = dlsym(dlhandle, "register_md4_slow");
	void(*register_md5_hex)(void (*md5_hex)(const char *hash[VECTORSIZE], char *hashhex[VECTORSIZE])) = dlsym(dlhandle, "register_md5_hex");
	void(*register_sha1)(hash_stat (*md5)(char *plaintext[VECTORSIZE], char *hash[VECTORSIZE], int len, int threadid)) = dlsym(dlhandle, "register_sha1");
	void(*register_sha1_unicode)(void (*sha1_unicode)(char *plaintext[VECTORSIZE], char *hash[VECTORSIZE], int len[VECTORSIZE])) = dlsym(dlhandle, "register_sha1_unicode");
	void(*register_sha1_slow)(void (*sha1_slow)(char *plaintext[VECTORSIZE], char *hash[VECTORSIZE], int len[VECTORSIZE])) = dlsym(dlhandle, "register_sha1_slow");
	void(*register_sha1_hex)(void (*md5_hex)(const char *hash[VECTORSIZE], char *hashhex[VECTORSIZE])) = dlsym(dlhandle, "register_sha1_hex");
	void(*register_sha256_unicode)(void (*sha256_unicode)(const char *plaintext[VECTORSIZE], char *hash[VECTORSIZE], int len[VECTORSIZE])) = dlsym(dlhandle, "register_sha256_unicode");
	void(*register_sha256_hex)(void (*sha256_hex)(const char *hash[VECTORSIZE], char *hashhex[VECTORSIZE])) = dlsym(dlhandle, "register_sha256_hex");
	void(*register_sha512_unicode)(void (*sha512_unicode)(const char *plaintext[VECTORSIZE], char *hash[VECTORSIZE], int len[VECTORSIZE])) = dlsym(dlhandle, "register_sha512_unicode");
	void(*register_sha384_unicode)(void (*sha384_unicode)(const char *plaintext[VECTORSIZE], char *hash[VECTORSIZE], int len[VECTORSIZE])) = dlsym(dlhandle, "register_sha384_unicode");
	void(*register_sha512_hex)(void (*sha512_hex)(const char *hash[VECTORSIZE], char *hashhex[VECTORSIZE])) = dlsym(dlhandle, "register_sha512_hex");
	void(*register_fcrypt)(hash_stat (*fcrypt)(const char *password[VECTORSIZE], const char *salt, char *ret[VECTORSIZE])) = dlsym(dlhandle, "register_fcrypt");
	void(*register_fcrypt_slow)(hash_stat (*fcrypt_slow)(const char *password[VECTORSIZE], const char *salt, char *ret[VECTORSIZE])) = dlsym(dlhandle, "register_fcrypt_slow");
	void(*register_PEM_readfile)(void (*PEM_readfile)(const char *passphrase, int *RSAret)) = dlsym(dlhandle, "register_PEM_readfile");
	void(*register_new_biomem)(void (*new_biomem)(FILE *file)) = dlsym(dlhandle, "register_new_biomem");
	void(*register_pbkdf2)(void (*pbkdf2)(const char *pass, unsigned char *salt, int saltlen, int iter, int keylen, unsigned char *out)) = dlsym(dlhandle, "register_pbkdf2");
	void(*register_pbkdf2_len)(void (*pbkdf2_len)(const char *pass, int passlen, unsigned char *salt, int saltlen, int iter, int keylen, unsigned char *out)) = dlsym(dlhandle, "register_pbkdf2_len");
	void(*register_pbkdf2_256_len)(void (*pbkdf2_256_len)(const char *pass, int passlen, unsigned char *salt, int saltlen, int iter, int keylen, unsigned char *out)) = dlsym(dlhandle, "register_pbkdf2_256_len");
	void(*register_hmac_sha1_file)(void (*hmac_sha1_file)(void *key, int keylen, char *filename, long offset, long size, unsigned char *output, int outputlen)) = dlsym(dlhandle, "register_hmac_sha1_file");
	void(*register_hmac_sha1)(void (*hmac_sha1)(void *key, int keylen, unsigned char *data, int datalen,unsigned char *output, int outputlen)) = dlsym(dlhandle, "register_hmac_sha1");
	void(*register_hmac_md5)(void (*hmac_md5)(void *key, int keylen, unsigned char *data, int datalen, unsigned char *output, int outputlen)) = dlsym(dlhandle, "register_hmac_md5");
	void(*register_ripemd160)(void (*ripemd160)(const char *plaintext[VECTORSIZE], char *hash[VECTORSIZE], int len[VECTORSIZE])) = dlsym(dlhandle, "register_ripemd160");
	void(*register_whirlpool)(void (*whirlpool)(const char *plaintext[VECTORSIZE], char *hash[VECTORSIZE], int len[VECTORSIZE])) = dlsym(dlhandle, "register_whirlpool");
	void(*register_pbkdf512)(void (*pbkdf512)(const char *pass, int len, unsigned char *salt, int saltlen, int iter, int keylen, unsigned char *out)) = dlsym(dlhandle, "register_pbkdf512");
	void(*register_pbkdfrmd160)(void (*pbkdfrmd160)(const char *pass, int len, unsigned char *salt, int saltlen, int iter, int keylen, unsigned char *out)) = dlsym(dlhandle, "register_pbkdfrmd160");
	void(*register_pbkdfwhirlpool)(void (*pbkdfwhirlpool)(const char *pass, int len, unsigned char *salt, int saltlen, int iter, int keylen, unsigned char *out)) = dlsym(dlhandle, "register_pbkdfwhirlpool");
	void(*register_aes_encrypt)(void (*aes_encrypt)(const unsigned char *key, int keysize, const unsigned char *in, int len, unsigned char *vec, unsigned char *out, int mode)) = dlsym(dlhandle, "register_aes_encrypt");
	void(*register_aes_decrypt)(void (*aes_decrypt)(const unsigned char *key, int keysize, const unsigned char *in, int len, unsigned char *vec, unsigned char *out, int mode)) = dlsym(dlhandle, "register_aes_decrypt");
	void(*register_des_ecb_encrypt)(void (*des_ecb_encrypt)(const unsigned char *key, int keysize, const unsigned char *in[VECTORSIZE], int len, unsigned char *out[VECTORSIZE], int mode)) = dlsym(dlhandle, "register_des_ecb_encrypt");
	void(*register_des_ecb_decrypt)(void (*des_ecbdecrypt)(const unsigned char *key, int keysize, const unsigned char *in, int len, unsigned char *out, int mode)) = dlsym(dlhandle, "register_des_ecb_decrypt");
	void(*register_des_cbc_encrypt)(void (*des_ecb_encrypt)(const unsigned char *key[VECTORSIZE], int keysize, const unsigned char *in[VECTORSIZE], int len[VECTORSIZE], unsigned char *out[VECTORSIZE], unsigned char *iv[VECTORSIZE], int mode)) = dlsym(dlhandle, "register_des_cbc_encrypt");
	void(*register_rc4_encrypt)(void (*des_rc4_encrypt)(const unsigned char *key, int keysize, const unsigned char *in, int len, unsigned char *out)) = dlsym(dlhandle, "register_rc4_encrypt");
	void(*register_lm)(void (*lm)(const unsigned char *in[VECTORSIZE], unsigned char *out[VECTORSIZE])) = dlsym(dlhandle, "register_lm");
	void(*register_lm_slow)(void (*lm_slow)(const unsigned char *in[VECTORSIZE], unsigned char *out[VECTORSIZE])) = dlsym(dlhandle, "register_lm_slow");
	void(*register_aes_cbc_encrypt)(void (*aes_cbc_encrypt)(const unsigned char *in,unsigned char *out,unsigned long length,AES_KEY *key,unsigned char ivec[16],int oper)) = dlsym(dlhandle, "register_aes_cbc_encrypt");
	void(*register_aes_set_encrypt_key)(int (*aes_set_encrypt_key)(const unsigned char *userKey,const int bits,AES_KEY *key)) = dlsym(dlhandle, "register_aes_set_encrypt_key");
	void(*register_aes_set_decrypt_key)(int (*aes_set_decrypt_key)(const unsigned char *userKey,const int bits,AES_KEY *key)) = dlsym(dlhandle, "register_aes_set_decrypt_key");
	void(*register_decrypt_aes_xts)(void (*decrypt_aes_xts)(char *key1, char *key2, char *in, char *out, int len, int sector, int cur_block)) = dlsym(dlhandle, "register_decrypt_aes_xts");
	void(*register_decrypt_twofish_xts)(void (*decrypt_twofish_xts)(char *key1, char *key2, char *in, char *out, int len, int sector, int cur_block)) = dlsym(dlhandle, "register_decrypt_twofish_xts");
	void(*register_decrypt_serpent_xts)(void (*decrypt_serpent_xts)(char *key1, char *key2, char *in, char *out, int len, int sector, int cur_block)) = dlsym(dlhandle, "register_decrypt_serpent_xts");



        if ((hash_plugin_parse_hash != NULL) && (hash_plugin_check_hash != NULL) && (hash_plugin_is_raw != NULL) && (hash_plugin_is_special != NULL))
        {
// register our callbacks
	    register_add_username(hash_proto_add_username);
	    register_add_hash(hash_proto_add_hash);
	    register_add_salt(hash_proto_add_salt);
	    register_add_salt2(hash_proto_add_salt2);
	    register_md5(hash_proto_md5);
	    register_md5_unicode(hash_proto_md5_unicode);
	    register_md5_unicode_slow(hash_proto_md5_unicode_slow);
	    register_md5_slow(hash_proto_md5_slow);
	    register_md4(hash_proto_md4);
	    register_md4_unicode(hash_proto_md4_unicode);
	    register_md4_slow(hash_proto_md4_slow);
	    register_md5_hex(hash_proto_md5_hex);
	    register_sha1(hash_proto_sha1);
	    register_sha1_unicode(hash_proto_sha1_unicode);
	    register_sha1_slow(hash_proto_sha1_slow);
	    register_sha1_hex(hash_proto_sha1_hex);
	    register_sha256_unicode(hash_proto_sha256_unicode);
	    register_sha256_hex(hash_proto_sha256_hex);
	    register_sha512_unicode(hash_proto_sha512_unicode);
	    register_sha384_unicode(hash_proto_sha384_unicode);
	    register_sha512_hex(hash_proto_sha512_hex);
	    register_fcrypt(hash_proto_fcrypt);
	    register_fcrypt_slow(hash_proto_fcrypt_slow);
	    register_new_biomem(hash_proto_new_biomem);
	    register_PEM_readfile(hash_proto_PEM_readfile);
	    register_pbkdf2(hash_proto_pbkdf2);
	    register_pbkdf2_len(hash_proto_pbkdf2_len);
	    register_pbkdf2_256_len(hash_proto_pbkdf2_256_len);
	    register_hmac_sha1_file(hash_proto_hmac_sha1_file);
	    register_hmac_sha1(hash_proto_hmac_sha1);
	    register_hmac_md5(hash_proto_hmac_md5);
	    register_ripemd160(hash_proto_ripemd160);
	    register_whirlpool(hash_proto_whirlpool);
	    register_pbkdf512(hash_proto_pbkdf512);
	    register_pbkdfrmd160(hash_proto_pbkdfrmd160);
	    register_pbkdfwhirlpool(hash_proto_pbkdfwhirlpool);
	    register_aes_encrypt(hash_proto_aes_encrypt);
	    register_aes_decrypt(hash_proto_aes_decrypt);
	    register_des_ecb_encrypt(hash_proto_des_ecb_encrypt);
	    register_des_ecb_decrypt(hash_proto_des_ecb_decrypt);
	    register_des_cbc_encrypt(hash_proto_des_cbc_encrypt);
	    register_rc4_encrypt(hash_proto_rc4_encrypt);
	    register_lm(hash_proto_lm);
	    register_lm_slow(hash_proto_lm_slow);
	    register_aes_cbc_encrypt(hash_proto_aes_cbc_encrypt);
	    register_aes_set_encrypt_key(hash_proto_aes_set_encrypt_key);
	    register_aes_set_decrypt_key(hash_proto_aes_set_decrypt_key);
	    register_decrypt_aes_xts(hash_proto_decrypt_aes_xts);
	    register_decrypt_twofish_xts(hash_proto_decrypt_twofish_xts);
	    register_decrypt_serpent_xts(hash_proto_decrypt_serpent_xts);

	    /* set vector size hackery */
	    if ( (strcmp(get_current_plugin(),"desunix")==0) || (strcmp(get_current_plugin(),"lm")==0) || (strcmp(get_current_plugin(),"oracle-old")==0)) 
	    {
		vectorsize = 128; 
		get_vector_size(128);
	    }
	    else if ( (strcmp(get_current_plugin(),"privkey")==0) || (strcmp(get_current_plugin(),"zip")==0) || (strcmp(get_current_plugin(),"wpa")==0) || (strcmp(get_current_plugin(),"rar")==0) || (strcmp(get_current_plugin(),"dmg")==0))
	    {
		vectorsize = 8;
		get_vector_size(8);
	    }
	    else if (strcmp(get_current_plugin(),"privkey")==0)
	    {
		vectorsize = 24;
		get_vector_size(24);
	    }
	    else 
	    {
		vectorsize = 12;
		get_vector_size(12);
	    }
	    
	    /* single-hash optimization for certain plugins */
	    cpu_optimize_single=0;
	    if ((strcmp(get_current_plugin(),"md5")==0) || (strcmp(get_current_plugin(),"sha1")==0) || (strcmp(get_current_plugin(),"md4")==0) || (strcmp(get_current_plugin(),"ntlm")==0) || (strcmp(get_current_plugin(),"desunix")==0) || (strcmp(get_current_plugin(),"md4")==0)) cpu_optimize_single=1;

	    /* is raw? */
	    hash_is_raw = hash_plugin_is_raw();
	    if (!detecting) hlog("Plugin \'%s\' loaded successfully\n",get_current_plugin());
	}
	else 
	{
	    if (!detecting) elog("Plugin \'%s\' could not be loaded\n",get_current_plugin());
	    dlclose(dlhandle);
	    return hash_err;
	}
    }
    else 
    {
	if (!detecting) elog("Cannot open plugin library: %s\n",soname);
	return hash_err;
    }
    return hash_ok;
}
Exemplo n.º 4
0
/* Program entrypoint */
int main(int argc, char *argv[])
{
    unsigned long tempqueuesize=0;
    char *fvalue = NULL;
    char *dvalue = NULL;
    int option,option_index;
    int pflag=0, bflag = 0, rflag=0;
    int cpu_thread_factor=0;
    int cnt;
    int hash_num_threads=0;
    struct option long_options[] = 
    {
	{"plugin-info", 2, 0, 'P'},
	{"plugin", 1, 0, 'p'},
	{"session-info", 2, 0, 'S'},
	{"session", 1, 0, 's'},
	{"hashlist", 1, 0, 'f'},
	{"brute", 2, 0, 'b'},
	{"outfile", 1, 0, 'o'},
	{"uncrackedfile", 1, 0, 'O'},
	{"markov-info", 0, 0, 'M'},
	{"markov", 1, 0, 'm'},
	{"markov-threshold", 1, 0, 'n'},
	{"markov-limit", 1, 0, 'N'},
	{"rule", 1, 0, 'r'},
	{"rule-print", 1, 0, 'R'},
	{"help", 0, 0, 'h'},
	{"cpu", 0, 0, 'c'},
	{"fast-markov",0,0,'F'},
	{"gpu-threads", 1, 0, 'G'},
	{"cpu-threads", 1, 0, 'C'},
	{"gpu-double", 0, 0, 'D'},
	{"gpu-temp", 0, 0, 'T'},
	{"gpu-platform", 0, 0, 't'},
	{"add-opts", 0, 0, 'a'},
	{"plugin-opts", 0, 0, 'A'},
	{0, 0, 0, 0}
    };


    /* initialize */
    printf("\n");
    hlog("Version %s\n", PACKAGE_VERSION);
    session_restore_flag = 0;
    hash_plugin_parse_hash = NULL;
    hash_plugin_check_hash = NULL;
    hash_list = NULL;
    cracked_list = NULL;
    attack_method = -1;
    markov_attack_init();
    attack_method = attack_method_markov;
    OpenSSL_add_all_algorithms();
    fast_markov = 0;
    cpuonly=0;
    hashgen_stdout_mode=0; 
    cnt=0;
    out_cracked_file=NULL;
    out_uncracked_file=NULL;
    markovstat = NULL;
    attack_checkpoints=0;
    attack_avgspeed=0;
    additional_options=malloc(1);
    additional_options[0]=0;
    padditional_options=malloc(1);
    padditional_options[0]=0;


    /* Detect CPU features and setup optimized routines */
    if (cpu_feat_setup() == hash_err)
    {
        elog("No x86 CPU found! %s\n","");
        exit(1);
    }

    while ((argv[cnt])&&(cnt<MAXARGV))
    {
	session_argv[cnt]=malloc(strlen(argv[cnt])+1);
	strcpy(session_argv[cnt],argv[cnt]);
	cnt++;
    }
    have_ocl=0;
    nwthreads=0;

    /* Init scheduler */
    scheduler_init();
    ocl_user_threads=0;
    ocl_gpu_double=0;
    ocl_gpu_tempthreshold=90;
    ocl_gpu_platform=100;
    interactive_mode=0;

    /* Set AMD OpenCL secret envvars */
    //setenv("GPU_MAX_ALLOC_PERCENT","100",1);
    //setenv("GPU_USE_SYNC_OBJECTS","1",1);
    // Bug in AMD Catalyst 13.4
    setenv("GPU_FLUSH_ON_EXECUTION","1",1);

    /* See if someone tried to pipe to stdin */
    detect_pipe();
    disable_term_linebuffer();

#ifndef HAVE_JSON_JSON_H
    wlog("This hashkill build has session save/restore support disabled. Please reconfigure with --with-json and rebuild\n%s","");
#endif

    /* now store the command line parameters to be used by sessions module */
    attack_over = 0;
    ctrl_c_pressed=0;
    session_put_commandline(argv);

    /* install SIGINT handler */
    signal(SIGINT, sigint_handler);
    signal(SIGTERM, sigint_handler);

    opterr = 0;
    while ((option = getopt_long(argc, argv, "p:f:d:P::b::t:T:S::s:o:O:N:n:M::m:hicFDG:C:a:T:r:RA:",long_options, &option_index)) != -1)
    switch (option)
    {
	case 'r':
	    if (optarg) 
	    {
		hlog("Rule based attack, using rule:%s\n",optarg);
		attack_method = attack_method_rule;
		rflag=1;
		rule_file=alloca(1024);
		strcpy(rule_file,optarg);
	    }
	    else
	    {
		usage(argv[0]);
		exit(EXIT_FAILURE);
	    }
    	    rflag = 1;
	    break;

	case 'R':
	    hashgen_stdout_mode=1;
	    break;


	case 'h':
	    usage(argv[0]);
	    exit(EXIT_SUCCESS);
	    break;
	case 'G':
	    ocl_user_threads = atoi(optarg);
	    if (ocl_user_threads>8) ocl_user_threads = 0;
	    break;
	case 'C':
	    cpu_thread_factor = atoi(optarg);
	    if ((cpu_thread_factor>256)||(cpu_thread_factor<1)) cpu_thread_factor=16;
	    break;

	case 's':
	    if (!optarg) {
		usage(argv[0]);
		exit(EXIT_FAILURE);
	    }
	    else {
		if (session_restore(optarg) == hash_err) exit(EXIT_FAILURE);
		pflag = 1;
	    }
	break;


	case 'P':
	    if (!optarg) (void)print_plugins_summary(DATADIR"/hashkill/plugins");
	    else print_plugin_detailed(optarg);
    	    exit(EXIT_SUCCESS);
	break;

	case 'a':
	    free(padditional_options);
	    padditional_options = malloc(strlen(optarg)+1);
	    strcpy(padditional_options,optarg);
	    process_addopts(optarg);
	break;

	case 'A':
	    free(additional_options);
	    additional_options = malloc(strlen(optarg)+1);
	    strcpy(additional_options,optarg);
	break;

	case 'c':
	    cpuonly = 1;
	break;

	case 'i':
	    hlog("interactive mode turned on!%s\n","");
	    interactive_mode = 1;
	break;

	case 'F':
	    fast_markov = 1;
	break;
	case 'T':
	    ocl_gpu_tempthreshold=atoi(optarg);
	break;
	case 'b':
	    if (optarg) 
	    {
		if (parse_bruteforce_args(optarg) == hash_err)
		{
		    exit(EXIT_FAILURE);
		}
	    }
	    else
	    {
		char *tempopt = NULL;
		tempopt = malloc(100);
		strcpy(tempopt,"1:8:lalphanum:");
		if (parse_bruteforce_args(tempopt) == hash_err)
		{
		    free(tempopt);
		    exit(EXIT_FAILURE);
		}
		free(tempopt);
		hlog("Using 1:8:lalpha defaults. Use -b<params> (no whitespaces) to specify them%s\n","");
	    }
    	    bflag = 1;
	    break;
	
	case 'm':
	    if (optarg) 
	    {
		if (markov_load_statfile(optarg) == hash_err)
		{
		    exit(EXIT_FAILURE);
		}
		else
		{
		    markovstat = malloc(64);
		    strcpy(markovstat,optarg);
		    attack_method = attack_method_markov;
		}
	    }
	    else
	    {
		usage(argv[0]);
		exit(EXIT_FAILURE);
	    }
	    break;


	case 'S':
	    if (!optarg) (void)print_sessions_summary();
	    else print_session_detailed(optarg);
	    exit(EXIT_SUCCESS);
	break;


	
	case 'p':
	    set_current_plugin(optarg);
            if (load_plugin()==hash_err)
	    {
    	        elog("Cannot load plugin (%s)\n",optarg);
    		exit(EXIT_FAILURE);
    	    }
	    pflag=1;
	break;

        case 'N':
	    markov_max_len = atoi(optarg);
	break;

        case 'D':
	    ocl_gpu_double = 1;
	    //setenv("GPU_MAX_HEAP_SIZE", "196", 1);
	    hlog("Using GPU double mode\n%s","");
	break;

        case 'n':
	    markov_threshold = atoi(optarg);
	break;

        case 't':
	    ocl_gpu_platform = atoi(optarg);
	break;

        
        case 'M':
	    markov_print_statfiles();
	    exit(EXIT_SUCCESS);
	break;
        
	case 'f':
	    fvalue = optarg;
	break;
        
	case 'd':
	    dvalue = optarg;
	break;

	case 'o':
	    out_cracked_file=malloc(strlen(optarg)+1);
	    strcpy(out_cracked_file,optarg);
	break;

	case 'O':
	    out_uncracked_file=malloc(strlen(optarg)+1);
	    strcpy(out_uncracked_file,optarg);
	break;


        case '?':
	    if ((optopt == 'f') || (optopt == 'P') || (optopt == 'd'))
	    {
		fprintf(stderr, "Option -%c requires an argument.\n", optopt);
    	    }
	
	default:
	break;
    }


    /* First check if out_cracked_file and out_uncracked_file are good */
    if (out_cracked_file)
    if (hash_err == check_out_file(out_cracked_file)) exit(1);
    if (out_uncracked_file)
    if (hash_err == check_out_file(out_uncracked_file)) exit(1);


    if (fvalue) 
    {
	strncpy(hashlist_file,fvalue,254);
	hashlist_file[254] = 0;
	if (pflag==0) 
	{
	    if (detect_plugin(DATADIR"/hashkill/plugins",hashlist_file,NULL) == hash_err)
	    {
    		elog("Cannot detect hash type%s\n","");
    		exit(EXIT_FAILURE);
	    }
	}
	(void)load_hashes_file(fvalue);
    }


    /* Do we have argument (hash)? */
    if (argv[optind]) 
    {
	if (pflag==0) 
	{
	    if (detect_plugin(DATADIR"/hashkill/plugins",NULL,argv[optind])==hash_err)
	    {
    		elog("Cannot detect hash type%s\n","");
    		exit(EXIT_FAILURE);
	    }
	}
	strncpy(hash_cmdline,argv[optind],HASHFILE_MAX_LINE_LENGTH);
	if (load_single_hash(hash_cmdline) == hash_err)
	{
	    if (!fvalue) 
	    {
		elog("Cannot load hash: %s\n",argv[optind]);
		exit(EXIT_FAILURE);
	    }
	}
    }


    if (strcmp(get_current_plugin(),"bitcoin")!=0)
    {

	/* Hashes num */
	hashes_count = get_hashes_num();

	/* Bruteforce? */
	if ((bflag)&&(!dvalue)&&(!rflag))
	{
	    fast_markov = 0; // do not mess with the charset in the opencl code
	    attack_method = attack_method_simple_bruteforce;
	}

    
	/* sl3 plugin is an exception: bruteforce only! */
	if (strcmp(get_current_plugin(),"sl3")==0)
	{
	    attack_method = attack_method_simple_bruteforce;
	}

	if ((attack_method != attack_method_simple_bruteforce) && ((attack_method != attack_method_markov)) && (attack_method != attack_method_rule))
	{
	    usage(argv[0]);
	    exit(EXIT_FAILURE);
	}
    
	/* threads sizing */
	if ((get_hashes_num() == 0)&&(hashgen_stdout_mode==0))
	{
	    elog("No hashes loaded!%s (try --help)\n","");
	    exit(EXIT_FAILURE);
	}
    
	if (cpu_thread_factor==0) 
	{
	    hash_num_threads = hash_num_cpu();
	}
	else hash_num_threads = cpu_thread_factor;
    }
    else attack_method = attack_method_simple_bruteforce;
    time1=time(NULL);

    /* CPU optimize single hacks */
    if (strcmp(get_current_plugin(),"md5")==0)
    {
	if ((attack_method==attack_method_simple_bruteforce)&&(bruteforce_end>7)) cpu_optimize_single=2;
	else if ((attack_method==attack_method_markov)&&(markov_max_len>7)) cpu_optimize_single=2;
    }
    if ((hash_list)&&(hash_list->next)) cpu_optimize_single=0;

    have_ocl = initialize_opencl();
    if ((have_ocl==hash_ok)&&(cpuonly==0)) have_ocl = ocl_get_device();

    if (cpuonly==1)
    {
	wlog("GPU acceleration available, but -c option was provided. Running on CPUs would likely be slower.\n%s","");
    }



    /* Markov? */
    if (attack_method == attack_method_markov) 
    {
	if (!markovstat) 
	{
	    markov_load_statfile("rockyou");
	    markovstat = malloc(64);
	    strcpy(markovstat,"rockyou");
	}

    	if ((cpuonly==0) && (have_ocl == hash_ok))
    	{
    	    if ((ocl_markov() != hash_ok) && (attack_over==0))
    	    {
    	    	if (tempqueuesize > HASHKILL_MAXQUEUESIZE) tempqueuesize = HASHKILL_MAXQUEUESIZE;
    		(void)main_thread_markov(hash_num_threads);
    	    }
    	}
	else main_thread_markov(hash_num_threads);
    }

    

    /* Rule-based */
    if (attack_method == attack_method_rule) 
    {
    	if (hash_err==rule_preprocess(rule_file)) {exit(1);}
    	if ((cpuonly==0) && (have_ocl == hash_ok))
    	{
    	    if ((ocl_rule() != hash_ok) && (attack_over==0))
    	    {
    	    	nwthreads = hash_num_threads;
    	    	if (tempqueuesize > HASHKILL_MAXQUEUESIZE) tempqueuesize = HASHKILL_MAXQUEUESIZE;
    		main_thread_rule(hash_num_threads);
    	    }
    	}
	else main_thread_rule(hash_num_threads);
    }


    /* Bruteforce? */
    if (attack_method == attack_method_simple_bruteforce) 
    {
	if (strcmp(get_current_plugin(),"bitcoin")!=0) hlog("Bruteforce charset (size=%d): %s\n",strlen(bruteforce_charset),bruteforce_charset);
	if ((have_ocl == hash_ok) && (cpuonly==0))
	{
	    if ( (ocl_bruteforce() != hash_ok) && (attack_over==0))
	    {
		if (tempqueuesize > HASHKILL_MAXQUEUESIZE) tempqueuesize = HASHKILL_MAXQUEUESIZE;
		(void)main_thread_bruteforce(hash_num_threads);
	    }
	}
	else main_thread_bruteforce(hash_num_threads);
    }


    /* We delete session file ONLY when attack is over */
    if (ctrl_c_pressed==0)
    {
        session_unlink_file();
	if (have_ocl==hash_ok) session_unlink_file_ocl();
    }
    

    if (get_cracked_num() > 0) print_cracked_list();    

    if (out_cracked_file)
    {
        print_cracked_list_to_file(out_cracked_file);
    }
    
    if ((hash_plugin_is_special)&&(hash_plugin_is_special()==0))
    {
    
	if (out_uncracked_file)
	{
	    print_uncracked_list_to_file(out_uncracked_file);
	}
    }

    time2=time(NULL);
    printf("\n");
    hlog("Attack took %u seconds.\n",(unsigned int)(time2-time1));

    hlog("Bye bye :)\n\n%s","");
//    thread_attack_cleanup();
//    cleanup_lists();

    return 0;
}