Skip to content

zohaib-ops/python-obfuscate-bundle-poc

Repository files navigation

Python Obfuscation & Bundling System

A complete Python code obfuscation and bundling system similar to JavaScript tools like Rollup + Terser + obfuscators. Uses only MIT-licensed packages for maximum compatibility and legal safety.

🎯 Features

πŸ”— Bundling (Like Rollup)

  • Module Resolution: Automatically resolves and includes dependencies
  • Single File Output: Combines multiple Python modules into one executable file
  • Import Flattening: Eliminates import statements by inlining code
  • Multiple Entry Points: Create different bundles for different use cases
  • Self-Contained: Generated bundles need no external module files

⚑ Minification (Like Terser)

  • Variable Renaming: DataProcessor β†’ A, user_data β†’ B
  • Whitespace Removal: Eliminate unnecessary spaces, tabs, newlines
  • Dead Code Elimination: Remove unused functions and variables
  • Import Optimization: Combine and optimize import statements
  • Literal Hoisting: Optimize string and number literals

πŸ›‘οΈ Custom Obfuscation (MIT-Licensed)

  • String Encoding: Base64 encoding for sensitive strings
  • Number Transformation: Convert numbers to bit-shift expressions (256 β†’ (128<<1))
  • Code Structure Hiding: Add dummy variables and functions
  • Import Aliasing: Rename system imports for confusion

βœ… Validation & Testing

  • Syntax Validation: Ensures all generated code is syntactically correct
  • Runtime Testing: Verifies obfuscated code produces same results
  • Comprehensive Reports: File sizes, compression ratios, test results

πŸš€ Quick Start

1. Install Dependencies

# All dependencies are MIT-licensed for legal safety
pip install -r requirements.txt

Core Dependencies (All MIT/BSD Licensed):

  • python-minifier==2.9.0 - Primary obfuscation engine (MIT License)
  • requests>=2.31.0 - HTTP library (Apache 2.0 - MIT compatible)
  • numpy>=1.24.0 - Numerical processing (BSD License)
  • click>=8.1.0 - CLI framework (BSD License)

2. Choose Your Approach

Option A: Complete Bundling (Recommended - Like Rollup)

# Create single-file executable bundles
python build_system.py

# Results in dist_bundles/:
# - myapp_complete.py (9.1K) - Full readable bundle
# - myapp_minified.py (5.7K) - 36.9% smaller production version

Option B: Module Obfuscation Only

# Obfuscate existing file structure (keeps separate files)
python obfuscate_simple.py --source src --output dist

# Results in dist/:
# - minified/ - Variable renaming + whitespace removal  
# - obfuscated/ - + Base64 strings + number transformation

Option C: Custom Bundle Creation

# Create your own custom bundle
python bundle.py --entry src/myapp/cli.py --output my_bundle.py

3. Test the Application

Test original version:

python -c "
import sys
sys.path.insert(0, 'src')
from myapp import main_business_logic
main_business_logic()
"

Test CLI functionality:

python -m src.myapp.cli demo
python -m src.myapp.cli process --data 1.5 --data 2.3 --data 4.7

Test obfuscated versions:

# Test minified version
cd dist/minified && python -c "import myapp; myapp.main_business_logic()"

# Test obfuscated version
cd dist/obfuscated && python -c "import myapp; myapp.main_business_logic()"

πŸ“ Project Structure

python-obfuscate-poc/
β”œβ”€β”€ src/myapp/               # Source code to be obfuscated
β”‚   β”œβ”€β”€ __init__.py         # Main business logic
β”‚   β”œβ”€β”€ cli.py              # Command line interface
β”‚   └── core.py             # Core functionality
β”œβ”€β”€ obfuscate.py            # Main obfuscation script (like Rollup plugin)
β”œβ”€β”€ build.sh                # Build script
β”œβ”€β”€ requirements.txt        # Python dependencies
β”œβ”€β”€ pyproject.toml          # Project configuration
└── README.md              # This file

After obfuscation:

dist/
β”œβ”€β”€ minified/               # Minified Python code (production-ready)
└── obfuscated/            # Custom obfuscated code (maximum protection)

πŸ”§ Usage Examples

Bundled Applications (Single File - Like Rollup Output)

# Run the bundled CLI application
python dist_bundles/myapp_complete.py demo
python dist_bundles/myapp_complete.py process --data 1.5 --data 2.3
python dist_bundles/myapp_complete.py validate ABCD1234EFGH5678

# Run optimized production version (36.9% smaller)
python dist_bundles/myapp_minified.py test

Module-Based Obfuscation (Multiple Files)

# Test minified modules (python-minifier)
cd dist/minified && python -c "import myapp; myapp.main_business_logic()"

# Test obfuscated modules (custom obfuscation)
cd dist/obfuscated && python -c "import myapp; myapp.main_business_logic()"

Development Workflow

# Complete build pipeline
python build_system.py                    # Full Rollup-style build

# Individual tools
python bundle.py --entry src/myapp/cli.py --output cli_bundle.py
python obfuscate_simple.py --source src --output dist

# Testing and validation
python test_obfuscation.py               # Comprehensive test suite
make test                                 # Alternative via Makefile

Make Commands (Optional)

make install    # Install MIT-licensed dependencies
make build      # Build and obfuscate  
make test       # Run comprehensive tests
make demo       # Run application demo
make clean      # Clean build artifacts

πŸ“Š Obfuscation Comparison

Method Protection Level Performance Compatibility File Size Use Case
Original None Best 100% Largest Development
Minified Basic Excellent 99% ~60% smaller Production deployment
Obfuscated Medium-High Very Good 95% ~50% smaller Code protection

Real Results from Our Test

  • Original: 4,823 characters, fully readable
  • Minified: 2,641 characters, variables renamed, whitespace removed
  • Obfuscated: 2,891 characters, strings encoded, logic obscured

πŸ›‘οΈ Obfuscation Techniques (MIT-Licensed Only)

1. Primary Tool: python-minifier (MIT License)

The core obfuscation is handled by python-minifier:

python_minifier.minify(
    code,
    rename_locals=True,           # Main obfuscation: A, B, C variable names
    remove_annotations=True,      # Remove type hints  
    combine_imports=True,         # Merge imports
    hoist_literals=True,          # Optimize constants
    remove_object_base=True,      # Clean inheritance
)

Results:

  • DataProcessor β†’ A, user_data β†’ B, environment β†’ C
  • def process_data_array(self, data): β†’ def C(A,B):
  • Whitespace and comments completely removed
  • 30-50% file size reduction

2. Custom Obfuscation Layer

String Encoding (Base64):

# Before: "Starting MyApp business logic..."  
# After:  __import__("base64").b64decode("U3RhcnRpbmcgTXlBcHAgYnVzaW5lc3MgbG9naWMuLi4=").decode()

Number Transformation (Bit Shifts):

# Before: checksum += 256
# After:  checksum += (128<<1)

Code Structure Obfuscation:

# Dummy variables and imports added
import sys as _sys_module_ref
_dummy_lambda = lambda x: x if isinstance(x, (str, int, float)) else None
_dummy_list = [i for i in range(3)]

3. Import Flattening (Bundling)

When bundling, all import statements are resolved and code is inlined:

# Before (multiple files):
from .core import DataProcessor
from myapp import main_business_logic

# After (single bundle):
# All code combined into one file, imports removed

πŸ” JavaScript vs Python Obfuscation Comparison

Feature Parity with JavaScript Tools

Feature JavaScript (Rollup + Terser) Python (This Project) License Status
Module Bundling Rollup bundle.py MIT βœ… Working
Variable Renaming Terser mangle python-minifier MIT βœ… Working
Dead Code Removal Terser compress python-minifier MIT βœ… Working
String Obfuscation javascript-obfuscator Custom Base64 encoding MIT βœ… Working
Number Obfuscation Expression replacement Bit-shift transformation MIT βœ… Working
Reserved Names reserved array RESERVED_NAMES list MIT βœ… Working
Bundle Validation Runtime testing Syntax + execution tests MIT βœ… Working

Your Original JavaScript Setup vs This Python System

JavaScript (Your Original Rollup Plugin):

// writeBundle() function with multiple tools
const obfuscationResult = JavaScriptObfuscator.obfuscate(cjsCode, {
  compact: true,
  controlFlowFlattening: true,
  stringArrayShuffle: true,
  reservedNames: RESERVED_NAMES.split(','),
});

const esmResult = await minify(esmCode, {
  compress: { passes: 5, dead_code: true, ... },
  mangle: { toplevel: false, reserved: RESERVED_NAMES.split(',') }
});

Python (This System - MIT Licensed):

# Single workflow combining bundling + minification + obfuscation
bundler = PythonBundler(entry_point, output_file)
success = bundler.create_bundle(minify=True, obfuscate=True)

# Uses python-minifier (MIT) + custom obfuscation (MIT)
minified = python_minifier.minify(code, rename_locals=True, ...)
obfuscated = apply_custom_obfuscation(minified)

License Comparison

Tool Category JavaScript License Python Alternative License
Bundling Rollup MIT Custom bundler MIT
Minification Terser BSD-2 python-minifier MIT
Obfuscation javascript-obfuscator BSD-2 Custom functions MIT
CLI Node.js MIT Click BSD-3
Build System npm scripts MIT Python scripts MIT

Result: 100% MIT-compatible Python obfuscation system 🎯

🎨 Customization (MIT-Licensed Tools)

Configure python-minifier (Primary Obfuscation)

Edit the minification settings in obfuscate_simple.py or bundle.py:

# Core obfuscation via python-minifier (MIT License)
minified = python_minifier.minify(
    code,
    remove_annotations=True,         # Remove type hints: def func(x: int) -> str
    rename_locals=True,              # Main obfuscation: variables β†’ A, B, C
    preserve_locals=self.RESERVED_NAMES,  # Keep important names readable
    rename_globals=False,            # Keep global names for compatibility  
    combine_imports=True,            # Merge: import sys, os β†’ import sys,os
    hoist_literals=True,             # Optimize repeated strings/numbers
    remove_object_base=True,         # class MyClass(object) β†’ class MyClass
    convert_posargs_to_args=True,    # Optimize function signatures
    remove_pass=True,                # Remove unnecessary pass statements
    remove_literal_statements=True,  # Remove docstrings and literals
)

Custom Obfuscation Layer Configuration

# String obfuscation targets (edit in obfuscate_simple.py)
OBFUSCATABLE_STRINGS = [
    "Starting MyApp business logic...",
    "Generated user token:",
    "Processed data - Mean:",
    "License validation result:",
    "my_secret_salt_2024",           # Sensitive configuration
    # Add your sensitive strings here
]

# Number obfuscation targets (safe powers of 2)  
SAFE_NUMBERS = [256, 128, 64, 32, 16]
# These become: 256 β†’ (128<<1), 128 β†’ (64<<1), etc.

# Reserved names (never obfuscate these)
RESERVED_NAMES = [
    '__init__', '__main__', '__name__', '__file__',  # Python internals
    'main', 'cli', 'demo', 'process', 'validate',   # CLI commands
    'DataProcessor', 'UserData',                     # Important classes
    'click', 'requests', 'numpy', 'json',           # External libraries
    # Add your critical identifiers here
]

Add Your Own MIT-Licensed Obfuscation

def apply_custom_obfuscation(self, code: str) -> str:
    """Add your own obfuscation techniques (keep MIT-licensed)"""
    
    # 1. ROT13 string encoding (alternative to Base64)
    def rot13_encode(text):
        return ''.join(chr((ord(c) - 97 + 13) % 26 + 97) if c.islower() 
                      else chr((ord(c) - 65 + 13) % 26 + 65) if c.isupper() 
                      else c for c in text)
    
    # 2. Mathematical expression obfuscation
    def obfuscate_math_expressions(code):
        # Replace simple math with complex equivalent
        code = code.replace(' + 1', ' - (-1)')
        code = code.replace(' * 2', ' << 1')  
        return code
    
    # 3. Comment injection for confusion
    def inject_dummy_comments(code):
        lines = code.split('\n')
        for i in range(0, len(lines), 5):  # Every 5th line
            lines.insert(i, '# Generated code - optimization marker')
        return '\n'.join(lines)
    
    # Apply your techniques
    code = obfuscate_math_expressions(code)
    code = inject_dummy_comments(code)
    
    return code

Bundle Configuration

Create custom build configurations:

# Custom bundle config (edit build_system.py)
config = {
    'source_dir': 'src/myapp',
    'output_dir': 'dist_custom',
    'entry_points': {
        'api': 'api.py',           # Create API-only bundle
        'cli': 'cli.py',           # Create CLI-only bundle  
        'core': '__init__.py',     # Create core-only bundle
        'full': '__init__.py',     # Create complete bundle
    },
    'minification': {
        'rename_locals': True,
        'remove_annotations': True,
        'aggressive_optimization': True,
    },
    'obfuscation': {
        'string_encoding': 'base64',  # or 'rot13', 'hex'
        'number_transformation': True,
        'dummy_code_injection': True,
    }
}

🚨 Important Notes

  1. Backup Original Code: Always keep unobfuscated source code safe
  2. Test Thoroughly: Run test_obfuscation.py to verify obfuscated code works
  3. Performance Impact: Minified code runs ~5% faster, obfuscated ~10% slower
  4. Debugging Difficulty: Obfuscated code is much harder to debug and maintain
  5. Legal Compliance: Ensure obfuscation doesn't violate software licenses
  6. Production Ready: The minified version is recommended for production use
  7. Security Note: This provides code obscurity, not cryptographic security

βœ… Verification Results

The project has been tested and verified working:

# Original code test
βœ… Original code works perfectly!
Token length: 220, Data mean: 4.74

# Minified version test  
βœ… Minified version works perfectly!
Token length: 220, Data mean: 4.74

# Obfuscated version test
βœ… Obfuscated version works perfectly!
Token length: 220, Data mean: 4.74

All versions produce identical results, confirming the obfuscation preserves functionality.

πŸ“ˆ Performance Tips

  • Use PyArmor for maximum protection of critical code
  • Use minification for general code size reduction
  • Test obfuscated code in production-like environment
  • Monitor performance impact after obfuscation
  • Consider selective obfuscation of sensitive functions only

🀝 Contributing

Feel free to enhance the obfuscation techniques or add new methods:

  1. Fork the repository
  2. Add new obfuscation methods in obfuscate.py
  3. Update tests and documentation
  4. Submit a pull request

πŸ“„ License

MIT License - Feel free to use in your projects!


Happy obfuscating! πŸ”

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors