首页 > Python > Pyinstaller使用cython防止反编译

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文件了。(其余新生成的文件忽略,不用看)
如下图:

1

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
 
这里有import,也有def,貌似程序没有用到import的库,没关系,这里是为了演示,因为有个坑,后面会说。 为什么需要增加个main.py呢? 是因为,我的程序文件加密成pyd文件了,但是pyinstaller不能编译pyd文件。我需要用一个main.py文件调用这个pyd,然后pyinstaller编译main.py就可以看了。
看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,编译出来的程序是没有这些引用的库的,会造成程序出错。

当然,还有另一种解决方案,就是用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。

至此,大功告成,运行看看,程序正常运行。