Skip to main content

Python Code Protection SDK with obfuscation and anti-debug features

Project description

PyLockWare SDK

Python Code Protection SDK with advanced obfuscation, anti-debug features, and annotation-based control.

Python Version License

Version 2.0

Very important Note:

Virtualization is beta, and may not be fully supported yet. Respect to [CustomVM for good virtual machine.

🚀 Features

Annotation-Based Control

  • @external - Preserve function/class names (for public APIs)
  • @skip_obf - Skip all obfuscation steps (for debugging)
  • @preserve_name - Alias for @external
  • Annotations are automatically removed after obfuscation

Obfuscation Techniques

  • String Protection - Base64 + zlib encoding
  • Number Obfuscation - Arithmetic expressions
  • State Machine - Transform functions into state machines
  • Junk Code - Fake branches with opaque predicates
  • Builtin Dispatcher - Replace built-in calls
  • Import Obfuscation - Dynamic import execution
  • Call Obfuscation - Indirect function calls
  • Name Remapping - Rename identifiers

Anti-Debug Protection

  • Native Mode - Windows AMD64 only, protects even from dll injections, etc.
  • Cross-platform Mode - Python-level checks

Build System

  • pyproject.toml Integration - Standard Python configuration
  • Nuitka Support - Compile to native executables
  • CLI & GUI - Multiple interfaces
  • Programmatic API - Use from Python code

📦 Installation

Via pip (Recommended)

# Basic installation
pip install pylockware

# With GUI support
pip install pylockware[gui]

# With Nuitka support
pip install pylockware[nuitka]

# Full installation (all features)
pip install pylockware[full]

From Source

git clone https://github.com/yourusername/pylockware.git
cd pylockware
pip install -e .

Verify Installation

# SDK CLI
pylockware --help

# Legacy CLI
pylockware-cli --help

# GUI (if installed with [gui])
pylockware-gui

🎯 Quick Start

1. Initialize Project

cd your_project
pylockware init

This creates a [tool.pylockware] section in your pyproject.toml:

[tool.pylockware]
project_path = "."
entry_point = "main.py"
entry_function = "main"
output_dir = "dist"

# Obfuscation options
string_prot = true
state_machine = true
junk_code = true
# ... more options

2. Add Annotations to Your Code

from pylockware import external, skip_obf

# Public API - name will be preserved
@external
def public_api_function(data: str) -> str:
    return process_data(data)

# Internal function - will be obfuscated
def process_data(data: str) -> str:
    return data.upper()

# Debug function - will not be obfuscated
@skip_obf
def debug_log(message: str):
    print(f"[DEBUG] {message}")

# Public class
@external
class PublicAPI:
    @external
    def public_method(self):
        pass
    
    def _internal_method(self):
        # Will be obfuscated
        pass

3. Build Your Project

# Basic build
pylockware build

# With custom options
pylockware build --entry-point app.py --output-dir build

# Clean before build
pylockware build --clean

# With Nuitka compilation
pylockware build --enable-nuitka

4. Run Protected Application

python dist/main.py

📚 Documentation

Annotations

@external

Marks function/class as external API. Name is preserved during remapping, but other transformations are applied.

@external
def api_function():
    pass

@external
class APIClass:
    pass

Note: Annotations are automatically removed from the final obfuscated code.

@skip_obf

Completely skips obfuscation for function/class. Code remains in original form.

@skip_obf
def debug_function():
    pass

@skip_obf
class DebugClass:
    pass

Warning: Use only for debugging. Do not leave in production code.

Configuration (pyproject.toml)

[tool.pylockware]
# Basic settings
project_path = "."              # Project path
entry_point = "main.py"         # Entry point file
entry_function = "main"         # Main function name
output_dir = "dist"             # Output directory

# Obfuscation options
remap = false                   # Name remapping
string_prot = true              # String protection
num_obf = true                  # Number obfuscation
import_obf = false              # Import obfuscation
state_machine = true            # State machine transformation
builtin_dispatcher = true       # Builtin dispatcher
junk_code = true                # Junk code generation
decorator_obf = true            # Decorator obfuscation
call_obf = false                # Call obfuscation
disable_traceback = true        # Disable traceback

# Obfuscation parameters
junk_density = 0.5              # Junk code density (0.0-1.0)
opaque_complexity = "high"      # Opaque predicate complexity (low/medium/high)
name_gen = "english"            # Name generator (english/chinese/mixed/numbers/hex)
banner = "Protected by PyLockWare"  # Banner text

# Anti-debug
anti_debug = null               # null, "native", "crossplatform"
anti_debug_mode = "native"      # Anti-debug mode

# Nuitka options
enable_nuitka = false           # Enable Nuitka
nuitka_onefile = true           # Single file
nuitka_standalone = true        # Standalone build
nuitka_output_name = null       # Output name
nuitka_disable_console = true   # Disable console
nuitka_icon = null              # Icon path
nuitka_admin = false            # Require admin
nuitka_plugins = []             # Nuitka plugins
nuitka_extra_imports = []       # Extra imports
nuitka_options = []             # Extra options

Programmatic API

Builder

from pylockware.sdk import Builder, BuildConfig

# Create builder
builder = Builder(config)
builder = Builder.from_pyproject(path)

# Build
success = builder.build()
success = builder.build(banner="Custom Banner")

# Clean
builder.clean()

# Update configuration
builder.update_config(
    string_prot=True,
    state_machine=True
)

BuildConfig

from pylockware.sdk import BuildConfig

# Create configuration
config = BuildConfig(
    entry_point="main.py",
    output_dir="dist",
    string_prot=True
)

# Convert to dict
config_dict = config.to_dict()

# Create from dict
config = BuildConfig.from_dict(config_dict)

Configuration Functions

from pylockware.sdk import load_config, save_config, init_config

# Load configuration
config = load_config()
config = load_config(Path("custom/pyproject.toml"))

# Save configuration
save_config(config)
save_config(config, Path("custom/pyproject.toml"))

# Initialize configuration
config = init_config()
config = init_config(force=True)  # Overwrite existing

🔧 CLI Commands

init

Initialize PyLockWare configuration in pyproject.toml

pylockware init
pylockware init --config path/to/pyproject.toml
pylockware init --force  # Overwrite existing

build

Build protected application

pylockware build
pylockware build --config path/to/pyproject.toml
pylockware build --clean
pylockware build --entry-point app.py
pylockware build --output-dir build
pylockware build --remap
pylockware build --enable-nuitka

clean

Clean output directory

pylockware clean
pylockware clean --config path/to/pyproject.toml

📝 Examples

Example 1: Simple Build

from pylockware.sdk import Builder

builder = Builder.from_pyproject()
builder.build()

Example 2: Custom Configuration

from pylockware.sdk import Builder, BuildConfig

config = BuildConfig(
    entry_point="app.py",
    output_dir="protected",
    string_prot=True,
    state_machine=True,
    junk_code=True,
    junk_density=0.7,
    banner="My Protected App"
)

builder = Builder(config)
builder.build()

Example 3: Build with Nuitka

from pylockware.sdk import Builder, BuildConfig

config = BuildConfig(
    entry_point="main.py",
    string_prot=True,
    state_machine=True,
    enable_nuitka=True,
    nuitka_onefile=True,
    nuitka_disable_console=True,
    nuitka_icon="icon.ico"
)

builder = Builder(config)
builder.build()

Example 4: Using Annotations

from pylockware import external, skip_obf

@external
class MyAPI:
    """Public API class"""
    
    @external
    def public_method(self, data):
        """Public method"""
        return self._process(data)
    
    def _process(self, data):
        """Private method - will be obfuscated"""
        return data.upper()

@skip_obf
def debug_helper():
    """Debug function - will not be obfuscated"""
    print("Debug info")

🎓 Complete Example

See examples/sdk_example/ for a complete working example:

cd examples/sdk_example

# Initialize (pyproject.toml already exists)
pylockware init

# Build via CLI
pylockware build

# Or programmatically
python build.py --mode pyproject
python build.py --mode config
python build.py --mode overrides

# Run protected application
python dist/main.py

🔒 Security Recommendations

  1. Use @external for public APIs - Preserves function/class names that must be accessible externally
  2. Use @skip_obf only for debugging - Do not leave these annotations in production code
  3. Combine multiple obfuscation techniques - string_prot + state_machine + junk_code provides better protection
  4. Use Nuitka for final builds - Compiles Python to native code
  5. Don't store secrets in code - Obfuscation is not a replacement for proper secret management

⚠️ Known Limitations

  • import_obf and call_obf are incompatible with each other
  • import_obf does not work with Nuitka
  • Native anti-debug only works on Windows AMD64
  • Annotations work only at function and class level

🔄 Migration from v2.x

Old Way (CLI)

python cli.py examples/example_project \
    --entry-point main.py \
    --string-prot \
    --state-machine

New Way (SDK)

  1. Initialize configuration:
cd examples/example_project
pylockware init
  1. Edit pyproject.toml:
[tool.pylockware]
entry_point = "main.py"
string_prot = true
state_machine = true
  1. Build:
pylockware build

Backward Compatibility

The old CLI still works:

# Legacy CLI
python cli.py project_path --entry-point main.py --string-prot

# Or via installed command
pylockware-cli project_path --entry-point main.py --string-prot

🛠️ Development

Setup Development Environment

git clone https://github.com/yourusername/pylockware.git
cd pylockware
pip install -e .[dev]

Run Tests

pytest
pytest tests/test_sdk.py -v

Code Formatting

black pylockware

Type Checking

mypy pylockware

📋 System Requirements

  • Python 3.8 or higher
  • Windows, Linux, or macOS
  • For native anti-debug: Windows AMD64

📦 Optional Dependencies

GUI

  • PySide6 >= 6.0.0
  • pyside6-fluent-widgets

Nuitka

  • nuitka >= 1.0.0
  • ordered-set
  • zstandard

Windows (for native anti-debug)

  • pywin32

🐛 Troubleshooting

Command not found: pylockware

Ensure pip installed the package in the correct environment:

python -m pip install pylockware
python -m pylockware.cli.build --help

GUI dependencies not installed

Install GUI dependencies:

pip install pylockware[gui]

Import error: tomli

For Python < 3.11, tomli is required:

pip install tomli

Nuitka issues

Install Nuitka dependencies:

pip install pylockware[nuitka]

📄 License

MIT License - see LICENSE file for details.

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

📧 Support

🙏 Acknowledgments

  • Nuitka project for Python compilation
  • PySide6 for GUI framework
  • All contributors and users

Note: PyLockWare is a code protection tool. While it provides multiple layers of obfuscation, no obfuscation is unbreakable. Use it as part of a comprehensive security strategy, not as the only protection mechanism.

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

pylockware-2.0.1.tar.gz (128.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pylockware-2.0.1-py3-none-any.whl (143.6 kB view details)

Uploaded Python 3

File details

Details for the file pylockware-2.0.1.tar.gz.

File metadata

  • Download URL: pylockware-2.0.1.tar.gz
  • Upload date:
  • Size: 128.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pylockware-2.0.1.tar.gz
Algorithm Hash digest
SHA256 0429856ad2257a76340469b6dc7b1ed77e405d7a30598607e7a6dbf85665972c
MD5 74b39b63e98618d62f42e1ab9182df4f
BLAKE2b-256 4e24e943e8f50baabe9f4f4072a07d75931f614d56efd77533be2f56734bd1fa

See more details on using hashes here.

Provenance

The following attestation bundles were made for pylockware-2.0.1.tar.gz:

Publisher: python-publish.yml on amogus-gggy/PyLockWare

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pylockware-2.0.1-py3-none-any.whl.

File metadata

  • Download URL: pylockware-2.0.1-py3-none-any.whl
  • Upload date:
  • Size: 143.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pylockware-2.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 6c5f75308ee8d5366f9a2db4ad2351833c237a20203990f0dbb638a6a504854a
MD5 4d0b82228252daec2026db474d810abc
BLAKE2b-256 ae1aa4d1b48f2e9039a0c6c5b0791a8cd404697b76f47fe88fc243d95d028e99

See more details on using hashes here.

Provenance

The following attestation bundles were made for pylockware-2.0.1-py3-none-any.whl:

Publisher: python-publish.yml on amogus-gggy/PyLockWare

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page