1.1. Getting Started¶
New to Pyarmor? Well, you came to the right place: read this material to quickly get up and running.
Content
1.1.1. What’s Pyarmor¶
Pyarmor is a command line tool used to obfuscate Python scripts, bind obfuscated scripts to fixed machine or expire obfuscated scripts.
Key Features:
- The obfuscated scritpt is still a normal
.py
script, in most of cases the original python scripts can be replaced with obfuscated scripts seamlessly. - Provide many options to obfuscate the scripts to balance security and performance
- Rename functions/methods/classes/variables/arguments, irreversible obfuscation
- Convert part of Python functions to C function, irreversible obfuscation
- Bind obfuscated scripts to fixed machine or expire obfuscted scripts
- Protect obfuscated scripts by Themida (Only for Windows)
1.1.2. Installation from PyPI¶
Pyarmor packages are published on the PyPI. The preferred tool for installing packages from PyPI is pip. This tool is provided with all modern versions of Python.
On Linux or MacOS, you should open your terminal and run the following command:
$ pip install -U pyarmor
On Windows, you should open Command Prompt (Win-r and type cmd) and run the same command:
C:\> pip install -U pyarmor
After installation, type pyarmor --version on the command prompt. If everything worked fine, you will see the version number for the Pyarmor package you just installed.
1.1.3. Obfuscating one script¶
Here it’s the simplest command to obfuscate one script foo.py
:
$ pyarmor gen foo.py
The command gen
could be replaced with g
or generate
:
$ pyarmor g foo.py
$ pyarmor generate foo.py
This command generates an obfuscated script dist/foo.py
, which is a
valid Python script, run it by Python interpreter:
$ python dist/foo.py
Check all generated files in the default output path:
$ ls dist/
... foo.py
... pyarmor_runtime_000000
There is an extra Python package pyarmor_runtime_000000
, which is
required to run the obfuscated script.
1.1.3.1. Distributing the obfuscated script¶
Only copy dist/foo.py
to another machine doesn’t work, instead copy
all the files in the dist/
.
Why? It’s clear after checking the content of dist/foo.py
:
from pyarmor_runtime_000000 import __pyarmor__
__pyarmor__(__name__, __file__, ...)
Actually the obfuscaetd script can be taken as normal Python script with
dependent package pyarmor_runtime
, use it as it’s not obfuscated.
Note
The obfuscated scripts could be run by Python interpreter without Pyarmor, DO NOT install Pyarmor in the Target Device
1.1.4. Obfuscating one package¶
Now let’s do a package. -O
is used to set output path
dist2
different from the default:
$ pyarmor gen -O dist2 src/mypkg
Check the output:
$ ls dist2/
... mypkg
... pyarmor_runtime_000000
$ ls dist2/mypkg/
... __init__.py
All the obfuscated scripts in the dist2/mypkg
, test it:
$ cd dist2/
$ python -C 'import mypkg'
If there are sub-packages, using -r
to enable recursive mode:
$ pyarmor gen -O dist2 -r src/mypkg
1.1.4.1. Distributing the obfuscated package¶
Also it works to copy the whole path dist2
to another machine. But
it’s not convience, the better way is using -i
to generate all
the required files inside package path:
$ pyarmor gen -O dist3 -r -i src/mypkg
Check the output:
$ ls dist3/
... mypkg
$ ls dist3/mypkg/
... __init__.py
... pyarmor_runtime_000000
Now everything is in the package path dist3/mypkg
, just copy the
whole path to any target machine.
Note
Comparing current dist3/mypkg/__init__.py
with above section
dist2/mypkg/__init__.py
to understand more about obfuscated
scripts
1.1.5. Expiring obfuscated scripts¶
It’s easy to set expire date for obfuscated scripts by -e
. For
example, generate obfuscated script with the expire date to 30 days:
$ pyarmor gen -O dist4 -e 30 foo.py
Run the obfuscated scripts dist4/foo.py
to verify it:
$ python dist4/foo.py
It checks network time, make sure your machine is connected to internet.
Let’s use another form to set past date 2020-12-31
:
$ pyarmor gen -O dist4 -e 2020-12-31 foo.py
Now dist4/foo.py
should not work:
$ python dist4/foo.py
If expire date has a leading .
, it will check local time other than
NTP server. For examples:
$ pyarmor gen -O dist4 -e .30 foo.py
$ pyarmor gen -O dist4 -e .2020-12-31 foo.py
For this form internet connection is not required in target machine.
Distributing the expired script is same as above, copy the whole directory
dist4/
to target machine.
1.1.6. Binding obfuscated scripts to device¶
Suppose got target machine hardware informations:
IPv4: 128.16.4.10
Enternet Addr: 00:16:3e:35:19:3d
Hard Disk Serial Number: HXS2000CN2A
Using -e
to bind hardware information to obfuscated scripts. For
example, bind dist5/foo.py
to enternet address:
$ pyarmor gen -O dist5 -b 00:16:3e:35:19:3d foo.py
So dist5/foo.py
only could run in target machine.
It’s same to bind IPv4 and serial number of hard disk:
$ pyarmor gen -O dist5 -b 128.16.4.10 foo.py
$ pyarmor gen -O dist5 -b HXS2000CN2A foo.py
It’s possible to combine some of them. For example:
$ pyarmor gen -O dist5 -b "00:16:3e:35:19:3d HXS2000CN2A" foo.py
Only both enternet address and hard disk are matched machine could run this obfuscated script.
Distributing scripts bind to device is same as above, copy the whole
directory dist5/
to target machine.
1.1.7. Packaging obfuscated scripts¶
Remeber again, the obfuscated script is normal Python script, use it as it’s not obfuscated.
Suppose package mypkg
structure like this:
projects/
└── src/
└── mypkg/
├── __init__.py
├── utils.py
└── config.json
First make output path projects/dist6
for obfuscated package:
$ cd projects
$ mkdir dist6
Then copy package data files to output path:
$ cp -a src/mypkg dist6/
Next obfuscate scripts to overwrite all the .py
files in
dist6/mypkg
:
$ pyarmor gen -O dist6 -i src/mypkg
The final output:
projects/
├── README.md
└── src/
└── mypkg/
├── __init__.py
├── utils.py
└── config.json
└── dist6/
└── mypkg/
├── __init__.py
├── utils.py
├── config.json
└── pyarmor_runtime_000000/__init__.py
Comparing with src/mypkg
, the only difference is dist6/mypkg
has an extra sub-package pyarmor_runtime_000000
. The last thing is
packaging dist6/mypkg
as your prefer way.
New to Python packaging? Refer to Python Packaging User Guide
1.1.8. Something need to know¶
There is binary extension module pyarmor_runtime
in extra
sub-package pyarmor_runtime_000000
, here it’s package content:
$ ls dist6/mypkg/pyarmor_runtime_000000
... __init__.py
... pyarmor_runtime.so
Generally using binary extensions means the obfuscated scripts require
pyarmor_runtime
be created for different platforms, so they
- only works for platforms which provides pre-built binaries
- may not be compatible with different builds of CPython interpreter
- often will not work correctly with alternative interpreters such as PyPy, IronPython or Jython
For example, when obfuscating scripts by Python 3.8, they can’t be run by Python 3.7, 3.9 etc.
Another disadvantage of relying on binary extensions is that alternative import mechanisms (such as the ability to import modules directly from zipfiles) often won’t work for extension modules (as the dynamic loading mechanisms on most platforms can only load libraries from disk).
1.1.9. What to read next¶
There is a complete installation guide that covers all the possibilities:
- install pyarmor by source
- call pyarmor from Python script
- clean uninstallation
Next is Basic Obfuscation. It covers
- using more option to obfuscate script and package
- using outer file to store runtime key
- localizing runtime error messages
- packing obfuscated scripts and protect system packages
And then Advanced Tutorials, some of them are not available in trial pyarmor
- 2 irreversible obfuscation: RFT mode, BCC mode pyarmor-pro
- Customization error handler
- plugin and hooks
- runtime error internationalization
- cross platform, multiple platforms and multiple Python version
Also you may be instersting in this guide Highest security and performace
1.1.10. How the documentation is organized¶
Pyarmor has a lot of documentation. A high-level overview of how it’s organized will help you know where to look for certain things:
- Part 1: Tutorials now you’re reading.
- Part 2: How To guides are recipes. They guide you through the steps involved in addressing key problems and use-cases. They are more advanced than tutorials and assume some knowledge of how Python works.
- Part 3: References guides contain key concepts, man page, configurations and other aspects of Pyarmor machinery.
- Part 4: Topics guides insight into key topics and provide useful background information and explanation. They describe how it works and how to use it but assume that you have a basic understanding of key concepts.
- Part 5: Licneses describes EULA of Pyarmor, the different Pyarmor licenses and how to purchase Pyarmor license.
Looking for specific information? Try the Index, or the detailed table of contents.