Skip to main content

PyPrivate-Obf

A Python source obfuscator reconstructed from the Py Private Android application.
The original author and owner of this encoder is the PSH Team — t.me/psh_team.
This repository is a reverse-engineered Python reconstruction of their work from the APK source.

PyPI Python License Downloads



Installation    CLI Usage    Encoders    Guards    Python API

CLI Preview

pyprivate-obf CLI demo

Installation

pip install pyprivate-obf

To use CPython obfuscation (Cython + GCC compilation), also install:

pip install cython

# Debian / Ubuntu
sudo apt install gcc python3-dev

# Termux
pkg install clang python-dev

CLI Usage

Interactive wizard

Run without any arguments to get a step-by-step menu:

pyprivate-obf

Or force interactive mode explicitly:

pyprivate-obf --interactive

Non-interactive (flags)

pyprivate-obf <input.py> [OPTIONS] [-o output.py]
All available flags
Flag Description
--encode-strings Replace every string literal with bytes([...]).decode()
--bytecode Marshal bytecode + opcode-pattern swap
--cpython Cython --embed → C source → GCC native binary launcher
--layers N Number of marshal layers to apply (default: 1, max: 20)
--re-check-version Re-prepend Python version guard inside every layer
--expiry "YYYY-MM-DD HH:MM:SS.000000" Add an expiry date guard
--expiry-message "..." Message shown when expired (default: "This file has expired.")
--pip PKG1 PKG2 ... Auto-install packages on first run
--check-version Lock script to the current Python major.minor version
--telegram-bot-token TOKEN Telegram channel guard — bot token
--telegram-channel-id @channel Telegram channel guard — channel id
-o / --output FILE Output file path (default: <input>.enc.py)

Examples

# Encode strings + 3 bytecode layers
pyprivate-obf script.py --encode-strings --bytecode --layers 3

# CPython (native binary) obfuscation
pyprivate-obf script.py --cpython

# Add an expiry date
pyprivate-obf script.py --bytecode --expiry "2025-12-31 23:59:59.000000"

# Auto-install dependencies on first run
pyprivate-obf script.py --bytecode --pip requests numpy pillow

# Lock to current Python version
pyprivate-obf script.py --bytecode --check-version

# Telegram channel membership gate
pyprivate-obf script.py --bytecode \
  --telegram-bot-token 123456:ABCdef \
  --telegram-channel-id @mychannel

# Chain everything with a custom output path
pyprivate-obf script.py --encode-strings --bytecode --layers 2 \
  --check-version -o protected.py

Encoding Methods

There are four independent encoding methods. They live in pyprivate_obf/encoding_methods/ and each one accepts a source: str and returns an obfuscated str.

encode_strings

Rewrites every string literal in the source as bytes([...]).decode().

pyprivate-obf script.py --encode-strings

Before:

print("hello world")

After:

print(bytes([104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]).decode())

bytecode_obfuscation

Compiles the source, serialises it with marshal, then swaps a known opcode pattern in the bytecode so it cannot be cleanly disassembled with stock dis. Output format:

import marshal
exec(marshal.loads(b'...'))
pyprivate-obf script.py --bytecode
pyprivate-obf script.py --bytecode --layers 5   # 5 nested marshal layers

cpython_obfuscation

Compiles the source to C using Cython --embed, strips the compressed string-table sections so only clean ASCII C code remains, then wraps it in a Python launcher that writes the .c file to .py_private/<timestamp>, compiles it with GCC, and runs the native binary.

Requires: cython (pip) + gcc + Python headers.

pyprivate-obf script.py --cpython

The output .py file contains only the clean C source as a plain string — no binary or base64 data.


simple_marshal

Plain marshal wrap with no opcode swap. Used as a fallback when no encoding method is selected, and in DEBUG mode.

# applied automatically when no --bytecode / --cpython flag is given
pyprivate-obf script.py

Guard Layers

Guards are injected at the top of the output script before encoding. Multiple guards can be combined.

Expiry Time

Refuses to run after a given date and time.

pyprivate-obf script.py --expiry "2025-06-30 23:59:59.000000"
pyprivate-obf script.py --expiry "2025-06-30 23:59:59.000000" --expiry-message "License expired."

Python Version Lock

Refuses to run on any Python version other than the one used to obfuscate.

pyprivate-obf script.py --check-version

Pip Installer

Auto-installs missing packages on first run.

pyprivate-obf script.py --pip requests numpy pillow

Telegram Channel Guard

Verifies that the user has joined a Telegram channel before allowing execution.

pyprivate-obf script.py \
  --telegram-bot-token 123456:ABCxyz \
  --telegram-channel-id @mychannel

Python API

Use the encoders and guards directly from Python:

from pyprivate_obf import encode_strings, bytecode_obfuscation
from pyprivate_obf import ExpiryTime, CheckVersion, LibrariesInstaller, EnterChannel

source = open("script.py").read()

# Encode strings
source = encode_strings(source)

# Bytecode obfuscation
source = bytecode_obfuscation(source)

# CPython obfuscation (requires cython + gcc)
from pyprivate_obf.encoding_methods.cpython_obfuscation import cpython_obfuscation
source = cpython_obfuscation(source)

# Add expiry guard
source = ExpiryTime(
    time="2025-12-31 23:59:59.000000",
    message="This script has expired."
).get_new_source(source)

# Add pip installer guard
source = LibrariesInstaller(
    package_names=["requests", "numpy"]
).get_new_source(source)

# Add Python version lock
source = CheckVersion().get_new_source(source)

# Add Telegram channel guard
source = EnterChannel(
    bot_token="123456:ABCxyz",
    channel_id="@mychannel"
).get_new_source(source)

with open("protected.py", "w") as f:
    f.write(source)

Credits

This project is a reverse-engineered Python reconstruction of the Py Private v4.1.2 Android application.

The original encoder was authored by the PSH Team: t.me/psh_team

The APK was decompiled using apktool. The inner Python source was bundled via Chaquopy as .pyc files (Python 3.9 bytecode) inside assets/chaquopy/app.imy. Each .pyc was decompiled and reconstructed into clean Python source.


License

MIT © pooraddyy

Release files for pyprivate-obf 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyprivate-obf 1.0.0
File Size Uploaded
pyprivate_obf-1.0.0.tar.gz 18.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pyprivate-obf 1.0.0
File Interpreter ABI Platform
pyprivate_obf-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 38.8 kB

Release files / pyprivate_obf-1.0.0.tar.gz

Download URL pyprivate_obf-1.0.0.tar.gz
Size 18.7 kB
Tags Source
SHA-256 checksum
How to use checksums
869fb8da3c5435f178536a3902219f971423a935bc86334b1d5a5c1e53496f09
BLAKE2b-256 checksum
How to use checksums
97f34e3ce56a237f4451ea43c111ed166e1cfc44b270fab6652d788f3e69d113
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 20, 2026.

Transparency log

Release files / pyprivate_obf-1.0.0-py3-none-any.whl

Download URL pyprivate_obf-1.0.0-py3-none-any.whl
Size 20.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e86d8adb5961722f9c5d2b6b0a9244e39b0f7d4a3892fcb6dd200dd7f4fb4806
BLAKE2b-256 checksum
How to use checksums
45784b290ca2707f536a5ec0f04ebf0e86a3804b00a8f7254ddd29cc22226bc5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 20, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page