How PyInstaller decompiles (cracks source code) and prevents decompiling Python files after they are packaged as exe
Share some tips and experiences here.Keep the author's information and article links for sharing, reprinting or citing your hard work.
Author's environment:
win7+python3.5(anaconda3)
Theoretically, systems with win7 and above and any version of python are available.
1. Basic scripts
First, we build a simple script, such as output a series of numbers, text, and so on. Here we output a series of words and calculate the power of three times at the same time.
# -*- coding: utf-8 -*- """ Created on Wed Aug 29 09:18:13 2018 @author: Li Zeng hai """ def test(num): print('num={n}, {n}^3={n2}'.format(n=num, n2=num**3)) if __name__ == '__main__': while 1: try: num = input('Tip: Enter"q"Exit the program.\n Please enter a number:') if num.lower() == 'q': break num = float(num) print(num) except: print('The number you entered is incorrect!') continue test(num)
Save this script as mylib.py and run it:
As you can see, the script is working correctly.
For demonstration purposes, we create a new script into the main.py script file and import the test function from mylib.
# -*- coding: utf-8 -*- from mylib import * while 1: try: num = input('Tip: Enter"q"Exit the program.\n Please enter a number:') if num.lower() == 'q': break num = float(num) print(num) except: print('The number you entered is incorrect!') continue test(num)
2. Package as exe using PyInstaller
Package it as a single exe using the following command (remove-F is not a single exe)
pyinstaller -F main.py
The packaging process is as follows:
E:\t>pyinstaller -F main.py 505 INFO: PyInstaller: 3.3.1 505 INFO: Python: 3.5.5 505 INFO: Platform: Windows-7-6.1.7601-SP1 505 INFO: wrote E:\t\main.spec 505 INFO: UPX is not available. 505 INFO: Extending PYTHONPATH with paths ['E:\\t', 'E:\\t'] 505 INFO: checking Analysis 505 INFO: Building Analysis because out00-Analysis.toc is non existent 505 INFO: Initializing module dependency graph... 521 INFO: Initializing module graph hooks... 521 INFO: Analyzing base_library.zip ... 6269 INFO: running Analysis out00-Analysis.toc 6269 INFO: Adding Microsoft.Windows.Common-Controls to dependent assemblies of final executable required by d:\anaconda3\python.exe 6956 INFO: Caching module hooks... 6956 INFO: Analyzing E:\t\main.py 6956 INFO: Loading module hooks... 6956 INFO: Loading module hook "hook-pydoc.py"... 6956 INFO: Loading module hook "hook-xml.py"... 7283 INFO: Loading module hook "hook-encodings.py"... 7533 INFO: Looking for ctypes DLLs 7549 INFO: Analyzing run-time hooks ... 7549 INFO: Looking for dynamic libraries 7720 INFO: Looking for eggs 7720 INFO: Using Python library d:\anaconda3\python35.dll 7720 INFO: Found binding redirects: [] 7720 INFO: Warnings written to E:\t\build\main\warnmain.txt 7751 INFO: Graph cross-reference written to E:\t\build\main\xref-main.html 7767 INFO: checking PYZ 7767 INFO: Building PYZ because out00-PYZ.toc is non existent 7767 INFO: Building PYZ (ZlibArchive) E:\t\build\main\out00-PYZ.pyz 8345 INFO: Building PYZ (ZlibArchive) E:\t\build\main\out00-PYZ.pyz completed successfully. 8345 INFO: checking PKG 8345 INFO: Building PKG because out00-PKG.toc is non existent 8345 INFO: Building PKG (CArchive) out00-PKG.pkg 9954 INFO: Building PKG (CArchive) out00-PKG.pkg completed successfully. 9954 INFO: Bootloader d:\anaconda3\lib\site-packages\PyInstaller\bootloader\Windows-64bit\run.exe 9954 INFO: checking EXE 9954 INFO: Building EXE because out00-EXE.toc is non existent 9954 INFO: Building EXE from out00-EXE.toc 9954 INFO: Appending archive to EXE E:\t\dist\main.exe 9954 INFO: Building EXE from out00-EXE.toc completed successfully. E:\t>
Finally, build, disk folders are generated in the directory.Where exe file is in disk.It is working properly.As follows:
3. Decompiled Pyinstaller packaged exe
Such exe s can already be migrated to other computers for use, and this is the end if it is for the convenience of other computers.Sometimes, however, we may use this feature for many people, but if you don't want to open source or be cracked by others, this is not enough.
Because at this point exe can be decompiled by others.
Tools used here:
exe decompile tool: pyinstxtractor.py: Click here to download
pyc decompile tool: Easy Python Decompiler Or decompile pyc online.
Place pyinstxtractor.py in the same directory as the exe file and execute the following cmd command:
python pyinstxtractor.py main.exe
If executed successfully, a new decompiled folder, main.exe_extracted, will be generated in the same directory, as shown below:
At the same time, we can find the mylib module, which was introduced by exe at that time, in pyc format, in the path circled below.
pyc format file, decompile is very simple.Using the tools provided in the previous section or finding an online minute decompile on the web, let's look at the results of the decompilation:
#!/usr/bin/env python # visit http://tool.lu/pyc/ for more information ''' Created on Wed Aug 29 09:18:13 2018 @author: Li Zeng hai ''' def test(num): print('num={n}, {n}^3={n2}'.format(n=num, n2=num ** 3)) if __name__ == '__main__': while None: try: num = input( '\xe6\x8f\x90\xe7\xa4\xba\xef\xbc\x9a\xe8\xbe\x93\xe5\x85\xa5"q"\xe9\x80\x80\xe5\x87\xba\xe7\xa8\x8b\xe5\xba\x8f\xe3\x80\x82\n\xe8\xaf\xb7\xe8\xbe\x93\xe5\x85\xa5\xe4\xb8\x80\xe4\xb8\xaa\xe6\x95\xb0\xe5\xad\x97\xef\xbc\x9a') if num.lower() == 'q': break num = float(num) print(num) except: None None None print( '\xe8\xbe\x93\xe5\x85\xa5\xe7\x9a\x84\xe6\x95\xb0\xe5\xad\x97\xe4\xb8\x8d\xe6\xad\xa3\xe7\xa1\xae\xef\xbc\x81') continue
As you can see, the source code is basically decompiled perfectly.Where Chinese is involved, coding problems will change.But the non-Chinese part is almost the same.
Ask you if you are afraid!!!
4. Compile scripts as pyd to prevent decompiling
Fear, hath.
How to solve this problem, consider compiling the module py file into a dynamic link library, which makes cracking more difficult.In python, the pyd format is a dynamic link library.Use cython to compile, and if anaconda comes with it, some pythons may not have cython, just install it:
pip install Cython
We create a new py file in the folder where main.py is located. Here I name it build_pyd.py, which reads as follows:
# -*- 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(["mylib.py", ] ), )
Then execute the following cmd command:
python build_pyd.py build_ext --inplace
The process and results are illustrated below, with the red-box PYD file compiled.Since I am a 64-bit system and python, an amd64 suffix is generated, so we can rename this deletion to mylib.pyd.
Note: When both mylib.pyd and mylib.py exist, the import priority is pyd>py, so PYD is the default import without removing the PY file.
At this point, we delete the build, disk folders, repeat Step 2, and compile to exe again.
Note: Compilation requires a relevant VC environment, as Python 3.5 is based on the VS14 version, so I installed it here as well.It cannot be compiled without installation.
You can verify that:
After decompiling main.exe again, mylib.pyc could not be found under the original path E:\tdist\main.exe_extractedout00-PYZ.pyz_extracted.
Because he is no longer a file that can be decompiled directly.
Where is he? He exists in the upper directory as a pyd.As follows:
pyd's decompilation is quite difficult, so you're done!
Reference link: https://www.lizenghai.com/archives/898.html
https://blog.csdn.net/zy841958835/article/details/79446871
https://blog.csdn.net/HW140701/article/details/93494869 (pyinstaller-F--key=***encrypted pyc prevents decompilation) pycropto needs to be installed during this process, which is cumbersome to install: https://www.cnblogs.com/xiohao/p/11216271.html)