This document describes the architecture of the Brute Force Unpackage tool after the Version 2.0 refactoring. The new architecture emphasizes modularity, extensibility, and performance through design patterns and multiprocessing.
- Separation of Concerns: Different responsibilities are isolated into dedicated modules
- Strategy Pattern: Archive formats are handled by interchangeable handler classes
- Template Method: Common attack logic is defined in base classes
- Factory Pattern: Handlers are created based on file type
- DRY (Don't Repeat Yourself): Eliminated code duplication through inheritance and composition
src/
├── core/ # Core framework components
│ ├── base_attacker.py # Abstract base class for all attacks
│ ├── archive_handlers.py # Archive format handlers (Strategy pattern)
│ └── multiprocess_attacker.py # Multiprocessing implementation
│
├── attackers/ # Attack mode implementations
│ ├── dictionary_attacker.py # Dictionary-based attacks
│ └── bruteforce_attacker.py # Brute-force attacks
│
├── dic_unpack/ # Legacy code (deprecated)
└── rnd_unpack/ # Legacy code (deprecated)
Purpose: Provides the abstract base class and common functionality for all attack modes.
Key Features:
- Abstract
generate_passwords()method for subclasses to implement - Common
attack()method with progress tracking - Consistent interface for all attack types
Design Pattern: Template Method Pattern
class BaseAttacker(ABC):
@abstractmethod
def generate_passwords(self) -> List[str]:
"""Subclasses must implement password generation"""
pass
def attack(self, file_path, archive_handler, password_candidates):
"""Common attack logic with progress tracking"""
# Attempts each password with progress bar
# Returns found password or NonePurpose: Encapsulate archive format-specific extraction logic.
Key Features:
- Abstract
ArchiveHandlerbase class - Concrete implementations:
RARHandler,ZIPHandler,SevenZHandler - Factory function
get_handler_for_file()for automatic handler selection - Consistent
try_extract()interface
Design Pattern: Strategy Pattern + Factory Pattern
class ArchiveHandler(ABC):
@abstractmethod
def try_extract(self, file_path: str, password: str) -> bool:
"""Attempt extraction with given password"""
pass
def get_handler_for_file(file_path: str) -> ArchiveHandler:
"""Factory function to create appropriate handler"""
# Returns RARHandler, ZIPHandler, or SevenZHandler based on extensionBenefits:
- Easy to add new archive formats
- Eliminates duplicate code across attack modes
- Testable in isolation
Purpose: Implements true parallelism to bypass Python's GIL.
Key Features:
- Automatic password distribution across processes
- Inter-process communication via
multiprocessing.Queue - Progress tracking across all workers
- Graceful termination when password is found
Architecture:
Main Process
├── Split passwords into N chunks (N = CPU cores)
├── Create N worker processes
├── Monitor results via Queue
└── Terminate all workers when password found
Worker Process 1
└── Test passwords from chunk 1
Worker Process 2
└── Test passwords from chunk 2
...
Worker Process N
└── Test passwords from chunk N
Why Multiprocessing vs Threading?
Python's Global Interpreter Lock (GIL) prevents multiple threads from executing Python code simultaneously. This makes threading ineffective for CPU-intensive tasks like password cracking.
Multiprocessing creates separate Python interpreter processes, each with its own GIL, enabling true parallel execution on multiple CPU cores.
Performance Impact:
- 1 process: 100% utilization of 1 core
- 4 processes: ~400% total CPU utilization (4 cores)
- 8 processes: ~800% total CPU utilization (8 cores)
Purpose: Implements dictionary-based password attacks.
Key Features:
- Loads passwords from text files recursively
- Deduplicates passwords using sets
- Supports both single-process and multiprocess modes
- Memory-efficient loading with error handling
Process Flow:
Initialize
└── Load dictionaries from path
├── Walk directory tree
├── Read all .txt files
├── Deduplicate passwords
└── Store in memory
Attack
├── Get archive handler
├── Choose single-process or multiprocess
└── Attempt all passwords
└── Return found password or None
Purpose: Implements brute-force attacks with configurable character sets.
Key Features:
- Customizable character sets (uppercase, lowercase, digits, symbols)
- Incremental length testing (1 to max_length)
- Efficient password generation using
itertools.product - Warning system for large search spaces
Process Flow:
Initialize
├── Build character set from options
├── Calculate total combinations
└── Display warnings if needed
Attack
└── For each length from 1 to max_length:
├── Generate all passwords of that length
├── Attempt passwords (single or multiprocess)
└── Return if password found
Complexity Analysis:
For character set size C and max length L:
- Total combinations:
C^1 + C^2 + ... + C^L - Examples:
- lowercase (26 chars), length 6: ~309 million combinations
- lowercase + digits (36 chars), length 6: ~2.2 billion combinations
- all chars (95 chars), length 6: ~735 billion combinations
User Input (main.py)
↓
Parse Arguments
↓
Validate File
↓
Get Archive Handler (factory)
↓
Create Dictionary Attacker
↓
Load Dictionaries
↓
Choose Mode:
├── Single Process → BaseAttacker.attack()
└── Multiprocess → MultiprocessAttacker.attack()
├── Split passwords
├── Create workers
├── Distribute work
└── Collect results
↓
Found Password?
├── Yes → Display success
└── No → Display failure
User Input (main.py)
↓
Parse Arguments
↓
Validate File
↓
Get Archive Handler (factory)
↓
Create Brute-force Attacker
├── Build character set
└── Calculate combinations
↓
For length = 1 to max_length:
├── Generate passwords
├── Choose Mode:
│ ├── Single Process → BaseAttacker.attack()
│ └── Multiprocess → MultiprocessAttacker.attack()
└── Password found?
├── Yes → Return and exit
└── No → Continue to next length
Before (v1.0):
attack_rar(),attack_zip(),attack_7z()repeated in bothDicUnpackandRndUnpack- 6 nearly-identical methods with only handler differences
After (v2.0):
- Single
attack()method inBaseAttacker - Archive-specific logic in handler classes
- ~70% code reduction
Before (v1.0):
- Thread module existed but was empty
- No parallel execution capability
- Single-threaded only
After (v2.0):
- Full multiprocessing implementation
- Automatic CPU core detection
- Configurable process count
- ~4-8x performance improvement on multi-core systems
Before (v1.0):
- Monolithic classes with mixed responsibilities
- Tight coupling between attack modes and formats
- Singleton pattern misuse
After (v2.0):
- Clean separation of concerns
- Strategy pattern for extensibility
- Loosely coupled components
- Easy to test and maintain
Before (v1.0):
- Generic exception catching
- Silent failures
- No validation
After (v2.0):
- Specific exception types
- Input validation
- Informative error messages
- Graceful degradation
Before (v1.0):
- Minimal feedback
- Typos in parameters (
simbol,brust) - No usage examples
After (v2.0):
- Detailed progress tracking
- Fixed parameter names
- Comprehensive help text
- Usage examples in README
- Create new handler class in
archive_handlers.py:
class NewFormatHandler(ArchiveHandler):
def try_extract(self, file_path: str, password: str) -> bool:
# Implement extraction logic
pass
def get_format_name(self) -> str:
return "NEW_FORMAT"- Register in factory function:
def get_handler_for_file(file_path: str) -> ArchiveHandler:
handlers = {
'.rar': RARHandler(),
'.zip': ZIPHandler(),
'.7z': SevenZHandler(),
'.new': NewFormatHandler(), # Add new handler
}
# ...- Create new attacker class inheriting from
BaseAttacker:
class NewAttacker(BaseAttacker):
def generate_passwords(self) -> List[str]:
# Implement password generation logic
pass
def attack_file(self, file_path, archive_handler, ...):
# Implement attack logic
pass- Integrate in
main.py:
if args.new_mode:
attacker = NewAttacker(...)
found_password = attacker.attack_file(...)The multiprocessing implementation distributes passwords evenly across workers:
chunk_size = ceil(total_passwords / num_processes)This ensures balanced workload and maximum CPU utilization.
When any worker finds the password:
queue.put(('found', password, worker_id))
# Main process terminates all workers immediately
for p in processes:
if p.is_alive():
p.terminate()This prevents wasted computation.
- Dictionary attacker loads all passwords once (shared read-only data)
- Brute-force attacker generates passwords incrementally by length
- Temporary directory usage prevents disk clutter
Uses tqdm for real-time feedback without performance overhead:
tbar = tqdm(passwords, desc="Attempting passwords")
for password in tbar:
tbar.set_description(f'Trying: {password}')- Tests password strength of YOUR archives
- Educational demonstration of brute-force attacks
- Security research and testing
- Unauthorized access to others' files
- Illegal activities
- Bypassing security without permission
- Requires explicit file path (no auto-discovery)
- No stealth mode or evasion techniques
- Comprehensive logging of all attempts
- Educational focus in documentation
# Test archive handlers
def test_zip_handler():
handler = ZIPHandler()
assert handler.get_format_name() == "ZIP"
# Test password generation
def test_bruteforce_generator():
attacker = BruteforceAttacker(include_lowercase=True, max_length=2)
passwords = attacker.generate_passwords_of_length(2)
assert len(passwords) == 26 * 26
# Test multiprocessing
def test_password_splitting():
mp = MultiprocessAttacker(num_processes=4)
chunks = mp.split_passwords(list(range(100)))
assert len(chunks) == 4
assert all(len(chunk) == 25 for chunk in chunks)Use test_new_features.py to verify:
- Handler creation
- Dictionary loading
- Password generation
- Multiprocessing initialization
Use test archives in origin_file/ with known passwords.
-
UnRAR library not found
- Solution: Install libunrar and set UNRAR_LIB_PATH
-
Out of memory
- Solution: Reduce process count or max-length
-
Very slow performance
- Solution: Reduce character set or max-length
-
Process hangs
- Solution: Use Ctrl+C to interrupt gracefully
Potential improvements for future versions:
- GPU Acceleration: Use CUDA/OpenCL for massive parallelism
- Distributed Computing: Spread work across multiple machines
- Smart Dictionary: Learn from successful passwords
- Resume Capability: Save progress and resume later
- Hybrid Attacks: Combine dictionary with mutations/rules
- Cloud Integration: Use cloud computing for large searches
- GUI Interface: Desktop application with visual progress
- Password Analytics: Statistics on common patterns
The Version 2.0 architecture provides a solid foundation for password cracking with:
✓ Clean, maintainable code structure ✓ True parallel processing capability ✓ Extensible design for new formats/modes ✓ Comprehensive documentation ✓ Professional error handling ✓ Optimized performance
The refactoring transformed a basic script into a robust, production-ready tool while maintaining simplicity and usability.