How To Pack Obfuscated Scripts¶
The obfuscated scripts generated by PyArmor can replace Python scripts seamlessly, but there is an issue when packing them into one bundle by PyInstaller:
All the dependencies of obfuscated scripts CAN NOT be found at all
To solve this problem, the common solution is
- Find all the dependenices by original scripts.
- Add runtimes files required by obfuscated scripts to the bundle
- Replace original scipts with obfuscated in the bundle
- Replace entry scrirpt with obfuscated one
PyArmor provides command pack to achieve this. But in some cases maybe it doesn’t work. This document describes what the command pack does, and also could be as a guide to bundle the obfuscated scripts by yourself.
First install pyinstaller
:
pip install pyinstaller
Then obfuscate scripts to dist/obf
:
pyarmor obfuscate --output dist/obf hello.py
Next generate specfile, add the obfuscated entry script and data files required by obfuscated scripts:
pyinstaller --add-data dist/obf/license.lic
--add-data dist/obf/pytransform.key
--add-data dist/obf/_pytransform.*
hello.py dist/obf/hello.py
And patch specfile hello.spec
, insert the following lines after the
Analysis
object. The purpose is to replace all the original scripts with
obfuscated ones:
a.scripts[-1] = 'hello', r'dist/obf/hello.py', 'PYSOURCE'
for i in range(len(a.pure)):
if a.pure[i][1].startswith(a.pathex[0]):
x = a.pure[i][1].replace(a.pathex[0], os.path.abspath('dist/obf'))
if os.path.exists(x):
if hasattr(a.pure, '_code_cache'):
with open(x) as f:
a.pure._code_cache[a.pure[i][0]] = compile(f.read(), a.pure[i][1], 'exec')
a.pure[i] = a.pure[i][0], x, a.pure[i][2]
Run patched specfile to build final distribution:
pyinstaller --clean -y hello.spec
Note
Option –clean is required, otherwise the obfuscated scripts will not be replaced because the cached .pyz will be used.
Check obfuscated scripts work:
# It works
dist/hello/hello.exe
rm dist/hello/license.lic
# It should not work
dist/hello/hello.exe