refactor(menu): fold rule analysis into Rule File Tools, move it to 90

analyze_rules was main-menu option 91, the last survivor of the 90-block
after the Hashmob downloads moved into their respective submenus. It is
now option 5 of the Rule File Tools submenu, which itself moves from main
menu key 81 to 90.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Justin Bollinger
2026-07-28 22:46:40 -04:00
co-authored by Claude Fable 5
parent 9511530d2d
commit f8d0d72a82
6 changed files with 17 additions and 12 deletions
+4 -4
View File
@@ -768,10 +768,9 @@ All tests use mocked API calls, so they can run without connectivity to a Hashvi
(21) PRINCE-LING Attack
(80) Wordlist Tools
(81) Rule File Tools
(82) Notifications
(91) Analyze Hashcat Rules
(90) Rule File Tools
(94) Hashview API
(95) Analyze hashes with Pipal
(96) Export Output to Excel Format
@@ -1015,13 +1014,14 @@ A submenu of wordlist preprocessing utilities using hashcat-utils binaries. All
All binaries are in `hate_crack/hashcat-utils/bin/`.
#### Rule File Tools (option 81)
#### Rule File Tools (option 90)
Preprocesses hashcat rule files using `cleanup-rules.bin` and `rules_optimize.bin` from hashcat-utils, and downloads rule files from Hashmob.net.
* **Clean** (1) - removes invalid syntax and duplicate rules using `cleanup-rules.bin`. Useful after combining rule files or downloading rules from external sources.
* **Optimize** (2) - consolidates redundant operations using `rules_optimize.bin`. Reduces rule file size and improves cracking speed.
* **Clean and optimize** (3) - runs both operations in sequence via a temporary file, then writes the final result.
* **Download rules from Hashmob.net** (4) - fetches rule files into the configured `rulesDirectory`.
* **Analyze Hashcat rules** (5) - opcode frequency analysis of a rule file, powered by HashcatRosetta.
The three preprocessing operations read from an input file and write to a separate output file (original is never modified).
@@ -1033,7 +1033,7 @@ Downloads the latest rule files from Hashmob.net's rule repository. These rules
* Reports download summary with success/failure counts
* Stores rules in the configured rules directory
#### Analyze Hashcat Rules
#### Analyze Hashcat Rules (Rule File Tools option 5)
Powered by HashcatRosetta (https://github.com/bandrel/HashcatRosetta), this feature analyzes hashcat rule files to provide detailed insights into rule composition and complexity.
* Prompts for a rule file path
+1 -2
View File
@@ -96,9 +96,8 @@ def get_main_menu_options():
"20": _attacks.pcfg_attack,
"21": _attacks.prince_ling_attack,
"80": _attacks.wordlist_tools_submenu,
"81": _attacks.rule_tools_submenu,
"82": notifications_submenu,
"91": analyze_rules,
"90": _attacks.rule_tools_submenu,
"95": pipal,
"96": export_excel,
"97": show_results,
+3
View File
@@ -1134,6 +1134,7 @@ def rule_tools_submenu(ctx: Any) -> None:
("2", "Optimize rule file (consolidate redundant operations)"),
("3", "Clean and optimize rule file (both)"),
("4", "Download rules from Hashmob.net"),
("5", "Analyze Hashcat rules (opcode statistics)"),
("99", "Back to Main Menu"),
]
while True:
@@ -1148,6 +1149,8 @@ def rule_tools_submenu(ctx: Any) -> None:
rule_cleanup_and_optimize_handler(ctx)
elif choice == "4":
download_hashmob_rules(print_fn=print, rules_dir=ctx.rulesDirectory)
elif choice == "5":
ctx.analyze_rules()
def wordlist_filter_length(ctx: Any) -> None:
+2 -4
View File
@@ -4738,9 +4738,8 @@ def get_main_menu_items():
("20", "PCFG Attack"),
("21", "PRINCE-LING Attack"),
("80", "Wordlist Tools"),
("81", "Rule File Tools"),
("82", "Notifications"),
("91", "Analyze Hashcat Rules"),
("90", "Rule File Tools"),
]
if hashview_api_key:
items.append(("94", "Hashview API"))
@@ -4781,9 +4780,8 @@ def get_main_menu_options():
"20": pcfg_attack,
"21": prince_ling_attack,
"80": wordlist_tools_submenu,
"81": rule_tools_submenu,
"82": notifications_submenu,
"91": analyze_rules,
"90": rule_tools_submenu,
"95": pipal,
"96": export_excel,
"97": show_results,
+6
View File
@@ -246,6 +246,12 @@ class TestRuleToolsSubmenu:
print_fn=print, rules_dir=ctx.rulesDirectory
)
def test_dispatches_to_analyze_rules(self):
ctx = _make_ctx()
with patch("hate_crack.menu.interactive_menu", side_effect=["5", "99"]):
rule_tools_submenu(ctx)
ctx.analyze_rules.assert_called_once_with()
def test_exits_on_99(self):
ctx = _make_ctx()
with patch("hate_crack.menu.interactive_menu", return_value="99"):
+1 -2
View File
@@ -33,9 +33,8 @@ MENU_OPTION_TEST_CASES = [
("20", CLI_MODULE._attacks, "pcfg_attack", "pcfg"),
("21", CLI_MODULE._attacks, "prince_ling_attack", "prince-ling"),
("80", CLI_MODULE._attacks, "wordlist_tools_submenu", "wordlist-tools"),
("81", CLI_MODULE._attacks, "rule_tools_submenu", "rule-tools"),
("82", CLI_MODULE, "notifications_submenu", "notifications-submenu"),
("91", CLI_MODULE, "analyze_rules", "analyze-rules"),
("90", CLI_MODULE._attacks, "rule_tools_submenu", "rule-tools"),
("95", CLI_MODULE, "pipal", "pipal"),
("96", CLI_MODULE, "export_excel", "export-excel"),
("97", CLI_MODULE, "show_results", "show-results"),