void tuning_db_destroy (hashcat_ctx_t *hashcat_ctx) { tuning_db_t *tuning_db = hashcat_ctx->tuning_db; if (tuning_db->enabled == false) return; int i; for (i = 0; i < tuning_db->alias_cnt; i++) { tuning_db_alias_t *alias = &tuning_db->alias_buf[i]; hcfree (alias->device_name); hcfree (alias->alias_name); } for (i = 0; i < tuning_db->entry_cnt; i++) { tuning_db_entry_t *entry = &tuning_db->entry_buf[i]; hcfree ((void *)entry->device_name); } hcfree (tuning_db->alias_buf); hcfree (tuning_db->entry_buf); memset (tuning_db, 0, sizeof (tuning_db_t)); }
void status_speed_machine_readable (hashcat_ctx_t *hashcat_ctx) { hashcat_status_t *hashcat_status = (hashcat_status_t *) hcmalloc (sizeof (hashcat_status_t)); const int rc_status = hashcat_get_status (hashcat_ctx, hashcat_status); if (rc_status == -1) { hcfree (hashcat_status); return; } for (int device_id = 0; device_id < hashcat_status->device_info_cnt; device_id++) { const device_info_t *device_info = hashcat_status->device_info_buf + device_id; if (device_info->skipped_dev == true) continue; event_log_info (hashcat_ctx, "%d:%" PRIu64, device_id + 1, (u64) (device_info->hashes_msec_dev_benchmark * 1000)); } status_status_destroy (hashcat_ctx, hashcat_status); hcfree (hashcat_status); }
void status_progress_machine_readable (hashcat_ctx_t *hashcat_ctx) { hashcat_status_t *hashcat_status = (hashcat_status_t *) hcmalloc (sizeof (hashcat_status_t)); const int rc_status = hashcat_get_status (hashcat_ctx, hashcat_status); if (rc_status == -1) { hcfree (hashcat_status); return; } for (int device_id = 0; device_id < hashcat_status->device_info_cnt; device_id++) { const device_info_t *device_info = hashcat_status->device_info_buf + device_id; if (device_info->skipped_dev == true) continue; event_log_info (hashcat_ctx, "%d:%" PRIu64 ":%0.2f", device_id + 1, device_info->progress_dev, device_info->runtime_msec_dev); } status_status_destroy (hashcat_ctx, hashcat_status); hcfree (hashcat_status); }
void potfile_destroy (hashcat_ctx_t *hashcat_ctx) { potfile_ctx_t *potfile_ctx = hashcat_ctx->potfile_ctx; if (potfile_ctx->enabled == false) return; hcfree (potfile_ctx->out_buf); hcfree (potfile_ctx->tmp_buf); memset (potfile_ctx, 0, sizeof (potfile_ctx_t)); }
void logfile_destroy (hashcat_ctx_t *hashcat_ctx) { logfile_ctx_t *logfile_ctx = hashcat_ctx->logfile_ctx; if (logfile_ctx->enabled == false) return; hcfree (logfile_ctx->logfile); hcfree (logfile_ctx->topid); hcfree (logfile_ctx->subid); memset (logfile_ctx, 0, sizeof (logfile_ctx_t)); }
void mask_ctx_destroy (hashcat_ctx_t *hashcat_ctx) { mask_ctx_t *mask_ctx = hashcat_ctx->mask_ctx; if (mask_ctx->enabled == false) return; hcfree (mask_ctx->css_buf); hcfree (mask_ctx->root_css_buf); hcfree (mask_ctx->markov_css_buf); hcfree (mask_ctx->root_table_buf); hcfree (mask_ctx->markov_table_buf); for (u32 mask_pos = 0; mask_pos < mask_ctx->masks_cnt; mask_pos++) { hcfree (mask_ctx->masks[mask_pos]); } hcfree (mask_ctx->masks); hcfree (mask_ctx->mfs); memset (mask_ctx, 0, sizeof (mask_ctx_t)); }
void dictstat_destroy (hashcat_ctx_t *hashcat_ctx) { hashconfig_t *hashconfig = hashcat_ctx->hashconfig; dictstat_ctx_t *dictstat_ctx = hashcat_ctx->dictstat_ctx; if (dictstat_ctx->enabled == false) return; if (hashconfig->dictstat_disable == true) return; hcfree (dictstat_ctx->filename); hcfree (dictstat_ctx->base); memset (dictstat_ctx, 0, sizeof (dictstat_ctx_t)); }
void status_benchmark (hashcat_ctx_t *hashcat_ctx) { const user_options_t *user_options = hashcat_ctx->user_options; if (user_options->machine_readable == true) { status_benchmark_machine_readable (hashcat_ctx); return; } hashcat_status_t *hashcat_status = (hashcat_status_t *) hcmalloc (sizeof (hashcat_status_t)); const int rc_status = hashcat_get_status (hashcat_ctx, hashcat_status); if (rc_status == -1) { hcfree (hashcat_status); return; } for (int device_id = 0; device_id < hashcat_status->device_info_cnt; device_id++) { const device_info_t *device_info = hashcat_status->device_info_buf + device_id; if (device_info->skipped_dev == true) continue; event_log_info (hashcat_ctx, "Speed.#%d.........: %9sH/s (%0.2fms) @ Accel:%d Loops:%d Thr:%d Vec:%d", device_id + 1, device_info->speed_sec_dev, device_info->exec_msec_dev, device_info->kernel_accel_dev, device_info->kernel_loops_dev, device_info->kernel_threads_dev, device_info->vector_width_dev); } if (hashcat_status->device_info_active > 1) { event_log_info (hashcat_ctx, "Speed.#*.........: %9sH/s", hashcat_status->speed_sec_all); } status_status_destroy (hashcat_ctx, hashcat_status); hcfree (hashcat_status); }
void status_progress (hashcat_ctx_t *hashcat_ctx) { const user_options_t *user_options = hashcat_ctx->user_options; if (user_options->machine_readable == true) { status_progress_machine_readable (hashcat_ctx); return; } hashcat_status_t *hashcat_status = (hashcat_status_t *) hcmalloc (sizeof (hashcat_status_t)); const int rc_status = hashcat_get_status (hashcat_ctx, hashcat_status); if (rc_status == -1) { hcfree (hashcat_status); return; } for (int device_id = 0; device_id < hashcat_status->device_info_cnt; device_id++) { const device_info_t *device_info = hashcat_status->device_info_buf + device_id; if (device_info->skipped_dev == true) continue; event_log_info (hashcat_ctx, "Progress.#%d......: %" PRIu64, device_id + 1, device_info->progress_dev); } for (int device_id = 0; device_id < hashcat_status->device_info_cnt; device_id++) { const device_info_t *device_info = hashcat_status->device_info_buf + device_id; if (device_info->skipped_dev == true) continue; event_log_info (hashcat_ctx, "Runtime.#%d.......: %0.2fms", device_id + 1, device_info->runtime_msec_dev); } status_status_destroy (hashcat_ctx, hashcat_status); hcfree (hashcat_status); }
static int mp_css_append_salt (hashcat_ctx_t *hashcat_ctx, salt_t *salt_buf) { mask_ctx_t *mask_ctx = hashcat_ctx->mask_ctx; u32 salt_len = salt_buf->salt_len; u8 *salt_buf_ptr = (u8 *) salt_buf->salt_buf; u32 css_cnt_salt = mask_ctx->css_cnt + salt_len; cs_t *css_buf_salt = (cs_t *) hccalloc (css_cnt_salt, sizeof (cs_t)); memcpy (css_buf_salt, mask_ctx->css_buf, mask_ctx->css_cnt * sizeof (cs_t)); for (u32 i = 0, j = mask_ctx->css_cnt; i < salt_len; i++, j++) { css_buf_salt[j].cs_buf[0] = salt_buf_ptr[i]; css_buf_salt[j].cs_len = 1; } hcfree (mask_ctx->css_buf); mask_ctx->css_buf = css_buf_salt; mask_ctx->css_cnt = css_cnt_salt; return 0; }
void outcheck_ctx_destroy (hashcat_ctx_t *hashcat_ctx) { outcheck_ctx_t *outcheck_ctx = hashcat_ctx->outcheck_ctx; user_options_t *user_options = hashcat_ctx->user_options; if (outcheck_ctx->enabled == false) return; if (rmdir (outcheck_ctx->root_directory) == -1) { if (errno == ENOENT) { // good, we can ignore } else if (errno == ENOTEMPTY) { // good, we can ignore } else { event_log_error (hashcat_ctx, "%s: %m", outcheck_ctx->root_directory); //return -1; } } if (user_options->outfile_check_dir == NULL) { hcfree (outcheck_ctx->root_directory); } memset (outcheck_ctx, 0, sizeof (outcheck_ctx_t)); }
void straight_ctx_destroy (hashcat_ctx_t *hashcat_ctx) { straight_ctx_t *straight_ctx = hashcat_ctx->straight_ctx; if (straight_ctx->enabled == false) return; for (u32 dict_pos = 0; dict_pos < straight_ctx->dicts_cnt; dict_pos++) { hcfree (straight_ctx->dicts[dict_pos]); } hcfree (straight_ctx->dicts); hcfree (straight_ctx->kernel_rules_buf); memset (straight_ctx, 0, sizeof (straight_ctx_t)); }
void status_speed (hashcat_ctx_t *hashcat_ctx) { const user_options_t *user_options = hashcat_ctx->user_options; if (user_options->machine_readable == true) { status_speed_machine_readable (hashcat_ctx); return; } hashcat_status_t *hashcat_status = (hashcat_status_t *) hcmalloc (sizeof (hashcat_status_t)); const int rc_status = hashcat_get_status (hashcat_ctx, hashcat_status); if (rc_status == -1) { hcfree (hashcat_status); return; } for (int device_id = 0; device_id < hashcat_status->device_info_cnt; device_id++) { const device_info_t *device_info = hashcat_status->device_info_buf + device_id; if (device_info->skipped_dev == true) continue; event_log_info (hashcat_ctx, "Speed.Dev.#%d.....: %9sH/s (%0.2fms)", device_id + 1, device_info->speed_sec_dev, device_info->exec_msec_dev); } if (hashcat_status->device_info_active > 1) { event_log_info (hashcat_ctx, "Speed.Dev.#*.....: %9sH/s", hashcat_status->speed_sec_all); } status_status_destroy (hashcat_ctx, hashcat_status); hcfree (hashcat_status); }
void combinator_ctx_destroy (hashcat_ctx_t *hashcat_ctx) { combinator_ctx_t *combinator_ctx = hashcat_ctx->combinator_ctx; if (combinator_ctx->enabled == false) return; hcfree (combinator_ctx->scratch_buf); memset (combinator_ctx, 0, sizeof (combinator_ctx_t)); }
void cpt_ctx_destroy (hashcat_ctx_t *hashcat_ctx) { cpt_ctx_t *cpt_ctx = hashcat_ctx->cpt_ctx; if (cpt_ctx->enabled == false) return; hcfree (cpt_ctx->cpt_buf); memset (cpt_ctx, 0, sizeof (cpt_ctx_t)); }
static int get_exec_path (char *exec_path, const size_t exec_path_sz) { #if defined (__linux__) || defined (__CYGWIN__) char *tmp; hc_asprintf (&tmp, "/proc/%d/exe", getpid ()); const ssize_t len = readlink (tmp, exec_path, exec_path_sz - 1); hcfree (tmp); if (len == -1) return -1; #elif defined (_WIN) const DWORD len = GetModuleFileName (NULL, exec_path, exec_path_sz - 1); if (len == 0) return -1; #elif defined (__APPLE__) u32 size = (u32) exec_path_sz; if (_NSGetExecutablePath (exec_path, &size) != 0) return -1; const size_t len = strlen (exec_path); #elif defined (__FreeBSD__) #include <sys/sysctl.h> int mib[4]; mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_PATHNAME; mib[3] = -1; size_t size = exec_path_sz; sysctl (mib, 4, exec_path, &size, NULL, 0); const size_t len = strlen (exec_path); #else #error Your Operating System is not supported or detected #endif exec_path[len] = 0; return 0; }
void hashes_destroy (hashcat_ctx_t *hashcat_ctx) { hashes_t *hashes = hashcat_ctx->hashes; hcfree (hashes->digests_buf); hcfree (hashes->digests_shown); hcfree (hashes->digests_shown_tmp); hcfree (hashes->salts_buf); hcfree (hashes->salts_shown); hcfree (hashes->esalts_buf); hcfree (hashes->hash_info); hcfree (hashes->out_buf); hcfree (hashes->tmp_buf); memset (hashes, 0, sizeof (hashes_t)); }
void bitmap_ctx_destroy (hashcat_ctx_t *hashcat_ctx) { bitmap_ctx_t *bitmap_ctx = hashcat_ctx->bitmap_ctx; if (bitmap_ctx->enabled == false) return; hcfree (bitmap_ctx->bitmap_s1_a); hcfree (bitmap_ctx->bitmap_s1_b); hcfree (bitmap_ctx->bitmap_s1_c); hcfree (bitmap_ctx->bitmap_s1_d); hcfree (bitmap_ctx->bitmap_s2_a); hcfree (bitmap_ctx->bitmap_s2_b); hcfree (bitmap_ctx->bitmap_s2_c); hcfree (bitmap_ctx->bitmap_s2_d); memset (bitmap_ctx, 0, sizeof (bitmap_ctx_t)); }
u32 hlfmt_detect (hashcat_ctx_t *hashcat_ctx, FILE *fp, u32 max_check) { const hashconfig_t *hashconfig = hashcat_ctx->hashconfig; // Exception: those formats are wrongly detected as HLFMT_SHADOW, prevent it if (hashconfig->hash_mode == 5300) return HLFMT_HASHCAT; if (hashconfig->hash_mode == 5400) return HLFMT_HASHCAT; u32 *formats_cnt = (u32 *) hccalloc (HLFMTS_CNT, sizeof (u32)); u32 num_check = 0; char *line_buf = (char *) hcmalloc (HCBUFSIZ_LARGE); while (!feof (fp)) { const size_t line_len = fgetl (fp, line_buf); if (line_len == 0) continue; if (hlfmt_detect_pwdump (hashcat_ctx, line_buf, line_len)) formats_cnt[HLFMT_PWDUMP]++; if (hlfmt_detect_passwd (hashcat_ctx, line_buf, line_len)) formats_cnt[HLFMT_PASSWD]++; if (hlfmt_detect_shadow (hashcat_ctx, line_buf, line_len)) formats_cnt[HLFMT_SHADOW]++; if (num_check == max_check) break; num_check++; } hcfree (line_buf); u32 hashlist_format = HLFMT_HASHCAT; for (u32 i = 1; i < HLFMTS_CNT; i++) { if (formats_cnt[i - 1] >= formats_cnt[i]) continue; hashlist_format = i; } free (formats_cnt); return hashlist_format; }
static void main_outerloop_finished (MAYBE_UNUSED hashcat_ctx_t *hashcat_ctx, MAYBE_UNUSED const void *buf, MAYBE_UNUSED const size_t len) { hashcat_user_t *hashcat_user = hashcat_ctx->hashcat_user; status_ctx_t *status_ctx = hashcat_ctx->status_ctx; // wait for outer threads status_ctx->shutdown_outer = true; for (int thread_idx = 0; thread_idx < hashcat_user->outer_threads_cnt; thread_idx++) { hc_thread_wait (1, &hashcat_user->outer_threads[thread_idx]); } hcfree (hashcat_user->outer_threads); hashcat_user->outer_threads_cnt = 0; }
int module_hash_init_selftest (MAYBE_UNUSED const hashconfig_t *hashconfig, hash_t *hash) { const size_t st_hash_len = strlen (hashconfig->st_hash); char *tmpdata = (char *) hcmalloc (st_hash_len / 2); for (size_t i = 0, j = 0; j < st_hash_len; i += 1, j += 2) { const u8 c = hex_to_u8 ((const u8 *) hashconfig->st_hash + j); tmpdata[i] = c; } const int parser_status = module_hash_decode (hashconfig, hash->digest, hash->salt, hash->esalt, hash->hook_salt, hash->hash_info, tmpdata, st_hash_len / 2); hcfree (tmpdata); return parser_status; }
static int mp_add_cs_buf (hashcat_ctx_t *hashcat_ctx, const u32 *in_buf, size_t in_len, cs_t *css, u32 css_cnt) { const hashconfig_t *hashconfig = hashcat_ctx->hashconfig; cs_t *cs = &css[css_cnt]; size_t css_uniq_sz = CHARSIZ * sizeof (u32); u32 *css_uniq = (u32 *) hcmalloc (css_uniq_sz); size_t i; for (i = 0; i < cs->cs_len; i++) { const u32 u = cs->cs_buf[i]; css_uniq[u] = 1; } for (i = 0; i < in_len; i++) { u32 u = in_buf[i] & 0xff; if (hashconfig->opts_type & OPTS_TYPE_PT_UPPER) u = (u32) toupper (u); if (css_uniq[u] == 1) continue; css_uniq[u] = 1; cs->cs_buf[cs->cs_len] = u; cs->cs_len++; } hcfree (css_uniq); return 0; }
static int mp_css_utf16be_expand (hashcat_ctx_t *hashcat_ctx) { mask_ctx_t *mask_ctx = hashcat_ctx->mask_ctx; u32 css_cnt_utf16be = mask_ctx->css_cnt * 2; cs_t *css_buf_utf16be = (cs_t *) hccalloc (css_cnt_utf16be, sizeof (cs_t)); for (u32 i = 0, j = 0; i < mask_ctx->css_cnt; i += 1, j += 2) { css_buf_utf16be[j + 0].cs_buf[0] = 0; css_buf_utf16be[j + 0].cs_len = 1; memcpy (&css_buf_utf16be[j + 1], &mask_ctx->css_buf[i], sizeof (cs_t)); } hcfree (mask_ctx->css_buf); mask_ctx->css_buf = css_buf_utf16be; mask_ctx->css_cnt = css_cnt_utf16be; return 0; }
int module_hash_encode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const void *digest_buf, MAYBE_UNUSED const salt_t *salt, MAYBE_UNUSED const void *esalt_buf, MAYBE_UNUSED const void *hook_salt_buf, MAYBE_UNUSED const hashinfo_t *hash_info, char *line_buf, MAYBE_UNUSED const int line_size) { const dpapimk_t *dpapimk = (const dpapimk_t *) esalt_buf; u32 version = 2; u32 context = dpapimk->context; u32 rounds = salt->salt_iter + 1; u32 contents_len = dpapimk->contents_len; u32 SID_len = dpapimk->SID_len; u32 iv_len = 32; u8 cipher_algorithm[8] = { 0 }; u8 hash_algorithm[8] = { 0 }; u8 SID[512] = { 0 }; u8* SID_tmp; u32 *ptr_SID = (u32 *) dpapimk->SID; u32 *ptr_iv = (u32 *) dpapimk->iv; u32 *ptr_contents = (u32 *) dpapimk->contents; u32 u32_iv[4]; u8 iv[32 + 1]; // convert back SID SID_tmp = (u8 *) hcmalloc ((SID_len + 1) * sizeof(u8)); for (u32 i = 0; i < (SID_len / 4) + 1; i++) { u8 hex[8] = { 0 }; u32_to_hex (byte_swap_32 (ptr_SID[i]), hex); for (u32 j = 0, k = 0; j < 8; j += 2, k++) { SID_tmp[i * 4 + k] = hex_to_u8 (&hex[j]); } } // overwrite trailing 0x80 SID_tmp[SID_len] = 0; for (u32 i = 0, j = 0 ; j < SID_len ; i++, j += 2) { SID[i] = SID_tmp[j]; } hcfree (SID_tmp); for (u32 i = 0; i < iv_len / 8; i++) { u32_iv[i] = byte_swap_32 (ptr_iv[i]); u32_to_hex (u32_iv[i], iv + i * 8); } iv[32] = 0; u32 u32_contents[36]; u8 contents[288 + 1]; for (u32 i = 0; i < contents_len / 8; i++) { u32_contents[i] = byte_swap_32 (ptr_contents[i]); u32_to_hex (u32_contents[i], contents + i * 8); } contents[288] = 0; if (contents_len == 288) { memcpy (cipher_algorithm, "aes256", strlen ("aes256")); memcpy (hash_algorithm, "sha512", strlen ("sha512")); } const int line_len = snprintf (line_buf, line_size, "%s%d*%d*%s*%s*%s*%d*%s*%d*%s", SIGNATURE_DPAPIMK, version, context, SID, cipher_algorithm, hash_algorithm, rounds, iv, contents_len, contents); return line_len; }
static int sp_setup_tbl (hashcat_ctx_t *hashcat_ctx) { folder_config_t *folder_config = hashcat_ctx->folder_config; mask_ctx_t *mask_ctx = hashcat_ctx->mask_ctx; user_options_t *user_options = hashcat_ctx->user_options; char *shared_dir = folder_config->shared_dir; char *hcstat = user_options->markov_hcstat; u32 disable = user_options->markov_disable; u32 classic = user_options->markov_classic; hcstat_table_t *root_table_buf = mask_ctx->root_table_buf; hcstat_table_t *markov_table_buf = mask_ctx->markov_table_buf; /** * Initialize hcstats */ u64 *root_stats_buf = (u64 *) hccalloc (SP_ROOT_CNT, sizeof (u64)); u64 *root_stats_ptr = root_stats_buf; u64 *root_stats_buf_by_pos[SP_PW_MAX]; for (int i = 0; i < SP_PW_MAX; i++) { root_stats_buf_by_pos[i] = root_stats_ptr; root_stats_ptr += CHARSIZ; } u64 *markov_stats_buf = (u64 *) hccalloc (SP_MARKOV_CNT, sizeof (u64)); u64 *markov_stats_ptr = markov_stats_buf; u64 *markov_stats_buf_by_key[SP_PW_MAX][CHARSIZ]; for (int i = 0; i < SP_PW_MAX; i++) { for (int j = 0; j < CHARSIZ; j++) { markov_stats_buf_by_key[i][j] = markov_stats_ptr; markov_stats_ptr += CHARSIZ; } } /** * Load hcstats File */ char hcstat_tmp[256]; if (hcstat == NULL) { snprintf (hcstat_tmp, sizeof (hcstat_tmp), "%s/%s", shared_dir, SP_HCSTAT); hcstat = hcstat_tmp; } struct stat s; if (stat (hcstat, &s) == -1) { event_log_error (hashcat_ctx, "%s: %s", hcstat, strerror (errno)); return -1; } FILE *fd = fopen (hcstat, "rb"); if (fd == NULL) { event_log_error (hashcat_ctx, "%s: %s", hcstat, strerror (errno)); return -1; } u8 *inbuf = (u8 *) hcmalloc (s.st_size); SizeT inlen = (SizeT) hc_fread (inbuf, 1, s.st_size, fd); if (inlen != (SizeT) s.st_size) { event_log_error (hashcat_ctx, "%s: Could not read data.", hcstat); fclose (fd); hcfree (inbuf); return -1; } fclose (fd); u8 *outbuf = (u8 *) hcmalloc (SP_FILESZ); SizeT outlen = SP_FILESZ; const char props = 0x1c; // lzma properties constant, retrieved with 7z2hashcat const SRes res = hc_lzma2_decompress (inbuf, &inlen, outbuf, &outlen, &props); if (res != SZ_OK) { event_log_error (hashcat_ctx, "%s: Could not uncompress data.", hcstat); hcfree (inbuf); hcfree (outbuf); return -1; } if (outlen != SP_FILESZ) { event_log_error (hashcat_ctx, "%s: Could not uncompress data.", hcstat); hcfree (inbuf); hcfree (outbuf); return -1; } u64 *ptr = (u64 *) outbuf; u64 v = *ptr++; u64 z = *ptr++; memcpy (root_stats_buf, ptr, sizeof (u64) * SP_ROOT_CNT); ptr += SP_ROOT_CNT; memcpy (markov_stats_buf, ptr, sizeof (u64) * SP_MARKOV_CNT); // ptr += SP_MARKOV_CNT; hcfree (inbuf); hcfree (outbuf); /** * switch endianess */ v = byte_swap_64 (v); z = byte_swap_64 (z); for (int i = 0; i < SP_ROOT_CNT; i++) root_stats_buf[i] = byte_swap_64 (root_stats_buf[i]); for (int i = 0; i < SP_MARKOV_CNT; i++) markov_stats_buf[i] = byte_swap_64 (markov_stats_buf[i]); /** * verify header */ if (v != SP_VERSION) { event_log_error (hashcat_ctx, "%s: Invalid header", hcstat); return -1; } if (z != 0) { event_log_error (hashcat_ctx, "%s: Invalid header", hcstat); return -1; } /** * Markov modifier of hcstat_table on user request */ if (disable) { memset (root_stats_buf, 0, SP_ROOT_CNT * sizeof (u64)); memset (markov_stats_buf, 0, SP_MARKOV_CNT * sizeof (u64)); } if (classic) { /* Add all stats to first position */ for (int i = 1; i < SP_PW_MAX; i++) { u64 *out = root_stats_buf_by_pos[0]; u64 *in = root_stats_buf_by_pos[i]; for (int j = 0; j < CHARSIZ; j++) { *out++ += *in++; } } for (int i = 1; i < SP_PW_MAX; i++) { u64 *out = markov_stats_buf_by_key[0][0]; u64 *in = markov_stats_buf_by_key[i][0]; for (int j = 0; j < CHARSIZ; j++) { for (int k = 0; k < CHARSIZ; k++) { *out++ += *in++; } } } /* copy them to all pw_positions */ for (int i = 1; i < SP_PW_MAX; i++) { memcpy (root_stats_buf_by_pos[i], root_stats_buf_by_pos[0], CHARSIZ * sizeof (u64)); } for (int i = 1; i < SP_PW_MAX; i++) { memcpy (markov_stats_buf_by_key[i][0], markov_stats_buf_by_key[0][0], CHARSIZ * CHARSIZ * sizeof (u64)); } } /** * Initialize tables */ hcstat_table_t *root_table_ptr = root_table_buf; hcstat_table_t *root_table_buf_by_pos[SP_PW_MAX]; for (int i = 0; i < SP_PW_MAX; i++) { root_table_buf_by_pos[i] = root_table_ptr; root_table_ptr += CHARSIZ; } hcstat_table_t *markov_table_ptr = markov_table_buf; hcstat_table_t *markov_table_buf_by_key[SP_PW_MAX][CHARSIZ]; for (int i = 0; i < SP_PW_MAX; i++) { for (int j = 0; j < CHARSIZ; j++) { markov_table_buf_by_key[i][j] = markov_table_ptr; markov_table_ptr += CHARSIZ; } } /** * Convert hcstat to tables */ for (int i = 0; i < SP_ROOT_CNT; i++) { u32 key = i % CHARSIZ; root_table_buf[i].key = key; root_table_buf[i].val = root_stats_buf[i]; } for (int i = 0; i < SP_MARKOV_CNT; i++) { u32 key = i % CHARSIZ; markov_table_buf[i].key = key; markov_table_buf[i].val = markov_stats_buf[i]; } hcfree (root_stats_buf); hcfree (markov_stats_buf); /** * Finally sort them */ for (int i = 0; i < SP_PW_MAX; i++) { qsort (root_table_buf_by_pos[i], CHARSIZ, sizeof (hcstat_table_t), sp_comp_val); } for (int i = 0; i < SP_PW_MAX; i++) { for (int j = 0; j < CHARSIZ; j++) { qsort (markov_table_buf_by_key[i][j], CHARSIZ, sizeof (hcstat_table_t), sp_comp_val); } } return 0; }
int mask_ctx_init (hashcat_ctx_t *hashcat_ctx) { mask_ctx_t *mask_ctx = hashcat_ctx->mask_ctx; user_options_extra_t *user_options_extra = hashcat_ctx->user_options_extra; user_options_t *user_options = hashcat_ctx->user_options; mask_ctx->enabled = false; if (user_options->example_hashes == true) return 0; if (user_options->left == true) return 0; if (user_options->opencl_info == true) return 0; if (user_options->show == true) return 0; if (user_options->usage == true) return 0; if (user_options->version == true) return 0; if (user_options->attack_mode == ATTACK_MODE_STRAIGHT) return 0; if (user_options->attack_mode == ATTACK_MODE_COMBI) return 0; mask_ctx->enabled = true; mask_ctx->root_table_buf = (hcstat_table_t *) hccalloc (SP_ROOT_CNT, sizeof (hcstat_table_t)); mask_ctx->markov_table_buf = (hcstat_table_t *) hccalloc (SP_MARKOV_CNT, sizeof (hcstat_table_t)); const int rc_setup_tbl = sp_setup_tbl (hashcat_ctx); if (rc_setup_tbl == -1) return -1; mask_ctx->root_css_buf = (cs_t *) hccalloc (SP_PW_MAX, sizeof (cs_t)); mask_ctx->markov_css_buf = (cs_t *) hccalloc (SP_PW_MAX * CHARSIZ, sizeof (cs_t)); mask_ctx->css_cnt = 0; mask_ctx->css_buf = NULL; mask_ctx->mask_from_file = false; mask_ctx->masks = NULL; mask_ctx->masks_pos = 0; mask_ctx->masks_cnt = 0; mask_ctx->mfs = (mf_t *) hccalloc (MAX_MFS, sizeof (mf_t)); mp_setup_sys (mask_ctx->mp_sys); if (user_options->custom_charset_1) { const int rc = mp_setup_usr (hashcat_ctx, mask_ctx->mp_sys, mask_ctx->mp_usr, user_options->custom_charset_1, 0); if (rc == -1) return -1; } if (user_options->custom_charset_2) { const int rc = mp_setup_usr (hashcat_ctx, mask_ctx->mp_sys, mask_ctx->mp_usr, user_options->custom_charset_2, 1); if (rc == -1) return -1; } if (user_options->custom_charset_3) { const int rc = mp_setup_usr (hashcat_ctx, mask_ctx->mp_sys, mask_ctx->mp_usr, user_options->custom_charset_3, 2); if (rc == -1) return -1; } if (user_options->custom_charset_4) { const int rc = mp_setup_usr (hashcat_ctx, mask_ctx->mp_sys, mask_ctx->mp_usr, user_options->custom_charset_4, 3); if (rc == -1) return -1; } if (user_options->attack_mode == ATTACK_MODE_BF) { if (user_options->benchmark == false) { if (user_options_extra->hc_workc) { char *arg = user_options_extra->hc_workv[0]; if (hc_path_exist (arg) == false) { const int rc = mask_append (hashcat_ctx, arg, NULL); if (rc == -1) return -1; } else { mask_ctx->mask_from_file = true; for (int i = 0; i < user_options_extra->hc_workc; i++) { arg = user_options_extra->hc_workv[i]; if (hc_path_is_file (arg) == true) { FILE *mask_fp = fopen (arg, "r"); if (mask_fp == NULL) { event_log_error (hashcat_ctx, "%s: %s", arg, strerror (errno)); return -1; } char *line_buf = (char *) hcmalloc (HCBUFSIZ_LARGE); while (!feof (mask_fp)) { const size_t line_len = fgetl (mask_fp, line_buf); if (line_len == 0) continue; if (line_buf[0] == '#') continue; char *mask_buf = mask_ctx_parse_maskfile_find_mask (line_buf, line_len); char *prepend_buf = NULL; if (line_buf != mask_buf) { // if we have custom charsets prepend_buf = line_buf; mask_buf[-1] = 0; } const int rc = mask_append (hashcat_ctx, mask_buf, prepend_buf); if (rc == -1) { fclose (mask_fp); return -1; } } hcfree (line_buf); fclose (mask_fp); } else { event_log_error (hashcat_ctx, "%s: unsupported file type.", arg); return -1; } } } } else { const char *mask = DEF_MASK; const int rc = mask_append (hashcat_ctx, mask, NULL); if (rc == -1) return -1; } } else { const char *mask = hashconfig_benchmark_mask (hashcat_ctx); const int rc = mask_append (hashcat_ctx, mask, NULL); if (rc == -1) return -1; } } else if (user_options->attack_mode == ATTACK_MODE_HYBRID1) { // display char *arg = user_options_extra->hc_workv[user_options_extra->hc_workc - 1]; // mod if (hc_path_exist (arg) == false) { const int rc = mask_append (hashcat_ctx, arg, NULL); if (rc == -1) return -1; } else { if (hc_path_is_file (arg) == true) { mask_ctx->mask_from_file = true; FILE *mask_fp = fopen (arg, "r"); if (mask_fp == NULL) { event_log_error (hashcat_ctx, "%s: %s", arg, strerror (errno)); return -1; } char *line_buf = (char *) hcmalloc (HCBUFSIZ_LARGE); while (!feof (mask_fp)) { const size_t line_len = fgetl (mask_fp, line_buf); if (line_len == 0) continue; if (line_buf[0] == '#') continue; char *mask_buf = mask_ctx_parse_maskfile_find_mask (line_buf, line_len); char *prepend_buf = NULL; if (line_buf != mask_buf) { // if we have custom charsets prepend_buf = line_buf; mask_buf[-1] = 0; } const int rc = mask_append (hashcat_ctx, mask_buf, prepend_buf); if (rc == -1) { fclose (mask_fp); return -1; } } hcfree (line_buf); fclose (mask_fp); } else { event_log_error (hashcat_ctx, "%s: unsupported file type.", arg); return -1; } } } else if (user_options->attack_mode == ATTACK_MODE_HYBRID2) { // display char *arg = user_options_extra->hc_workv[0]; // mod if (hc_path_exist (arg) == false) { const int rc = mask_append (hashcat_ctx, arg, NULL); if (rc == -1) return -1; } else { if (hc_path_is_file (arg) == true) { mask_ctx->mask_from_file = true; FILE *mask_fp = fopen (arg, "r"); if (mask_fp == NULL) { event_log_error (hashcat_ctx, "%s: %s", arg, strerror (errno)); return -1; } char *line_buf = (char *) hcmalloc (HCBUFSIZ_LARGE); while (!feof (mask_fp)) { const size_t line_len = fgetl (mask_fp, line_buf); if (line_len == 0) continue; if (line_buf[0] == '#') continue; char *mask_buf = mask_ctx_parse_maskfile_find_mask (line_buf, line_len); char *prepend_buf = NULL; if (line_buf != mask_buf) { // if we have custom charsets prepend_buf = line_buf; mask_buf[-1] = 0; } const int rc = mask_append (hashcat_ctx, mask_buf, prepend_buf); if (rc == -1) { fclose (mask_fp); return -1; } } hcfree (line_buf); fclose (mask_fp); } else { event_log_error (hashcat_ctx, "%s: unsupported file type.", arg); return -1; } } } if (mask_ctx->masks_cnt == 0) { event_log_error (hashcat_ctx, "Invalid mask."); return -1; } mask_ctx->mask = mask_ctx->masks[0]; return 0; }
static int mask_append (hashcat_ctx_t *hashcat_ctx, const char *mask, const char *prepend) { hashconfig_t *hashconfig = hashcat_ctx->hashconfig; user_options_t *user_options = hashcat_ctx->user_options; if (user_options->increment == true) { const u32 mask_length = mp_get_length (mask); u32 increment_min = user_options->increment_min; u32 increment_max = user_options->increment_max; increment_max = MIN (increment_max, mask_length); if (user_options->attack_mode == ATTACK_MODE_BF) { const u32 pw_min = hashconfig->pw_min; const u32 pw_max = hashconfig->pw_max; increment_min = MAX (increment_min, pw_min); increment_max = MIN (increment_max, pw_max); } for (u32 increment_len = increment_min; increment_len <= increment_max; increment_len++) { char *mask_truncated = (char *) hcmalloc (256); char *mask_truncated_next = mask_truncated; if (prepend) { // this happens with maskfiles only mask_truncated_next += snprintf (mask_truncated, 256, "%s,", prepend); } const int rc_truncated_mask = mp_get_truncated_mask (hashcat_ctx, mask, strlen (mask), increment_len, mask_truncated_next); if (rc_truncated_mask == -1) { hcfree (mask_truncated); break; } const int rc = mask_append_final (hashcat_ctx, mask_truncated); hcfree (mask_truncated); if (rc == -1) return -1; } } else { if (prepend) { // this happens with maskfiles only char *prepend_mask; hc_asprintf (&prepend_mask, "%s,%s", prepend, mask); const int rc = mask_append_final (hashcat_ctx, prepend_mask); hcfree (prepend_mask); if (rc == -1) return -1; } else { const int rc = mask_append_final (hashcat_ctx, mask); if (rc == -1) return -1; } } return 0; }
int potfile_init (hashcat_ctx_t *hashcat_ctx) { folder_config_t *folder_config = hashcat_ctx->folder_config; potfile_ctx_t *potfile_ctx = hashcat_ctx->potfile_ctx; user_options_t *user_options = hashcat_ctx->user_options; potfile_ctx->enabled = false; if (user_options->benchmark == true) return 0; if (user_options->example_hashes == true) return 0; if (user_options->keyspace == true) return 0; if (user_options->opencl_info == true) return 0; if (user_options->stdout_flag == true) return 0; if (user_options->speed_only == true) return 0; if (user_options->progress_only == true) return 0; if (user_options->usage == true) return 0; if (user_options->version == true) return 0; if (user_options->potfile_disable == true) return 0; potfile_ctx->enabled = true; if (user_options->potfile_path == NULL) { potfile_ctx->fp = NULL; hc_asprintf (&potfile_ctx->filename, "%s/hashcat.potfile", folder_config->profile_dir); } else { potfile_ctx->filename = hcstrdup (user_options->potfile_path); potfile_ctx->fp = NULL; } // keep all hashes if --username was combined with --left or --show potfile_ctx->keep_all_hashes = false; if (user_options->username == true) { if ((user_options->show == true) || (user_options->left == true)) { potfile_ctx->keep_all_hashes = true; } } // keep all hashes if -m 3000 was combined with --left or --show if (user_options->hash_mode == 3000) { if ((user_options->show == true) || (user_options->left == true)) { potfile_ctx->keep_all_hashes = true; } } // starting from here, we should allocate some scratch buffer for later use u8 *out_buf = (u8 *) hcmalloc (HCBUFSIZ_LARGE); potfile_ctx->out_buf = out_buf; // we need two buffers in parallel u8 *tmp_buf = (u8 *) hcmalloc (HCBUFSIZ_LARGE); potfile_ctx->tmp_buf = tmp_buf; // old potfile detection if (user_options->potfile_path == NULL) { char *potfile_old; hc_asprintf (&potfile_old, "%s/hashcat.pot", folder_config->profile_dir); if (hc_path_exist (potfile_old) == true) { event_log_warning (hashcat_ctx, "Old potfile detected: %s", potfile_old); event_log_warning (hashcat_ctx, "New potfile is: %s ", potfile_ctx->filename); event_log_warning (hashcat_ctx, NULL); } hcfree (potfile_old); } return 0; }
int potfile_remove_parse (hashcat_ctx_t *hashcat_ctx) { const hashconfig_t *hashconfig = hashcat_ctx->hashconfig; const hashes_t *hashes = hashcat_ctx->hashes; const potfile_ctx_t *potfile_ctx = hashcat_ctx->potfile_ctx; if (potfile_ctx->enabled == false) return 0; // if no potfile exists yet we don't need to do anything here if (hc_path_exist (potfile_ctx->filename) == false) return 0; hash_t *hashes_buf = hashes->hashes_buf; u32 hashes_cnt = hashes->hashes_cnt; // no solution for these special hash types (for instane because they use hashfile in output etc) if (hashconfig->hash_mode == 5200) return 0; if ((hashconfig->hash_mode >= 6200) && (hashconfig->hash_mode <= 6299)) return 0; if (hashconfig->hash_mode == 9000) return 0; if ((hashconfig->hash_mode >= 13700) && (hashconfig->hash_mode <= 13799)) return 0; if (hashconfig->hash_mode == 14600) return 0; hash_t hash_buf; hash_buf.digest = hcmalloc (hashconfig->dgst_size); hash_buf.salt = NULL; hash_buf.esalt = NULL; hash_buf.hook_salt = NULL; hash_buf.hash_info = NULL; hash_buf.cracked = 0; if (hashconfig->is_salted == true) { hash_buf.salt = (salt_t *) hcmalloc (sizeof (salt_t)); } if (hashconfig->esalt_size > 0) { hash_buf.esalt = hcmalloc (hashconfig->esalt_size); } if (hashconfig->hook_salt_size > 0) { hash_buf.hook_salt = hcmalloc (hashconfig->hook_salt_size); } // we only need this variable in a very specific situation: // whenever we use --username and --show together we want to keep all hashes sorted within a nice structure pot_tree_entry_t *all_hashes_tree = NULL; pot_tree_entry_t *tree_entry_cache = NULL; pot_hash_node_t *tree_nodes_cache = NULL; if (potfile_ctx->keep_all_hashes == true) { // we need *at most* one entry for every hash // (if there are no hashes with the same keys (hash + salt), a counter example would be: same hash but different user name) tree_entry_cache = (pot_tree_entry_t *) hccalloc (hashes_cnt, sizeof (pot_tree_entry_t)); // we need *always exactly* one linked list for every hash tree_nodes_cache = (pot_hash_node_t *) hccalloc (hashes_cnt, sizeof (pot_hash_node_t)); for (u32 hash_pos = 0; hash_pos < hashes_cnt; hash_pos++) { // initialize the linked list node: // we always need to create a new one and add it, because we want to keep and later update all hashes: pot_hash_node_t *new_node = &tree_nodes_cache[hash_pos]; new_node->hash_buf = &hashes_buf[hash_pos]; new_node->next = NULL; // initialize the entry: pot_tree_entry_t *new_entry = &tree_entry_cache[hash_pos]; // note: the "key" (hash + salt) is indirectly accessible via the first nodes "hash_buf" new_entry->nodes = new_node; // the hashconfig is needed here because we need to be able to check within the sort function if we also need // to sort by salt and we also need to have the correct order of dgst_pos0...dgst_pos3: new_entry->hashconfig = (hashconfig_t *) hashconfig; // "const hashconfig_t" gives a warning // the following function searches if the "key" is already present and if not inserts the new entry: void **found = tsearch (new_entry, (void **) &all_hashes_tree, sort_pot_tree_by_hash); pot_tree_entry_t *found_entry = (pot_tree_entry_t *) *found; // we now need to check these cases; tsearch () could return: // 1. NULL : if we have a memory allocation problem (not enough memory for the tree structure) // 2. found_entry == new_entry: if we successfully insert a new key (which was not present yet) // 3. found_entry != new_entry: if the key was already present // case 1: memory allocation error if (found_entry == NULL) { fprintf (stderr, "Error while allocating memory for the potfile search: %s\n", MSG_ENOMEM); return -1; } // case 2: this means it was a new insert (and the insert was successful) if (found_entry == new_entry) { // no updates to the linked list required (since it is the first one!) } // case 3: if we have found an already existing entry else { new_node->next = found_entry->nodes; } // we always insert the new node at the very beginning // (or in other words: the head of the linked list always points to *this* new inserted node) found_entry->nodes = new_node; } } // special case for a split hash if (hashconfig->hash_mode == 3000) { int parser_status = hashconfig->parse_func ((u8 *) LM_ZERO_HASH, 16, &hash_buf, hashconfig); if (parser_status == PARSER_OK) { if (potfile_ctx->keep_all_hashes == true) { potfile_update_hashes (hashcat_ctx, &hash_buf, NULL, 0, all_hashes_tree); } else { hash_t *found = (hash_t *) hc_bsearch_r (&hash_buf, hashes_buf, hashes_cnt, sizeof (hash_t), sort_by_hash_no_salt, (void *) hashconfig); potfile_update_hash (hashcat_ctx, found, NULL, 0); } } } const int rc = potfile_read_open (hashcat_ctx); if (rc == -1) return -1; char *line_buf = (char *) hcmalloc (HCBUFSIZ_LARGE); while (!feof (potfile_ctx->fp)) { int line_len = fgetl (potfile_ctx->fp, line_buf); if (line_len == 0) continue; char *last_separator = strrchr (line_buf, hashconfig->separator); if (last_separator == NULL) continue; // ?? char *line_pw_buf = last_separator + 1; int line_pw_len = line_buf + line_len - line_pw_buf; char *line_hash_buf = line_buf; int line_hash_len = last_separator - line_buf; line_hash_buf[line_hash_len] = 0; if (line_hash_len == 0) continue; if (hashconfig->is_salted == true) { memset (hash_buf.salt, 0, sizeof (salt_t)); } if (hashconfig->esalt_size > 0) { memset (hash_buf.esalt, 0, hashconfig->esalt_size); } if (hashconfig->hook_salt_size > 0) { memset (hash_buf.hook_salt, 0, hashconfig->hook_salt_size); } hash_t *found = NULL; if (hashconfig->hash_mode == 6800) { if (line_hash_len < 256) // 64 = 64 * u32 in salt_buf[] { // manipulate salt_buf memcpy (hash_buf.salt->salt_buf, line_hash_buf, line_hash_len); hash_buf.salt->salt_len = line_hash_len; found = (hash_t *) bsearch (&hash_buf, hashes_buf, hashes_cnt, sizeof (hash_t), sort_by_hash_t_salt); } } else if ((hashconfig->hash_mode == 2500) || (hashconfig->hash_mode == 2501)) { // here we have in line_hash_buf: hash:macap:macsta:essid:password char *sep_pos = strrchr (line_hash_buf, ':'); if (sep_pos == NULL) continue; sep_pos[0] = 0; char *hash_pos = line_hash_buf; const size_t hash_len = strlen (hash_pos); if (hash_len != 32 + 1 + 12 + 1 + 12) continue; char *essid_pos = sep_pos + 1; int essid_len = (int) strlen (essid_pos); if (is_hexify ((const u8 *) essid_pos, (const int) essid_len) == true) { essid_len = exec_unhexify ((const u8 *) essid_pos, essid_len, (u8 *) essid_pos, essid_len); } if (essid_len > 32) continue; if (hashconfig->is_salted == true) { // this should be always true, but we need it to make scan-build happy memcpy (hash_buf.salt->salt_buf, essid_pos, essid_len); hash_buf.salt->salt_len = essid_len; hash_buf.salt->salt_iter = ROUNDS_WPA - 1; u32 hash[4]; hash[0] = hex_to_u32 ((const u8 *) &hash_pos[ 0]); hash[1] = hex_to_u32 ((const u8 *) &hash_pos[ 8]); hash[2] = hex_to_u32 ((const u8 *) &hash_pos[16]); hash[3] = hex_to_u32 ((const u8 *) &hash_pos[24]); hash[0] = byte_swap_32 (hash[0]); hash[1] = byte_swap_32 (hash[1]); hash[2] = byte_swap_32 (hash[2]); hash[3] = byte_swap_32 (hash[3]); u32 *digest = (u32 *) hash_buf.digest; digest[0] = hash[0]; digest[1] = hash[1]; digest[2] = hash[2]; digest[3] = hash[3]; } found = (hash_t *) hc_bsearch_r (&hash_buf, hashes_buf, hashes_cnt, sizeof (hash_t), sort_by_hash, (void *) hashconfig); } else { int parser_status = hashconfig->parse_func ((u8 *) line_hash_buf, line_hash_len, &hash_buf, hashconfig); if (parser_status != PARSER_OK) continue; if (potfile_ctx->keep_all_hashes == true) { potfile_update_hashes (hashcat_ctx, &hash_buf, line_pw_buf, line_pw_len, all_hashes_tree); continue; } found = (hash_t *) hc_bsearch_r (&hash_buf, hashes_buf, hashes_cnt, sizeof (hash_t), sort_by_hash, (void *) hashconfig); } potfile_update_hash (hashcat_ctx, found, line_pw_buf, line_pw_len); } hcfree (line_buf); potfile_read_close (hashcat_ctx); if (potfile_ctx->keep_all_hashes == true) { pot_tree_destroy (all_hashes_tree); // this could be slow (should we just skip it?) hcfree (tree_nodes_cache); hcfree (tree_entry_cache); } if (hashconfig->esalt_size > 0) { hcfree (hash_buf.esalt); } if (hashconfig->hook_salt_size > 0) { hcfree (hash_buf.hook_salt); } if (hashconfig->is_salted == true) { hcfree (hash_buf.salt); } hcfree (hash_buf.digest); return 0; }
int module_hash_binary_parse (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra, hashes_t *hashes) { // note: if module_hash_binary_parse exists, then module_hash_decode is not called FILE *fp = fopen (hashes->hashfile, "rb"); if (fp == NULL) return (PARSER_HASH_FILE); #define TC_HEADER_SIZE 512 char *in = (char *) hcmalloc (TC_HEADER_SIZE); const size_t n = hc_fread (in, 1, TC_HEADER_SIZE, fp); fclose (fp); if (n != TC_HEADER_SIZE) return (PARSER_TC_FILE_SIZE); hash_t *hashes_buf = hashes->hashes_buf; hash_t *hash = &hashes_buf[0]; const int parser_status = module_hash_decode (hashconfig, hash->digest, hash->salt, hash->esalt, hash->hook_salt, hash->hash_info, in, TC_HEADER_SIZE); if (parser_status != PARSER_OK) return 0; hcfree (in); // keyfiles tc_t *tc = (tc_t *) hash->esalt; if (user_options->truecrypt_keyfiles) { char *keyfiles = hcstrdup (user_options->truecrypt_keyfiles); char *saveptr = NULL; char *keyfile = strtok_r (keyfiles, ",", &saveptr); while (keyfile) { if (hc_path_read (keyfile)) { cpu_crc32 (keyfile, (u8 *) tc->keyfile_buf); } keyfile = strtok_r ((char *) NULL, ",", &saveptr); } free (keyfiles); } // keyboard layout mapping if (user_options->keyboard_layout_mapping) { if (hc_path_read (user_options->keyboard_layout_mapping)) { initialize_keyboard_layout_mapping (user_options->keyboard_layout_mapping, tc->keyboard_layout_mapping_buf, &tc->keyboard_layout_mapping_cnt); } } return 1; }