Example #1
0
hash_stat session_write_rule_parm(char *rulename, uint64_t current, uint64_t overall, FILE *sessionfile)
{
#ifdef HAVE_JSON_JSON_H

    json_object *jobj;
    char ltemp[32];

    if (get_cracked_num()==get_hashes_num()) return(hash_ok);

    attack_header_node = json_object_new_object();
    jobj = json_object_new_string(rulename);
    json_object_object_add(attack_header_node,"rulefile", jobj);
    sprintf(ltemp,"%llu",current);
    jobj = json_object_new_string(ltemp);
    json_object_object_add(attack_header_node,"currentelem", jobj);
    sprintf(ltemp,"%llu",overall);
    jobj = json_object_new_string(ltemp);
    json_object_object_add(attack_header_node,"overall", jobj);
    sprintf(ltemp,"%llu",attack_overall_count);
    jobj = json_object_new_string(ltemp);
    json_object_object_add(attack_header_node,"overallcount", jobj);
    sprintf(ltemp,"%llu",attack_current_count);
    jobj = json_object_new_string(ltemp);
    json_object_object_add(attack_header_node,"currentcount", jobj);

    json_object_object_add(root_node,"rule", attack_header_node);
    return hash_ok;
#endif

}
Example #2
0
/* write Markov attack parameters to session file */
hash_stat session_write_markov_parm(char *statfile, int threshold, int len, uint64_t count, uint64_t current_elem, char *current_str, FILE *sessionfile)
{
#ifdef HAVE_JSON_JSON_H

    json_object *jobj;
    char ltemp[32];

    if (get_cracked_num()==get_hashes_num()) return(hash_ok);

    attack_header_node = json_object_new_object();
    jobj = json_object_new_string(statfile);
    json_object_object_add(attack_header_node,"statfile", jobj);
    jobj = json_object_new_int(threshold);
    json_object_object_add(attack_header_node,"threshold", jobj);
    jobj = json_object_new_int(len);
    json_object_object_add(attack_header_node,"maxlen", jobj);
    sprintf(ltemp,"%llu",count);
    jobj = json_object_new_string(ltemp);
    json_object_object_add(attack_header_node,"maxcount", jobj);
    sprintf(ltemp,"%llu",current_elem);
    jobj = json_object_new_string(ltemp);
    json_object_object_add(attack_header_node,"currentelem", jobj);
    jobj = json_object_new_string(current_str);
    json_object_object_add(attack_header_node,"currentstr", jobj);
    sprintf(ltemp,"%llu",attack_overall_count);
    jobj = json_object_new_string(ltemp);
    json_object_object_add(attack_header_node,"overallcount", jobj);
    sprintf(ltemp,"%llu",attack_current_count);
    jobj = json_object_new_string(ltemp);
    json_object_object_add(attack_header_node,"currentcount", jobj);
    json_object_object_add(root_node,"markov", attack_header_node);
    return hash_ok;
#endif
}
Example #3
0
/* write bruteforce attack parameters to session file */
hash_stat session_write_bruteforce_parm(int start, int end, char *prefix, char *suffix, char *charset, int curlen, char *curstr, uint64_t progress, FILE *sessionfile)
{
#ifdef HAVE_JSON_JSON_H

    json_object *jobj;
    char ltemp[32];

    if (get_cracked_num()==get_hashes_num()) return(hash_ok);

    attack_header_node = json_object_new_object();
    jobj = json_object_new_int(start);
    json_object_object_add(attack_header_node,"start", jobj);
    jobj = json_object_new_int(end);
    json_object_object_add(attack_header_node,"end", jobj);
    jobj = json_object_new_string(charset);
    json_object_object_add(attack_header_node,"charset", jobj);
    jobj = json_object_new_int(curlen);
    json_object_object_add(attack_header_node,"currentlen", jobj);
    jobj = json_object_new_string(curstr);
    json_object_object_add(attack_header_node,"currentstr", jobj);
    sprintf(ltemp,"%llu",progress);
    jobj = json_object_new_string(ltemp);
    json_object_object_add(attack_header_node,"currentelem", jobj);
    sprintf(ltemp,"%llu",attack_overall_count);
    jobj = json_object_new_string(ltemp);
    json_object_object_add(attack_header_node,"overallcount", jobj);
    sprintf(ltemp,"%llu",attack_current_count);
    jobj = json_object_new_string(ltemp);
    json_object_object_add(attack_header_node,"currentcount", jobj);
    json_object_object_add(root_node,"bruteforce", attack_header_node);
#endif
    return hash_ok;
}
Example #4
0
/* Put general attack parameters to session file */
hash_stat session_write_parameters(char *plugin, attack_method_t attacktype, uint64_t progress, FILE *sessionfile)
{
#ifdef HAVE_JSON_JSON_H
    time_t myclock;
    json_object *jobj;
    char buf[4096];
    int cnt;
    char *space=" ";
    struct tm *lotime;

    if (get_cracked_num()==get_hashes_num()) return(hash_ok);
    main_header_node = json_object_new_object();
    cnt=0;
    bzero(buf,4096);
    while ((session_argv[cnt])&&(cnt<MAXARGV-1)) 
    {
	strcat(buf,session_argv[cnt]);
	strcat(buf,space);
	cnt++;
    }

    jobj = json_object_new_string(buf);
    json_object_object_add(main_header_node,"commandline", jobj);
    jobj = json_object_new_string(plugin);
    json_object_object_add(main_header_node,"plugin", jobj);
    jobj = json_object_new_string(additional_options);
    json_object_object_add(main_header_node,"addopts", jobj);
    jobj = json_object_new_string(padditional_options);
    json_object_object_add(main_header_node,"paddopts", jobj);
    jobj = json_object_new_int((int)progress);
    json_object_object_add(main_header_node,"progress", jobj);
    jobj = json_object_new_int(attack_method);
    json_object_object_add(main_header_node,"attacktype", jobj);
    jobj = json_object_new_int(ocl_gpu_platform);
    json_object_object_add(main_header_node,"gpuplatform", jobj);
    jobj = json_object_new_int(hash_crack_speed);
    json_object_object_add(main_header_node,"attackspeed", jobj);
    myclock=time(NULL);
    if (myclock == ((time_t) -1)) return hash_err;
    lotime = localtime(&myclock);
    if (!lotime) return hash_err;
    jobj = json_object_new_string(asctime(lotime));
    json_object_object_add(main_header_node,"timestamp", jobj);
    jobj = json_object_new_string(getcwd((char *)&buf, 4095));
    json_object_object_add(main_header_node,"workdir", jobj);
    jobj = json_object_new_int(hash_ret_len);
    json_object_object_add(main_header_node,"hashlen", jobj);
    jobj = json_object_new_string(hashlist_file);
    json_object_object_add(main_header_node,"hashlistfile", jobj);
    if (out_cracked_file) jobj = json_object_new_string(out_cracked_file);
    else jobj = json_object_new_string("");
    json_object_object_add(main_header_node,"outcrackedfile", jobj);
    if (out_uncracked_file) jobj = json_object_new_string(out_uncracked_file);
    jobj = json_object_new_string("");
    json_object_object_add(main_header_node,"outuncrackedfile", jobj);
    json_object_object_add(root_node,"main", main_header_node);
    session_write_scheduler_parameters();
#endif
    return hash_ok;
}
Example #5
0
/* Write hash list to session file */
hash_stat session_write_hashlist(FILE *sessionfile)
{
#ifdef HAVE_JSON_JSON_H

    json_object *jobj;
    json_object *jchild;
    struct hash_list_s *mylist;
    char buff[1024];

    if (get_cracked_num()==get_hashes_num()) return(hash_ok);
    if (get_hashes_num()>100000) 
    {
	hash_list_node = json_object_new_array();
	json_object_object_add(root_node,"hashlist", hash_list_node);
	return(hash_ok);
    }

    hash_list_node = json_object_new_array();
    pthread_mutex_lock(&listmutex);
    mylist = hash_list;
    while ((mylist)&&(mylist->username))
    {
	jchild = json_object_new_object();
	jobj = json_object_new_string(mylist->username);
	json_object_object_add(jchild,"username", jobj);
	str2hex(mylist->hash, buff, hash_ret_len);
	jobj = json_object_new_string(buff);
	json_object_object_add(jchild,"hash", jobj);
	jobj = json_object_new_string(mylist->salt);
	json_object_object_add(jchild,"salt", jobj);
	jobj = json_object_new_string(mylist->salt);
	json_object_object_add(jchild,"salt", jobj);
	jobj = json_object_new_string(mylist->salt2);
	json_object_object_add(jchild,"salt2", jobj);
	json_object_array_add(hash_list_node,jchild);
	mylist = mylist->next;
    }
    pthread_mutex_unlock(&listmutex);
    json_object_object_add(root_node,"hashlist", hash_list_node);
#endif
    return hash_ok;
}
Example #6
0
hash_stat session_write_scheduler_parameters()
{
#ifdef HAVE_JSON_JSON_H

    json_object *jobj;
    json_object *jobjarr, *jobjarr1;
    json_object *jobj1;
    int a,b;

    if (get_cracked_num()==get_hashes_num()) return(hash_ok);
    scheduler_node = json_object_new_object();

    /* startlen */
    jobj = json_object_new_int(scheduler.startlen);
    json_object_object_add(scheduler_node,"startlen", jobj);
    /* len */
    jobj = json_object_new_int(scheduler.len);
    json_object_object_add(scheduler_node,"len", jobj);
    /* maxlen */
    jobj = json_object_new_int(scheduler.maxlen);
    json_object_object_add(scheduler_node,"maxlen", jobj);
    /* charset_size */
    jobj = json_object_new_int(scheduler.charset_size);
    json_object_object_add(scheduler_node,"charset_size", jobj);
    /* charset_size2 */
    jobj = json_object_new_int(scheduler.charset_size2);
    json_object_object_add(scheduler_node,"charset_size2", jobj);
    /* markov_l1 */
    jobj = json_object_new_int(scheduler.markov_l1);
    json_object_object_add(scheduler_node,"markov_l1", jobj);
    /* markov_l2_1 */
    jobj = json_object_new_int(scheduler.markov_l2_1);
    json_object_object_add(scheduler_node,"markov_l2_1", jobj);
    /* markov_l2_2 */
    jobj = json_object_new_int(scheduler.markov_l2_2);
    json_object_object_add(scheduler_node,"markov_l2_2", jobj);
    /* markov_l3_1 */
    jobj = json_object_new_int(scheduler.markov_l3_1);
    json_object_object_add(scheduler_node,"markov_l3_1", jobj);
    /* markov_l3_2 */
    jobj = json_object_new_int(scheduler.markov_l3_2);
    json_object_object_add(scheduler_node,"markov_l3_2", jobj);
    /* markov_l3_3 */
    jobj = json_object_new_int(scheduler.markov_l3_3);
    json_object_object_add(scheduler_node,"markov_l3_3", jobj);
    /* currentqueued */
    jobj = json_object_new_int(scheduler.currentqueued); // for accuracy
    json_object_object_add(scheduler_node,"currentqueued", jobj);
    /* currentrule */
    jobj = json_object_new_int(scheduler.currentrule);
    json_object_object_add(scheduler_node,"currentrule", jobj);
    /* bitmap1 */
    jobj = json_object_new_int(scheduler.bitmap1);
    json_object_object_add(scheduler_node,"bitmap1", jobj);
    /* ebitmap1 */
    jobj = json_object_new_int(scheduler.ebitmap1);
    json_object_object_add(scheduler_node,"ebitmap1", jobj);
    /* bitmap2[] */
    jobjarr = json_object_new_array();
    for (a=0;a<128;a++)
    {
	jobj1 = json_object_new_int(scheduler.bitmap2[a]);
	json_object_array_add(jobjarr,jobj1);

    }
    json_object_object_add(scheduler_node,"bitmap2", jobjarr);
    /* ebitmap2[] */
    jobjarr = json_object_new_array();
    for (a=0;a<128;a++)
    {
	jobj1 = json_object_new_int(scheduler.bitmap2[a]);
	json_object_array_add(jobjarr,jobj1);

    }
    json_object_object_add(scheduler_node,"ebitmap2", jobjarr);
    /* bitmap3[][] */
    jobjarr = json_object_new_array();
    for (a=0;a<128;a++)
    {
	jobjarr1 = json_object_new_array();
	for (b=0;b<128;b++)
	{
	    jobj1 = json_object_new_int(scheduler.bitmap3[a][b]);
	    json_object_array_add(jobjarr1,jobj1);
	}
	json_object_array_add(jobjarr,jobjarr1);

    }
    json_object_object_add(scheduler_node,"bitmap3", jobjarr);
    /* ebitmap3[][] */
    jobjarr = json_object_new_array();
    for (a=0;a<128;a++)
    {
	jobjarr1 = json_object_new_array();
	for (b=0;b<128;b++)
	{
	    jobj1 = json_object_new_int(scheduler.ebitmap3[a][b]);
	    json_object_array_add(jobjarr1,jobj1);
	}
	json_object_array_add(jobjarr,jobjarr1);

    }
    json_object_object_add(scheduler_node,"ebitmap3", jobjarr);
    /* Add to root node */
    json_object_object_add(root_node,"scheduler", scheduler_node);
#endif
    return hash_ok;
}
Example #7
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;
}