Pyinstaller使用cython防止反编译
Python 2023-02-18
使用pyinstaller将python的py文件编译成可执行exe文件,移植到其他机器使用,比较方便。但是,容易被反编译,泄露代码。
反编译主要是exe反编译成pyc文件,可以很轻松的得到源代码。
exe反编译工具:pyinstxtractor.py
pyc反编译工具:Easy Python Decompiler 或者在线反编译pyc。
如何防止反编译呢?可以考虑将模块py文件编译为动态链接库,这样破解难度将大大增加。其中,在python里,pyd格式即动态链接库。使用cython即可将py文件编译成pyd文件。
下面是详细的教程。
先看我的程序结构:
test文件夹下有三个文件。其中my_fun.py是我的程序文件。
为了加密编译,需要增加两个文件,即:build_pyd.py和main.py,具体代码和功能后面介绍。
1、安装Cython
pip install Cython
2、编写build_pyd.py
其内容如下:
from distutils.core import setup
from Cython.Build import cythonize
setup(
name='any words.....',
ext_modules=cythonize(["my_fun.py",
]
),
)
3、在test文件夹下执行以下cmd命令:
python build_pyd.py build_ext --inplace会在test文件夹下生成一个build文件夹和一个my_fun.cp37-win_amd64.pyd,这个文件就是我们需要的pyd文件了。(其余新生成的文件忽略,不用看)
如下图:

my_fun.cp37-win_amd64.pyd,说明是python3.7版本的,64位windows系统生成的。
需要将他的名字改为my_fun.pyd,以便后续编译使用。
4、编写main.py
先看看我的my_fun.py代码,main.py代码与他有关。
import sys
import requests
import base64
import os
def add(a,b):
c=a+b
return c
看main.py代码就清楚了:
import sys
import requests
import base64
import os
from my_fun import *
if __name__ == '__main__':
print(add(1,2))
main.py引用了my_fun.pyd(my_fun.pyd和my_fun.py同时存在,优先引用my_fun.pyd)。 并且,main.py调用了程序add(a,b)。 注意,我还引用了:
import sys
import requests
import base64
import os
这些在my_fun.py中引用了,但是,生成pyd以后,pyinstaller就不知道了,所以需要在main.py里引用一下。
这就是那个大坑,如果不在引用main.py,编译出来的程序是没有这些引用的库的,会造成程序出错。
这些在my_fun.py中引用了,但是,生成pyd以后,pyinstaller就不知道了,所以需要在main.py里引用一下。
这就是那个大坑,如果不在引用main.py,编译出来的程序是没有这些引用的库的,会造成程序出错。
当然,还有另一种解决方案,就是用pyinstaller编译时增加一个参数。--hidden-import=sys --hidden-import=requests ……
这样写起来比较麻烦,不如在main.py中调用简单。
至此,代码编写完毕,开始编译main.py就可以了。
pyinstaller -w main.py
生成文件如下图:

生成的文件在dist/main文件夹下(因为编译的是main.py),很多文件,因为有库的引用。main.exe是我的程序文件。
而my_fun.pyd被原封不动的搬了过来,说明编译过程中用了my_fun.pyd,而不是my_fun.py。
至此,大功告成,运行看看,程序正常运行。