General idea:
Pyinstaller when creates an executable generates .pyc files of the functions or scripts.
These .pyc files are easy to decompile.
So a better security option is to use .pyd files.
We need cython to generate .pyd files.
Read:
https://medium.com/analytics-vidhya/how-to-create-executable-of-your-python-application-from-linux-windows-mac-bcbcdd4603d4
https://programming.vip/docs/decompile-pyinstaller-packaged-exe-installation-package.html
https://github.com/extremecoders-re/pyinstxtractor/
Step 1: creating an executable .exe file.
Need: pyinstaller
pip install pyinstaller
then run:
pyinstaller yourfile.py
this will create an exe field in the dist directory - dist is the dir we are interested in not build
but in the dist dir there are supporting files as well,
to create a single executable file use:
pyinstaller yourfile.py --onefile
or
pyinstaller -F simpleprogram.py
The problem:
This exe can be decompiled to view source code.
Decompiling:
https://github.com/extremecoders-re/pyinstxtractor/
python pyinstxtractor.py yourfile_single.exe
You will see yourfile_single.exe_extracted folder which has .pyc file of your original source code which can be decompiled - we are not doing that now but it can be decompiled.
Read: https://programming.vip/docs/decompile-pyinstaller-packaged-exe-installation-package.html
Since .pyc file can be decompiled we are going to create a .pyd files for our functions
we create a separate file yourfile_support.py which contains the main code and yourfile.py which will import from yourfile_support.py and run the code, so yourfile.py doesn't do much but calls support file.
So first before compiling with pyinstaller we convert our yourfile_support.py to yourfile_support.py yourfile_support.pyd
when there are both .py and .pyd files in the folder, .pyd has preference over py and .pyd is difficult to decompile.
Creating .pyd
We need cython. Anaconda usually comes with cython but if you don't have install it.
Converting yourfile_support.py to yourfile_support.pyd:
first create another .py file named "build_pyd.py" having the following code:
# -*- coding: utf-8 -*-
"""
Created on Wed Aug 29 13:33:20 2018
@author: Li Zeng hai
"""
from distutils.core import setup
from Cython.Build import cythonize
setup(
name = 'any words.....',
ext_modules = cythonize(["yourfile_support.py",
]
),
)
Save it and then run:
python build_pyd.py build_ext --inplace
This will generate pyd file.
got error: error: Unable to find vcvarsall.bat
installed visual c++2015 build tools from:
http://go.microsoft.com/fwlink/?LinkId=691126&fixForIE=.exe.
worked!
It will generate something like simplefunction.cp37-win_amd64.pyd
rename it to simplefunction.pyd
delete all temp files and now do:
pyinstaller -F simpleprogram.py
Now do
python pyinstxtractor.py yourfile_single.exe
now in the extracted folder you cannot see simplefunction.pyc
you can only see: simplefunction.pyd
--------------------- Best way that does all -------------
pyarmor
pip install pyarmor
we need pyinstaller preinstalled
pip install pyinstaller
Then just run
pyarmor pack --clean -e "--onefile " main.py
*the space after --onefile is intentional
sometimes pyinstaller will give recursion error - this is probably because the environment has a lot of files
so create an new anaconda enviornment, install only the required packages and run pyarmor - no errors
for gui apps:
pyarmor pack --clean -e "--onefile -w " main.py