Pyarmor

Pyarmor is a command line tool used to obfuscate python scripts, bind obfuscated scripts to fixed machine or expire obfuscated scripts. It protects Python scripts by the following ways:

Look at what happened after foo.py is obfuscated by Pyarmor. Here are the files list in the output path dist

    foo.py

    pytransform.py
    _pytransform.so, or _pytransform.dll in Windows, _pytransform.dylib in MacOS

    pyshield.key
    pyshield.lic
    product.key
    license.lic

dist/foo.py is obfuscated script, the content is

   1     from pytransfrom import pyarmor_runtime
   2     pyarmor_runtime()
   3 
   4     __pyarmor__(__name__, __file__, b'\x06\x0f...')

All the other extra files called Runtime Files, which are required to run or import obfuscated scripts. So long as runtime files are in any Python path, obfuscated script dist/foo.py can be used as normal Python script. That is to say, the original python scripts can be replaced with obfuscated scripts seamlessly.

Obfuscate Scripts

How to obfuscate python scripts by Pyarmor?

First compile Python script to code object

    char *filename = "foo.py";
    char *source = read_file( filename );
    PyCodeObject *co = Py_CompileString( source, "<frozen foo>", Py_file_input );

Next change this code object as the following ways

Then serialize this reformed code object, obfuscate it to protect constants and literal strings

    char *string_code = marshal.dumps( co );
    char *obfuscated_code = obfuscate_algorithm( string_code );

Finally generate obfuscated script

    sprintf( buf, "__pyarmor__(__name__, __file__, b'%s')", obfuscated_code );
    save_file( "dist/foo.py", buf );

The obfuscated script is a normal Python script, it looks like this

   1     __pyarmor__(__name__, __file__, b'\x01\x0a...')

Run Obfuscated Scripts

What happens to run obfuscated script dist/foo.py by Python Interpreter?

The first 2 lines, which called Bootstrap Code

   1     from pytransfrom import pyarmor_runtime
   2     pyarmor_runtime()

It will fulfil the following tasks

The next code line in dist/foo.py is

   1     ...
   2 
   3     __pyarmor__(__name__, __file__, b'\x01\x0a...')

__pyarmor__ is called, it will import original module from obfuscated code

    static PyObject *
    __pyarmor__(char *name, char *pathname, unsigned char *obfuscated_code)
    {
        char *string_code = restore_obfuscated_code( obfuscated_code );
        PyCodeObject *co = marshal.loads( string_code );
        return PyImport_ExecCodeModuleEx( name, co, pathname );
    }

After that, in the runtime of this python process

Usage

Install

    pip install pyarmor

Obfuscate Scripts

    cd /path/to/pyarmor
    python pyarmor.py obfuscate --src=examples/simple --entry=queens.py

Run Obfuscated Scripts

    cd dist
    python queens.py

Bind obfuscated scripts to fixed machine and expire it on some day. By default the obfuscated scripts can run in any machine and never expired, this behavior can be changed by replacing runtime file dist/license.lic

    cd /path/to/pyarmor
    python pyarmor.py licenses --expired "2018-12-31" --bind-mac "70:f1:a1:23:f0:94" Jondy
    cp licenses/Jondy/license.lic dist/

    cd dist
    python queens.py

Support Platforms

Besides, pyarmor works well with py2exe and PyInstaller. Here are some examples.


CategoryDistutilsCookbook

Pyarmor (last edited 2018-11-06 04:21:54 by JondyZhao)

Unable to edit the page? See the FrontPage for instructions.