Advanced Python code obfuscator with machine ID binding
Project description
PyProtect - Advanced Python Code Obfuscator
PyProtect is a comprehensive Python code obfuscation tool with machine ID binding, designed to protect your Python applications from reverse engineering and unauthorized distribution.
๐ Features
Core Obfuscation
- 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
Machine Binding & Licensing
- 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
Project 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
Command Line Interface
- 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
๐ Table of Contents
- Installation
- Quick Start
- Usage
- Command Line Options
- Examples
- Security Features
- Architecture
- Limitations
- Troubleshooting
- Contributing
- License
๐ ๏ธ Installation
Choose one of the installation methods below based on your needs.
๐ Prerequisites
- 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)
๐ก Windows Users: See INSTALL_WINDOWS.md for detailed Windows-specific installation instructions and troubleshooting.
๐ Quick Install (Recommended)
One-Command Installation
Linux/macOS
# Clone and install PyProtect with standalone command
git clone https://github.com/dynaz/PyProtect.git
cd PyProtect
./install.sh
๐ก Note for Ubuntu 23.04+/Debian 12+/WSL: If you see "externally-managed-environment" error, the installer will automatically handle it. The
pyprotectcommand will work even if package installation is skipped.
Windows (PowerShell - Recommended)
# Clone and install PyProtect with standalone command
git clone https://github.com/dynaz/PyProtect.git
cd PyProtect
.\install.ps1
Windows (Command Prompt)
# Clone and install PyProtect with standalone command
git clone https://github.com/dynaz/PyProtect.git
cd PyProtect
install.bat
Verify Installation
# Linux/macOS/Windows (after restarting terminal)
pyprotect --help
# Should display: PyProtect - Python Obfuscator with Machine ID Binding
๐ฆ Manual Installation
Step 1: Download
# Clone the repository
git clone https://github.com/dynaz/PyProtect.git
cd PyProtect
Step 2: Make Executable (Linux/macOS only)
# Make the script executable
chmod +x pyprotect.py
Step 3: System Integration (Optional)
Linux/macOS
# Create global symlink (requires sudo)
sudo ln -sf "$(pwd)/pyprotect.py" /usr/local/bin/pyprotect
# Or add to your PATH
export PATH="$PATH:$(pwd)"
Windows (PowerShell - Run as Administrator)
# Create wrapper batch file
$scriptDir = Get-Location
$wrapperContent = "@echo off`npython `"$scriptDir\pyprotect.py`" %*"
$wrapperContent | Out-File -FilePath "$scriptDir\pyprotect.bat" -Encoding ASCII
# Add to user PATH
$currentPath = [Environment]::GetEnvironmentVariable("Path", "User")
[Environment]::SetEnvironmentVariable("Path", "$currentPath;$scriptDir", "User")
Windows (Command Prompt - Run as Administrator)
# Create wrapper batch file
echo @echo off > pyprotect.bat
echo python "%CD%\pyprotect.py" %%* >> pyprotect.bat
# Add to PATH (restart terminal after)
setx PATH "%PATH%;%CD%"
Step 4: Verify
# Test direct execution (Linux/macOS)
./pyprotect.py --help
# Test direct execution (Windows)
python pyprotect.py --help
# Test global command (after PATH setup and terminal restart)
pyprotect --help
๐ณ Docker Installation
Build Docker Image
git 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
Use Pre-built Image
# Pull and run
docker run -it dynaz/pyprotect --help
๐งช Development Installation
For Contributors
Linux/macOS
# Clone repository
git clone https://github.com/dynaz/PyProtect.git
cd PyProtect
# Set up virtual environment
python3 -m venv venv
source venv/bin/activate
# Install development dependencies
pip install -r requirements-dev.txt
# Run tests
python -m pytest tests/
# Make executable
chmod +x pyprotect.py
Windows (PowerShell)
# Clone repository
git clone https://github.com/dynaz/PyProtect.git
cd PyProtect
# Set up virtual environment
python -m venv venv
.\venv\Scripts\Activate.ps1
# Install development dependencies
pip install -r requirements-dev.txt
# Run tests
python -m pytest tests/
Windows (Command Prompt)
# Clone repository
git clone https://github.com/dynaz/PyProtect.git
cd PyProtect
# Set up virtual environment
python -m venv venv
venv\Scripts\activate.bat
# Install development dependencies
pip install -r requirements-dev.txt
# Run tests
python -m pytest tests/
๐ง Advanced Installation
Custom Installation Path
# 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
Portable Installation (USB/External Drive)
# Copy to external drive
EXTERNAL_DRIVE="/mnt/external"
cp -r PyProtect "$EXTERNAL_DRIVE/"
cd "$EXTERNAL_DRIVE/PyProtect"
# Run directly
python3 pyprotect.py --help
โ Post-Installation
Test Your Installation
# 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
Troubleshooting Installation
"pyprotect command not found"
# Check if in PATH
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.py
"externally-managed-environment" Error (Ubuntu/Debian/WSL)
Status: โ HANDLED - The installer now automatically handles this!
If you see this error on Ubuntu 23.04+, Debian 12+, or WSL:
error: externally-managed-environment
What happens: The installer will:
- โ
Automatically try with
--break-system-packagesflag - โ If that fails, skip package installation (symlink still works!)
- โ
The
pyprotectcommand will work even without package installation
Manual alternatives (if needed):
# Option 1: Use pipx (recommended for applications)
sudo apt install pipx
pipx install -e .
# Option 2: Use virtual environment
python3 -m venv venv
source venv/bin/activate
pip install -e .
# Option 3: Skip package install (symlink is sufficient)
# The symlink created by install.sh is enough to use 'pyprotect' command
Upgrade PyProtect
cd PyProtect
git pull origin main
./install.sh # Re-run installer
๐ Quick Start
โ NEW: PyProtect now supports Odoo and framework obfuscation! Public API names (functions and classes that don't start with
_) are automatically preserved, allowing cross-module imports to work correctly.
Protect a Single File
pyprotect -i my_script.py -b
# Output: /dist/my_script.py (machine-bound)
Protect an Entire Project
pyprotect -i my_project/ -b -e 365
# Output: /dist/my_project/ (entire project protected)
# Note: Only use for self-contained projects without explicit cross-module imports
Test Protection
# 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)"
๐ Usage
Basic Syntax
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.
โ Recommended Use Cases
- Odoo Addons: Custom Odoo modules and addons (โ NEW: Fully supported!)
- Django/Flask Apps: Web applications with multiple modules (โ NEW: Cross-module imports work!)
- Standalone Scripts: Single-file Python applications
- Final Applications: Complete apps with public APIs
- Closed Systems: Scripts running in controlled environments
- CLI Tools: Command-line utilities
- Custom Business Logic: Proprietary algorithms and business rules
- Framework Plugins: Plugins and extensions for existing frameworks
โ ๏ธ Use With Caution For
- Open-source Contributions: Code that others need to read and maintain
- Debugging Required: Code still in active development (harder to debug obfuscated code)
- Python Libraries: Public packages on PyPI (users expect readable source code)
Input Types
- Single File:
script.py - Directory:
myproject/(processes all.pyfiles recursively)
Output Types
- Single File:
protected.py(default:/dist/filename.py) - Directory:
protected/(default:/dist/inputname/, maintains input structure)
โ๏ธ Command Line Options
| 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 |
-b |
Bind code to current machine hardware | Disabled |
-e DAYS |
License expiration in days | 365 |
--no-preserve-api |
โจ NEW: Obfuscate all names including public API | Disabled (API preserved) |
๐ Public API Preservation (Default)
By default, PyProtect preserves public API names to allow cross-module imports:
- Preserved: Public functions/classes (no leading
_) - Obfuscated: Private functions/classes (leading
_) - Preserved: Odoo-specific attributes (
_name,_inherit,create, etc.) - Compatible: Works with Odoo, Django, Flask, and other frameworks
Example:
# Default: Preserves public API (Odoo/Framework compatible)
pyprotect -i my_odoo_addon/
# Full obfuscation: May break imports
pyprotect -i standalone_script.py --no-preserve-api
๐ก Examples
Example 1: Basic File Protection
# 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
Example 2: Machine-Bound Protection
# Protect and bind to current machine for 1 year
pyprotect -i app.py -o app_protected.py -b -e 365
Example 3: Project Protection
# Protect entire Django/Flask project (output to /dist/)
pyprotect -i my_django_project/ -b
# Or specify custom output directory
pyprotect -i my_django_project/ -o protected_project/ -b
Example 4: Check Machine ID
# Display current machine ID for licensing
pyprotect -m
# Output: Machine ID: 0a3a756bffd5fe563cb9b9ec3e5e17fb
Example 5: Check License Status
# 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
Example 6: Trial Version (30 days)
# Create time-limited trial version
pyprotect -i software.py -o trial_version.py -b -e 30
Example 7: Obfuscating Odoo Addons (โ Now Supported!)
# โ
NEW: Obfuscating Odoo addons now works correctly!
# Public API names are preserved, allowing cross-module imports
# Obfuscate a custom Odoo addon
pyprotect -i /path/to/custom_addon/ -o /dist/custom_addon/ -b
# Obfuscate entire Odoo server (if needed)
pyprotect -i /odoo18/odoo18-server/addons/my_custom_addon/ -b
# What gets preserved:
# โ
Public functions: def my_function() โ preserved
# โ
Public classes: class MyClass โ preserved
# โ
Public methods: def method() โ preserved
# โ
Odoo model attributes: _name, _inherit, create, write, etc.
# โ๏ธ Private functions: def _helper() โ obfuscated to _fn_0
# โ๏ธ Variables: user_input โ obfuscated to _obf_0
# Test after obfuscation:
cd /dist/custom_addon
python3 -m odoo # Should work! โ
๐ Security Features
Variable Obfuscation
# 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
String Encryption
# Original strings are base64 encoded
_STRINGS = ['c2VjcmV0MTIz', 'dG9rZW5fYWJjMTIz'] # Encrypted strings
Hardware Binding
- 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
Runtime Protection
# Automatic license check on import
_check_license() # Validates machine and expiration
๐๏ธ Architecture
Core Components
-
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
File Structure
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
โ ๏ธ Limitations
Current Limitations
- 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
Public API Preservation (Default Behavior)
- โ
Framework Compatible: By default, PyProtect preserves public API names (functions/classes not starting with
_) - โ
Cross-Module Imports:
from module import function_nameworks correctly after obfuscation - โ Odoo Compatible: Tested and working with Odoo's module system
- Option: Use
--no-preserve-apiflag for full obfuscation (may break imports)
Known Issues
- Very large files (>10MB) may be slow to process
- Some debugging tools may not work with obfuscated code
๐ง Troubleshooting
Common Issues
"ImportError: cannot import name 'function_name' from 'module'" (FIXED!)
Status: โ RESOLVED - This issue is now fixed in the latest version!
Solution: PyProtect now automatically preserves public API names (functions and classes that don't start with _), so cross-module imports work correctly by default.
How it works:
# Public functions (no leading _) are preserved:
def strftime_format_to_spreadsheet_date_format(fmt): # Name preserved โ
return _internal_helper(fmt) # Private function obfuscated โ
# After obfuscation, you can still import:
from module import strftime_format_to_spreadsheet_date_format # Works! โ
Advanced Option: If you need full obfuscation (which may break imports), use:
pyprotect -i mycode.py --no-preserve-api
Best Practice: Keep default behavior for Odoo/framework code. Only use --no-preserve-api for standalone scripts where no imports are needed.
"SyntaxError: invalid syntax"
Cause: F-strings or advanced Python syntax not supported
Solution: Convert f-strings to .format() or string concatenation
"ModuleNotFoundError"
Cause: Import paths changed after obfuscation Solution: Use absolute imports or adjust PYTHONPATH
"Unauthorized use of script"
Cause: License validation failed Solutions:
- Verify you're on the licensed machine
- Check license hasn't expired
- Regenerate license if hardware changed
"ast.Unparse not available"
Cause: Python version < 3.9 Solution: Upgrade Python or use string fallback mode
Debug Mode
# Enable verbose output
pyprotect -i input.py -o output.py --verbose
Recovery
# If obfuscation fails, restore from backup
cp original_file.py obfuscated_file.py.backup
๐ค Contributing
We welcome contributions! Please see our contributing guidelines:
- Fork the repository
- Create a feature branch
- Add tests for new features
- Submit a pull request
Development Setup
git clone https://github.com/dynaz/PyProtect
cd pyprotect
python3 -m pip install -r requirements-dev.txt
python3 -m pytest tests/
Code Standards
- Follow PEP 8 style guidelines
- Add docstrings to all functions
- Include unit tests for new features
- Update documentation for changes
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
Commercial Use
For commercial applications requiring advanced features:
- Enterprise licensing available
- Priority support
- Custom feature development
- Professional services
๐ Support
Documentation
Community
- GitHub Issues: Report bugs and request features
- Discussions: Ask questions and share experiences
- Wiki: Community guides and tutorials
Professional Support
For enterprise deployments and custom requirements:
- Email: dynaz@mac.com
- Enterprise licensing: dynaz@mac.com
Support the Project
If you find PyProtect helpful, consider supporting the development:
Your support helps maintain and improve this open-source project! โ
๐ฏ Quick Reference
Most Common Commands
# Quick protection (output to /dist/)
pyprotect -i file.py -b
# Project protection (output to /dist/)
pyprotect -i project/ -b
# Trial version (30 days)
pyprotect -i app.py -o trial.py -b -e 30
# Check machine ID
pyprotect -m
# Check license status
pyprotect -c
Verification
# 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! ๐โจ
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyprotect_th-1.0.2.tar.gz.
File metadata
- Download URL: pyprotect_th-1.0.2.tar.gz
- Upload date:
- Size: 35.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
81ebbb980fa53e412a1d1e0efc9d8c89df5e426cfe60411c8528705829979ad8
|
|
| MD5 |
23df898277cd0f6a11cce21def1ac2a5
|
|
| BLAKE2b-256 |
499b8b0c147ce8e3c7ad22fcb4b65cbcc4ef51b7db6adec38375cee507be8f17
|
File details
Details for the file pyprotect_th-1.0.2-py3-none-any.whl.
File metadata
- Download URL: pyprotect_th-1.0.2-py3-none-any.whl
- Upload date:
- Size: 23.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5fa031db6ccc49c4f8addda1b25ee02543aafb69d8bd3ccf543e9f4eeb6ecf12
|
|
| MD5 |
486708c025f627a94365459e666b7bc8
|
|
| BLAKE2b-256 |
848815e9defc86376f0479416edbfd368235e03d9ca7642d396d8dbe1917bda4
|