PyProtect is a comprehensive Python code obfuscation tool with machine ID binding, designed to protect your Python applications from reverse engineering and unauthorized distribution.
- Variable Name Obfuscation: Transforms readable variable names into obfuscated identifiers
- String Encryption: Encrypts string literals using base64 encoding
- AST Transformation: Advanced Abstract Syntax Tree manipulation
- Import Protection: Secures import statements and module loading
- Hardware Fingerprinting: Generates unique machine identifiers based on CPU, MAC address, and disk serial
- License Key Generation: Creates signed license keys with expiration dates
- Runtime Verification: Validates licenses on every code execution
- Tamper Detection: Detects attempts to modify or bypass protection
- Directory Processing: Obfuscates entire Python projects recursively
- Package Structure Preservation: Maintains original project structure
- Unified Licensing: Single license file for entire projects
- Cross-Platform: Works on Linux, Windows, and macOS
- Standalone Executable: Run with
pyprotectcommand after installation - Professional CLI: Standard flag-based interface (
-i,-o,-m,-c) - Easy Installation: One-command setup with
./install.sh - System Integration: Available globally after installation
- Installation
- Quick Start
- Usage
- Command Line Options
- Examples
- Security Features
- Architecture
- Limitations
- Troubleshooting
- Contributing
- License
Choose one of the installation methods below based on your needs.
- Python 3.6 or higher (3.9+ recommended for best performance)
- pip package manager
- Git (for cloning the repository)
- sudo/admin privileges (for system-wide installation)
# Clone and install PyProtect with standalone command
git clone https://github.com/dynaz/PyProtect.git
cd PyProtect
./install.shpyprotect --help
# Should display: PyProtect - Python Obfuscator with Machine ID Binding# Clone the repository
git clone https://github.com/dynaz/PyProtect.git
cd PyProtect# Make the script executable
chmod +x pyprotect.py# Create global symlink (requires sudo)
sudo ln -sf "$(pwd)/pyprotect.py" /usr/local/bin/pyprotect
# Or add to your PATH
export PATH="$PATH:$(pwd)"# Test direct execution
./pyprotect.py --help
# Test global command (if symlink created)
pyprotect --helpgit clone https://github.com/dynaz/PyProtect.git
cd PyProtect
# Build the image
docker build -t pyprotect .
# Run PyProtect in container
docker run -v $(pwd):/workspace pyprotect --help# Pull and run
docker run -it dynaz/pyprotect --help# Clone repository
git clone https://github.com/dynaz/PyProtect.git
cd PyProtect
# Set up virtual environment
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install development dependencies
pip install -r requirements-dev.txt
# Run tests
python -m pytest tests/
# Make executable
chmod +x pyprotect.py# Install to custom location
PYPROTECT_HOME="$HOME/.local/pyprotect"
mkdir -p "$PYPROTECT_HOME"
cp -r PyProtect/* "$PYPROTECT_HOME/"
chmod +x "$PYPROTECT_HOME/pyprotect.py"
# Add to PATH in your shell profile
echo "export PATH=\"\$PATH:$PYPROTECT_HOME\"" >> ~/.bashrc
source ~/.bashrc# Copy to external drive
EXTERNAL_DRIVE="/mnt/external"
cp -r PyProtect "$EXTERNAL_DRIVE/"
cd "$EXTERNAL_DRIVE/PyProtect"
# Run directly
python3 pyprotect.py --help# Basic functionality test
pyprotect -m # Should show your machine ID
# Obfuscation test
pyprotect -i examples/demo.py # Should create /dist/demo.py
# License check test
pyprotect -c # Should scan for license files# If pyprotect command not found
which pyprotect # Check if in PATH
ls -la /usr/local/bin/pyprotect # Check symlink
# Test direct execution
./pyprotect.py --help
# Check permissions
ls -la pyprotect.pycd PyProtect
git pull origin main
./install.sh # Re-run installerpyprotect -i my_script.py --bind-machine
# Output: /dist/my_script.py (machine-bound)pyprotect -i my_project/ --bind-machine --expiration 365
# Output: /dist/my_project/ (entire project protected)# Test a protected script (after running pyprotect on it)
python3 -c "import sys; sys.path.insert(0, '.'); import my_protected_script"
# Should work on licensed machine, fail on others
# Or test the examples in this repository:
cd examples
python3 -c "import demo_bound; result = demo_bound.secret_function('super_secret_key_12345'); print('Protected script result:', result)"
# Test protected project modules:
cd protected_project
python3 -c "from models.user import User; u = User('Test', 25); print('User:', u.name)"pyprotect -i INPUT [-o OUTPUT] [OPTIONS]Note: After installation with ./install.sh, you can use pyprotect from anywhere. Alternatively, use python3 pyprotect.py if running directly.
- Single File:
script.py - Directory:
myproject/(processes all.pyfiles recursively)
- Single File:
protected.py(default:/dist/filename.py) - Directory:
protected/(default:/dist/inputname/, maintains input structure)
| Option | Description | Default |
|---|---|---|
-i, --input INPUT |
Input file or directory | Required |
-o, --output OUTPUT |
Output file or directory | /dist/ |
-m, --machine-id |
Display current machine ID | - |
-c, --check-license DIR |
Check license validity in directory | Current dir |
--bind-machine |
Bind code to current machine hardware | Disabled |
--expiration DAYS |
License expiration in days | 365 |
# Protect a single Python file (output to /dist/filename.py)
pyprotect -i sensitive_code.py
# Or specify custom output
pyprotect -i sensitive_code.py -o protected.py# Protect and bind to current machine for 1 year
pyprotect -i app.py -o app_protected.py --bind-machine --expiration 365# Protect entire Django/Flask project (output to /dist/)
pyprotect -i my_django_project/ --bind-machine
# Or specify custom output directory
pyprotect -i my_django_project/ -o protected_project/ --bind-machine# Display current machine ID for licensing
pyprotect -m
# Output: Machine ID: 0a3a756bffd5fe563cb9b9ec3e5e17fb# Check license validity in current directory
pyprotect -c
# Check license in specific directory
pyprotect -c /path/to/protected/app
# Shows: β
VALID - License valid, β
Machine ID matches# Create time-limited trial version
pyprotect -i software.py -o trial_version.py --bind-machine --expiration 30# Original
def process_data(user_input, api_key="secret123"):
secret_token = "token_abc123"
return user_input + secret_token
# Protected
def _obf_0(_obf_1, _obf_2=_decrypt_str('0')):
_obf_3 = _decrypt_str('1')
return _obf_1 + _obf_3# Original strings are base64 encoded
_STRINGS = ['c2VjcmV0MTIz', 'dG9rZW5fYWJjMTIz'] # Encrypted strings- Machine ID Generation: Combines CPU, MAC, and disk serial
- License Validation: Runtime checks ensure code only runs on authorized machines
- Expiration Control: Time-based license expiration
# Automatic license check on import
_check_license() # Validates machine and expiration-
AST Processor (
Obfuscatorclass)- Parses Python code into Abstract Syntax Tree
- Transforms variable names and string literals
- Applies obfuscation rules
-
License Manager
- Generates hardware fingerprints
- Creates signed license keys
- Validates licenses at runtime
-
Runtime Engine
- Decrypts strings on-demand
- Verifies machine authorization
- Handles tamper detection
PyProtect/
βββ pyprotect.py # Main obfuscation tool
βββ README.md # This documentation
βββ examples/ # Sample projects
β βββ basic_script.py
β βββ sample_project/
βββ tests/ # Test cases
βββ test_obfuscation.py
βββ test_licensing.py
- F-string Support: Files containing f-strings may fail (working on fix)
- Complex Metaclasses: Advanced Python patterns may need adjustment
- Dynamic Imports:
importliband dynamic imports may require special handling - Third-party Libraries: Some libraries may not work with obfuscated code
- Files with f-strings (f"{variable}") may cause parsing errors
- Very large files (>10MB) may be slow to process
- Some debugging tools may not work with obfuscated code
Cause: F-strings or advanced Python syntax not supported
Solution: Convert f-strings to .format() or string concatenation
Cause: Import paths changed after obfuscation Solution: Use absolute imports or adjust PYTHONPATH
Cause: License validation failed Solutions:
- Verify you're on the licensed machine
- Check license hasn't expired
- Regenerate license if hardware changed
Cause: Python version < 3.9 Solution: Upgrade Python or use string fallback mode
# Enable verbose output
pyprotect -i input.py -o output.py --verbose# If obfuscation fails, restore from backup
cp original_file.py obfuscated_file.py.backupWe welcome contributions! Please see our contributing guidelines:
- Fork the repository
- Create a feature branch
- Add tests for new features
- Submit a pull request
git clone https://github.com/dynaz/PyProtect
cd pyprotect
python3 -m pip install -r requirements-dev.txt
python3 -m pytest tests/- Follow PEP 8 style guidelines
- Add docstrings to all functions
- Include unit tests for new features
- Update documentation for changes
This project is licensed under the MIT License - see the LICENSE file for details.
For commercial applications requiring advanced features:
- Enterprise licensing available
- Priority support
- Custom feature development
- Professional services
- GitHub Issues: Report bugs and request features
- Discussions: Ask questions and share experiences
- Wiki: Community guides and tutorials
For enterprise deployments and custom requirements:
- Email: dynaz@mac.com
- Enterprise licensing: dynaz@mac.com
If you find PyProtect helpful, consider supporting the development:
Your support helps maintain and improve this open-source project! β
# Quick protection (output to /dist/)
pyprotect -i file.py --bind-machine
# Project protection (output to /dist/)
pyprotect -i project/ --bind-machine
# Trial version (30 days)
pyprotect -i app.py -o trial.py --bind-machine --expiration 30
# Check machine ID
pyprotect -m
# Check license status
pyprotect -c# Test protected file
python3 protected.py
# Test protected module (after creating one)
python3 -c "import my_protected_module; print('Module works!')"
# View machine ID (alternative method)
pyprotect -m
# Check license validity in current directory
pyprotect -c
# Check license in protected project
pyprotect -c /dist/base
# Test example protected scripts
cd examples
python3 -c "import demo_bound; result = demo_bound.secret_function('super_secret_key_12345'); print('Demo result:', result)"
python3 -c "import test_protected; result = test_protected.secret_function('super_secret_key_12345'); print('Test result:', result)"PyProtect - Secure your Python code with advanced obfuscation and hardware binding! πβ¨