From 310e9ee79a75738c6cd4723d88f367170afed10f Mon Sep 17 00:00:00 2001 From: Chick3nman Date: Fri, 30 May 2025 14:13:43 -0500 Subject: [PATCH] Add --total-candidates flag and functionality --- docs/changes.txt | 1 + include/types.h | 4 ++++ src/hashcat.c | 1 + src/main.c | 13 +++++++++++++ src/terminal.c | 13 +++++++------ src/usage.c | 1 + src/user_options.c | 20 ++++++++++++++++++++ 7 files changed, 47 insertions(+), 6 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 8521d5591..c7ed132a2 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -66,6 +66,7 @@ - Added new feature (-Y) that creates N virtual instances for each device in your system at the cost of N times the device memory consumption - Added options --benchmark-min and --benchmark-max to set a hash-mode range to be used during the benchmark +- Added option --total-candidates to provide the total candidate count for an attack insteda of the internal "--keyspace" value ## ## Performance diff --git a/include/types.h b/include/types.h index 880af23ee..f6f82c992 100644 --- a/include/types.h +++ b/include/types.h @@ -107,6 +107,7 @@ typedef enum event_identifier EVENT_BITMAP_INIT_PRE = 0x00000011, EVENT_BITMAP_FINAL_OVERFLOW = 0x00000012, EVENT_CALCULATED_WORDS_BASE = 0x00000020, + EVENT_CALCULATED_WORDS_CNT = 0x00000021, EVENT_CRACKER_FINISHED = 0x00000030, EVENT_CRACKER_HASH_CRACKED = 0x00000031, EVENT_CRACKER_STARTING = 0x00000032, @@ -666,6 +667,7 @@ typedef enum user_options_defaults KERNEL_LOOPS = 0, KERNEL_THREADS = 0, KEYSPACE = false, + TOTAL_CANDIDATES = false, LEFT = false, LIMIT = 0, LOGFILE = true, @@ -843,6 +845,7 @@ typedef enum user_options_map IDX_STATUS_TIMER = 0xff4c, IDX_STDOUT_FLAG = 0xff4d, IDX_STDIN_TIMEOUT_ABORT = 0xff4e, + IDX_TOTAL_CANDIDATES = 0xff58, IDX_TRUECRYPT_KEYFILES = 0xff4f, IDX_USERNAME = 0xff50, IDX_VERACRYPT_KEYFILES = 0xff51, @@ -2357,6 +2360,7 @@ typedef struct user_options bool increment; bool keep_guessing; bool keyspace; + bool total_candidates; bool left; bool logfile; bool loopback; diff --git a/src/hashcat.c b/src/hashcat.c index e1607450c..a691d45aa 100644 --- a/src/hashcat.c +++ b/src/hashcat.c @@ -131,6 +131,7 @@ static int inner2_loop (hashcat_ctx_t *hashcat_ctx) status_ctx->words_base = status_ctx->words_cnt / amplifier_cnt; EVENT (EVENT_CALCULATED_WORDS_BASE); + EVENT (EVENT_CALCULATED_WORDS_CNT); if (user_options->keyspace == true) { diff --git a/src/main.c b/src/main.c index 085ce38b4..6d21cf92f 100644 --- a/src/main.c +++ b/src/main.c @@ -370,10 +370,22 @@ static void main_calculated_words_base (MAYBE_UNUSED hashcat_ctx_t *hashcat_ctx, const user_options_t *user_options = hashcat_ctx->user_options; if (user_options->keyspace == false) return; + if (user_options->total_candidates == true) return; event_log_info (hashcat_ctx, "%" PRIu64 "", status_ctx->words_base); } +static void main_calculated_words_cnt (MAYBE_UNUSED hashcat_ctx_t *hashcat_ctx, MAYBE_UNUSED const void *buf, MAYBE_UNUSED const size_t len) +{ + const status_ctx_t *status_ctx = hashcat_ctx->status_ctx; + const user_options_t *user_options = hashcat_ctx->user_options; + + if (user_options->keyspace == false) return; + if (user_options->total_candidates == false) return; + + event_log_info (hashcat_ctx, "%" PRIu64 "", status_ctx->words_cnt); +} + static void main_potfile_remove_parse_pre (MAYBE_UNUSED hashcat_ctx_t *hashcat_ctx, MAYBE_UNUSED const void *buf, MAYBE_UNUSED const size_t len) { const user_options_t *user_options = hashcat_ctx->user_options; @@ -1171,6 +1183,7 @@ static void event (const u32 id, hashcat_ctx_t *hashcat_ctx, const void *buf, co case EVENT_BITMAP_INIT_PRE: main_bitmap_init_pre (hashcat_ctx, buf, len); break; case EVENT_BITMAP_FINAL_OVERFLOW: main_bitmap_final_overflow (hashcat_ctx, buf, len); break; case EVENT_CALCULATED_WORDS_BASE: main_calculated_words_base (hashcat_ctx, buf, len); break; + case EVENT_CALCULATED_WORDS_CNT: main_calculated_words_cnt (hashcat_ctx, buf, len); break; case EVENT_CRACKER_FINISHED: main_cracker_finished (hashcat_ctx, buf, len); break; case EVENT_CRACKER_HASH_CRACKED: main_cracker_hash_cracked (hashcat_ctx, buf, len); break; case EVENT_CRACKER_STARTING: main_cracker_starting (hashcat_ctx, buf, len); break; diff --git a/src/terminal.c b/src/terminal.c index d87faed19..5afbf5735 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -28,12 +28,13 @@ void welcome_screen (hashcat_ctx_t *hashcat_ctx, const char *version_tag) { const user_options_t *user_options = hashcat_ctx->user_options; - if (user_options->quiet == true) return; - if (user_options->keyspace == true) return; - if (user_options->stdout_flag == true) return; - if (user_options->show == true) return; - if (user_options->left == true) return; - if (user_options->identify == true) return; + if (user_options->quiet == true) return; + if (user_options->keyspace == true) return; + if (user_options->total_candidates == true) return; + if (user_options->stdout_flag == true) return; + if (user_options->show == true) return; + if (user_options->left == true) return; + if (user_options->identify == true) return; if (user_options->usage > 0) { diff --git a/src/usage.c b/src/usage.c index 870c790d0..612c34c04 100644 --- a/src/usage.c +++ b/src/usage.c @@ -120,6 +120,7 @@ static const char *const USAGE_BIG_PRE_HASHMODES[] = " -s, --skip | Num | Skip X words from the start | -s 1000000", " -l, --limit | Num | Limit X words from the start + skipped words | -l 1000000", " --keyspace | | Show keyspace base:mod values and quit |", + " --total-candidates | | Show total candidate count (base*mod) and quit |", " -j, --rule-left | Rule | Single rule applied to each word from left wordlist | -j 'c'", " -k, --rule-right | Rule | Single rule applied to each word from right wordlist | -k '^-'", " -r, --rules-file | File | Multiple rules applied to each word from wordlists | -r rules/best64.rule", diff --git a/src/user_options.c b/src/user_options.c index 2adfc7ac2..8c0adeeb1 100644 --- a/src/user_options.c +++ b/src/user_options.c @@ -87,6 +87,7 @@ static const struct option long_options[] = {"kernel-threads", required_argument, NULL, IDX_KERNEL_THREADS}, {"keyboard-layout-mapping", required_argument, NULL, IDX_KEYBOARD_LAYOUT_MAPPING}, {"keyspace", no_argument, NULL, IDX_KEYSPACE}, + {"total-candidates", no_argument, NULL, IDX_TOTAL_CANDIDATES}, {"left", no_argument, NULL, IDX_LEFT}, {"limit", required_argument, NULL, IDX_LIMIT}, {"logfile-disable", no_argument, NULL, IDX_LOGFILE_DISABLE}, @@ -234,6 +235,7 @@ int user_options_init (hashcat_ctx_t *hashcat_ctx) user_options->kernel_threads = KERNEL_THREADS; user_options->keyboard_layout_mapping = NULL; user_options->keyspace = KEYSPACE; + user_options->total_candidates = TOTAL_CANDIDATES; user_options->left = LEFT; user_options->limit = LIMIT; user_options->logfile = LOGFILE; @@ -430,6 +432,7 @@ int user_options_getopt (hashcat_ctx_t *hashcat_ctx, int argc, char **argv) user_options->limit_chgd = true; break; case IDX_KEEP_GUESSING: user_options->keep_guessing = true; break; case IDX_KEYSPACE: user_options->keyspace = true; break; + case IDX_TOTAL_CANDIDATES: user_options->total_candidates = true; break; case IDX_BENCHMARK: user_options->benchmark = true; break; case IDX_BENCHMARK_ALL: user_options->benchmark_all = true; break; case IDX_BENCHMARK_MAX: user_options->benchmark_max = hc_strtoul (optarg, NULL, 10); break; @@ -1816,6 +1819,11 @@ void user_options_session_auto (hashcat_ctx_t *hashcat_ctx) user_options->session = "progress_only"; } + if (user_options->total_candidates == true) + { + user_options->session = "candidates"; + } + if (user_options->keyspace == true) { user_options->session = "keyspace"; @@ -1881,6 +1889,7 @@ void user_options_preprocess (hashcat_ctx_t *hashcat_ctx) if (user_options->hash_info == true || user_options->keyspace == true + || user_options->total_candidates == true || user_options->speed_only == true || user_options->progress_only == true || user_options->identify == true @@ -1951,6 +1960,11 @@ void user_options_preprocess (hashcat_ctx_t *hashcat_ctx) user_options->speed_only = true; } + if (user_options->total_candidates == true) + { + user_options->quiet = true; + } + if (user_options->keyspace == true) { user_options->quiet = true; @@ -1961,6 +1975,11 @@ void user_options_preprocess (hashcat_ctx_t *hashcat_ctx) user_options->backend_vector_width = 1; } + if (user_options->total_candidates == true) + { + user_options->keyspace = true; + } + if (user_options->stdout_flag == true) { user_options->force = true; @@ -3303,6 +3322,7 @@ void user_options_logger (hashcat_ctx_t *hashcat_ctx) logfile_top_uint (user_options->kernel_loops); logfile_top_uint (user_options->kernel_threads); logfile_top_uint (user_options->keyspace); + logfile_top_uint (user_options->total_candidates); logfile_top_uint (user_options->left); logfile_top_uint (user_options->logfile); logfile_top_uint (user_options->loopback);