A command-line tool for obfuscating Python scripts, binding obfuscated scripts to specific machines, and setting expiration dates
—
PyArmor's core obfuscation engine provides comprehensive Python script protection through multiple techniques including code transformation, string encryption, control flow obfuscation, and advanced binary compilation. The obfuscation system maintains script compatibility while providing strong protection against reverse engineering.
Transform Python source code into obfuscated form with runtime decryption and validation.
def encrypt_script(pubkey, filename: str, destname: str, wrap_mode: int = 1, obf_code: int = 1, obf_mod: int = 1, adv_mode: int = 0, rest_mode: int = 1, entry: int = 0, protection: int = 0, platforms = None, plugins = None, rpath = None, suffix: str = '', sppmode: bool = False, mixins = None) -> None:
"""
Obfuscate a single Python script file.
Args:
pubkey: Protection key from capsule
filename (str): Source script file path
destname (str): Destination obfuscated file path
wrap_mode (int): 0=disable, 1=enable wrap mode (default: 1)
obf_code (int): 0=none, 1=basic, 2=advanced code obfuscation (default: 1)
obf_mod (int): 0=disable, 1=enable module obfuscation (default: 1)
adv_mode (int): Advanced protection level 0-5 (default: 0)
rest_mode (int): Restriction mode 0-3 (default: 1)
entry (int): Entry point mode 0=normal, 1=entry (default: 0)
protection (int): Protection features bitmask (default: 0)
platforms: Target platform list or string (default: None)
plugins: Plugin list to apply (default: None)
rpath: Runtime path specification (default: None)
suffix (str): File suffix for runtime files (default: '')
sppmode (bool): Super plus mode enable (default: False)
mixins: Platform-specific mixins (default: None)
Raises:
EncryptError: If obfuscation fails
FileNotFoundError: If source file doesn't exist
PermissionError: If unable to write destination
"""
def pytransform_bootstrap(capsule = None, force: bool = False) -> None:
"""
Initialize PyArmor runtime environment and load protection library.
Args:
capsule: Protection capsule path (default: None for auto-detection)
force (bool): Force reinitialization even if already loaded (default: False)
Note:
This function must be called before any other PyArmor operations.
It initializes the core protection library (_pytransform) and sets up
the runtime environment for obfuscation operations.
"""
def make_capsule(filename: str = None) -> str:
"""
Generate protection capsule containing encryption keys.
Args:
filename (str, optional): Capsule file path, uses default if None
Returns:
str: Path to generated capsule file
Raises:
CapsuleError: If capsule generation fails
"""
def make_runtime(capsule, output: str, **kwargs) -> None:
"""
Generate runtime package for obfuscated scripts.
Args:
capsule: Protection capsule path or object
output (str): Output directory for runtime files
**kwargs: Runtime options
- platform (str): Target platform(s)
- package (int): 0=separate, 1=package with scripts
- suffix (str): Runtime file suffix
- bootstrap (int): Bootstrap code generation
- advanced (int): Advanced runtime features
Raises:
RuntimeError: If runtime generation fails
"""
def make_entry(entry: str, src: str, output: str, **kwargs) -> None:
"""
Generate entry point script with runtime initialization.
Args:
entry (str): Entry script name
src (str): Source directory
output (str): Output directory
**kwargs: Entry options
- bootstrap_code (int): Bootstrap generation mode
- suffix (str): File suffix for entry script
"""
def make_bootstrap_script(output: str, **kwargs) -> None:
"""
Generate standalone bootstrap script for runtime initialization.
Args:
output (str): Output directory
**kwargs: Bootstrap options
- capsule: Protection capsule
- template (str): Bootstrap template
"""
def make_project_command(platform: str, python: str, pyarmor: str, output: str) -> None:
"""
Generate platform-specific command script for project execution.
Args:
platform (str): Target platform specification
python (str): Python interpreter path
pyarmor (str): PyArmor script path
output (str): Output directory for generated script
"""
def search_plugins(plugins: list) -> list:
"""
Search and validate plugin files for obfuscation process.
Args:
plugins (list): List of plugin names or paths to search
Returns:
list: List of valid plugin file paths
Raises:
PluginError: If plugin files are not found or invalid
"""
def get_bind_key(filename: str) -> str:
"""
Extract hardware binding key from license or data file.
Args:
filename (str): Path to file containing binding information
Returns:
str: Hardware binding key extracted from file
Raises:
RuntimeError: If bind file not found or invalid
FileNotFoundError: If specified file doesn't exist
"""Modern obfuscation system with enhanced protection and performance optimization.
class Builder:
"""
Advanced obfuscation builder for v8+ interface.
"""
def __init__(self, ctx):
"""
Initialize builder with context.
Args:
ctx (Context): PyArmor context instance
"""
def generate_runtime_key(self, outer: bool = None) -> bytes:
"""
Generate runtime encryption key.
Args:
outer (bool, optional): Generate outer key for external runtime
Returns:
bytes: Generated runtime key data
"""
def generate_runtime_package(self, output: str) -> None:
"""
Generate complete runtime package with libraries.
Args:
output (str): Output directory path
"""
def process(self, options: dict, packer=None) -> None:
"""
Process obfuscation with comprehensive options.
Args:
options (dict): Obfuscation configuration
packer (optional): Packaging tool integration
"""
class Finder:
"""
Resource discovery and dependency management.
"""
def prepare(self, input_paths: list) -> None:
"""
Prepare resources for obfuscation processing.
Args:
input_paths (list): List of input file/directory paths
"""
def process(self) -> None:
"""
Discover and analyze all resources and dependencies.
"""
def append(self, resources: list) -> None:
"""
Add additional resources to processing queue.
Args:
resources (list): Additional resource objects
"""# Obfuscation mode constants
OBF_MODULE_MODE = {
0: "None", # No module obfuscation
1: "Simple" # Basic module protection
}
OBF_CODE_MODE = {
0: "None", # No code obfuscation
1: "Simple", # Basic code protection
2: "Fast" # Advanced code protection
}
WRAP_MODE = {
0: "None", # No wrapping
1: "Simple" # Function wrapping
}
ADVANCED_MODE = {
0: "Default", # Standard protection
1: "High", # Enhanced protection
2: "Super", # Super mode with C compilation
3: "VM Super", # Virtual machine + super mode
4: "Super Plus", # Maximum protection
5: "Super Pro" # Professional grade protection
}
RESTRICT_MODE = {
0: "None", # No restrictions
1: "Import", # Import restrictions
2: "Private", # Private mode
3: "Restrict" # Full restriction mode
}def enable_bcc_mode(options: dict) -> dict:
"""
Enable Binary Code Coverage protection.
Args:
options (dict): Current obfuscation options
Returns:
dict: Updated options with BCC enabled
Note:
BCC mode compiles Python functions to machine code
for maximum protection. Platform specific.
"""
def enable_jit_mode(options: dict) -> dict:
"""
Enable Just-In-Time compilation protection.
Args:
options (dict): Current obfuscation options
Returns:
dict: Updated options with JIT enabled
"""
def enable_rft_mode(options: dict) -> dict:
"""
Enable Runtime Function Transformation.
Args:
options (dict): Current obfuscation options
Returns:
dict: Updated options with RFT enabled
"""
def enable_themida_protection(options: dict) -> dict:
"""
Enable Themida anti-debugging protection (Windows only).
Args:
options (dict): Current obfuscation options
Returns:
dict: Updated options with Themida enabled
Note:
Requires Windows platform and Themida license
"""def enable_string_mixing(options: dict) -> dict:
"""
Enable string constant encryption and mixing.
Args:
options (dict): Obfuscation options
Returns:
dict: Options with string mixing enabled
Note:
Encrypts string literals and mixes them with dummy data
"""
def protect_constants(script_path: str, **kwargs) -> None:
"""
Apply constant protection to numeric and string literals.
Args:
script_path (str): Path to script file
**kwargs: Protection options
- level (int): Protection intensity 1-3
- strings (bool): Protect string constants
- numbers (bool): Protect numeric constants
"""def generate_cross_platform(scripts: list, platforms: list, **kwargs) -> None:
"""
Generate obfuscated scripts for multiple target platforms.
Args:
scripts (list): List of script file paths
platforms (list): Target platform specifications
**kwargs: Cross-platform options
- output (str): Output directory
- shared_runtime (bool): Use shared runtime package
Example platforms:
['linux.x86_64', 'windows.x86_64', 'darwin.x86_64']
"""
def download_platform_library(platform: str, **kwargs) -> str:
"""
Download platform-specific runtime library.
Args:
platform (str): Platform specification (e.g., 'linux.x86_64')
**kwargs: Download options
- update (bool): Force update existing library
- timeout (int): Download timeout in seconds
Returns:
str: Path to downloaded library
Raises:
DownloadError: If download fails
PlatformError: If platform not supported
"""from pyarmor import utils
# Initialize PyArmor
utils.pytransform_bootstrap()
# Generate capsule and runtime
capsule = utils.make_capsule()
utils.make_runtime(capsule, "dist")
# Obfuscate single script
utils.encrypt_script(capsule, "hello.py", "dist/hello.py")
# Create entry point
utils.make_entry("hello.py", ".", "dist")# Configure advanced obfuscation
options = {
'obf_code': 2, # Advanced code obfuscation
'obf_mod': 1, # Module obfuscation
'wrap_mode': 1, # Function wrapping
'advanced': 2, # Super mode
'restrict': 2, # Private mode
'cross_protection': 1, # Cross protection
'bootstrap_code': 1 # Bootstrap generation
}
# Apply to script
utils.encrypt_script(capsule, "main.py", "dist/main.py", **options)from pyarmor.cli.generate import Builder
from pyarmor.cli.context import Context
# Initialize context and builder
ctx = Context()
builder = Builder(ctx)
# Configure obfuscation options
options = {
'inputs': ['src/'],
'output': 'dist',
'recursive': True,
'obf_code': 2,
'mix_str': True,
'enable_bcc': True,
'restrict_module': 2,
'platforms': ['linux.x86_64', 'windows.x86_64']
}
# Process obfuscation
builder.process(options)# Enable comprehensive string protection
options = {
'mix_str': True, # String mixing
'advanced': 3, # VM mode for strings
'assert_call': True, # Function call validation
'assert_import': True # Import validation
}
utils.encrypt_script(capsule, "sensitive.py", "dist/sensitive.py", **options)# Multi-platform obfuscation
platforms = [
'linux.x86_64', # Linux 64-bit
'windows.x86_64', # Windows 64-bit
'darwin.x86_64', # macOS Intel
'darwin.arm64', # macOS Apple Silicon
'linux.aarch64' # Linux ARM64
]
# Download required libraries
for platform in platforms:
utils.download_pytransform(platform)
# Generate cross-platform runtime
utils.make_runtime(capsule, "dist", platform=",".join(platforms))
# Obfuscate with platform support
utils.encrypt_script(capsule, "app.py", "dist/app.py",
platform=",".join(platforms))from pyarmor.utils import EncryptError, RuntimeError, CapsuleError
try:
# Obfuscation operations
capsule = utils.make_capsule()
utils.make_runtime(capsule, "dist")
utils.encrypt_script(capsule, "main.py", "dist/main.py")
except CapsuleError as e:
print(f"Capsule generation failed: {e}")
except RuntimeError as e:
print(f"Runtime generation failed: {e}")
except EncryptError as e:
print(f"Script obfuscation failed: {e}")
except FileNotFoundError:
print("Source file not found")
except PermissionError:
print("Permission denied - check file/directory permissions")Install with Tessl CLI
npx tessl i tessl/pypi-pyarmor