Skip to main content

Python程序保护最佳实践

Python程序介绍#

Python是一种高级的、解释型的、面向对象的编程语言,python代码简洁易读,并且Python语言跨平台,拥有丰富的标准库和第三方库,深受开发人员的喜爱。

python程序常见扩展名

操作系统文件类型
windows/Linux/mac等系统py
pyc
pyd/pyz/pyx等

Python程序的安全性问题#

由于Python是一个面向字符串流的解释执行的特点,引发了安全问题,使用者执行Python程序时, python解释器需要通过Python源码来解释执行,即便是编译成pyc,也有工具可以直接反编译回Python代码,与源代码几乎大差不差, 因此Python软件的安全性变得尤为关键。

我们的python保护是一个字节码级别的保护技术,它能保证python脚本被直接反编译和修改的风险,确保Python脚本在部署后依然安全可靠。

支持范围#

特点#

1.字节码级别的保护:我们的保护技术在Python字节码级别进行保护,在整个Python程序执行过程中,没有源代码的存在,并且python反汇编函数无法正常反汇编出字节码。

2.实时加密和解密: Python字节码是被加密的,仅在执行之前进行解密,代码体执行完毕后会重新加密字节码,从而避免了脚本在内存中一次性全部dump出来。

3.高兼容性: 保护后的脚本大部分情况下能直接和之前未被保护的脚本无缝替换。

4.兼容多Python版本: 保护后的脚本可以在3.6-3.13之间的Python版本执行。

5.无缝替换的要求:Python解释器可以正确加载 virbox_pyruntime包里的C扩展库virbox_pyruntime包, 但virbox_pyruntime库需要有可写权限。

6.和DS方式保护进行对比:

dsprotectorpyprotector
部署需要对python保护,加入ds插件后,替换执行的python无需修改python
安全性可以从内存中dump出python源代码在内存中以代码对象(二进制)形式体现

语言环境#

1.保护环境:

不依赖电脑系统上的python版本,有无python版本均可保护。

该保护方式目前只支持py文件,不支持pyc的保护。

2.保护后的Python运行环境:

3.6-3.13版本

注:如果操作系统本身不支持python3.12或3.13,则无法加壳成功。

运行环境#

操作系统x86x64arm32arm64
Windows✔️✔️N/A暂不支持
Linux✔️✔️✔️✔️
macOSN/A✔️N/A✔️

执行过程#

保护的python文件执行的过程:

1.加载virbox_pyruntime模块;

2.调用virbox_pyruntime模块中virbox函数, 校验脚本是否被修改等,修复字节码加密函数,字节码解密函数,字符串/属性解密函数,检验函数;

3.执行代码对象;

4.在函数头解密字节码体;

5.在函数尾加密字节码体。

基础功能介绍#

加密选项#

函数校验

运行时校验函数,防止在内存动态替换。

模块校验

运行时校验导入的Python模块,防止被替换。

字符串加密

加密python代码中的字符串,提升逆向难度。

属性名称加密

加密python代码中的类属性。

局部变量混淆

将python函数中的局部变量重命名为无意义的字符串。

字节码动态加密

仅在函数执行时解密。

防篡改

禁止被保护的脚本添加其他的代码(注释可以添加)。

代码对象名称混淆

重命名代码对象的名称,防止推断代码逻辑。

运行平台#

由于python脚本可跨平台使用,将python脚本拖入到Virbox Protector工具界面,会自动显示支持的平台。如图所示:

以上分别表示windows(x86和x64架构)、Linux(x86和x64架构)、Arm Linux(arm32和arm64架构)、macOS(x64架构和arm64架构),可根据自己需要的平台进行勾选。

注:若一个运行平台都不勾选,则会保护不成功,提示"至少选择一个运行平台"。

打包#

功能介绍#

由于保护后的python脚本目录里带有pyruntime库,运行时需要使用pyruntime库去进行解密运行,若将python脚本打包成一个可执行文件,打包时未将pyruntime库打包进去,则打包后的程序无法运行。

为了方便用户进行打包,故加壳工具界面上提供打包选项,在加密时勾选该选项,则会自动将加密后的python脚本和pyruntime打包进可执行程序内。

打包过程#

1.点击"启用打包";

2.选择Python解释器,并确保选择的python.exe同目录的Scripts目录下安装了pyinstaller;

列表默认显示添加进环境变量里的python,也可添加其他路径下的python;

3.在保护前生成spec文件,确保未保护的python脚本能使用spec文件打包成功且打包后的文件能正常运行,然后在加壳工具界面上选择Spec文件;

4.点击"保护选中项目";

5.保护成功后在***_protected\dist里有打包成功后的可执行文件。

操作指引#

界面操作#

1.将包含py文件的文件夹拖入到加壳工具界面;

2.下载Python扩展包,网址:https://shell.virbox.com/down.html

3.点击安装扩展包,直接加载下载的python_extension.zip即可。

4.加密选项处根据自己需求选择;

5.Python Files选项处,会列出后缀名为py的文件;

Python密码:

1)当加密的py文件之间存在依赖关系时,若两次加壳的密码设置不同,则保护后的py文件无法通用,密码设置相同则可以通用;2)当加密的py文件之间不存在依赖关系时,若两次加壳的密码设置不管相同与否,保护的后py文件可正常使用。

6.选择保护,则会生成XXX_protected文件夹,其中项目结构中会多出了一个virbox_pyruntime包,执行保护后的代码必须依靠virbox_pyruntime包中的C扩展库。

注意:1.若执行的py文件同目录下没有此文件夹,则会运行失败。2.可以将virbox_pyruntime文件夹放到python环境的目录下,则保护后的py同目录下不需要virbox_pyruntime文件夹也可以运行。

命令行操作#

命令行工具环境#

python的命令行工具pyprotector_con 的默认路径位于:

Windows:正式版:C:\Program Files\senseshield\Virbox Protector 3\bin\pyprotector_con.exe试用版:C:\Program Files\senseshield\Virbox Protector 3 Trial\bin\pyprotector_con.exe
Linux:正式版:/usr/share/virboxprotector/bin/pyprotector_con试用版:/usr/share/virboxprotector-trial/bin/pyprotector_con
macOS:正式版:/Applications/Virbox Protector 3.app/Contents/MacOS/bin/pyprotector_con试用版:/Applications/Virbox Protector 3 trial.app/Contents/MacOS/bin/pyprotector_con

命令行参数#

1.加密选项

选项命令行默认选项
安装扩展包--install=<zip_path>0
指定py保护后运行的python版本--target-python-version=0
函数检验--function-check=<value>0
模块检验--module-check=<value>0
字符串加密--str-enc=<value>0
属性名加密--attr-enc=<value>0
局部变量混淆--local-var-rename=<value>1
字节码动态加密--bc-dyn-enc=<value>1
代码对象名称混淆--co-rename=<value>1
过滤指定的文件不保护--excludes=0
输出文件夹路径-o=<output_path>0

2.打包选项

选项命令行默认选项
启用打包--pack=<value>0
Python解释器--interpreter=<value>0
PyInstaller Spec路径--spec-path=<value>0
指定配置文件-x0

2.命令行举例

1)命令安装扩展包,命令参考:

"C:\Program Files\senseshield\Virbox Protector 3\bin\pyprotector_con.exe" --install=D:\Desktop\python_extension.zip

2)过滤嵌套的文件夹里的py,命令参考:

"C:\Program Files\senseshield\Virbox Protector 3\bin\pyprotector_con.exe" <py-demo> --excludes=<py-demo>/<dirs> -o <py-demo_protected>

3)过滤单个py文件,命令参考:

"C:\Program Files\senseshield\Virbox Protector 3\bin\pyprotector_con.exe" <py-demo> --excludes=*/demo.py -o <py-demo_protected>

或者--excludes=指定py的全路径也可过滤。

4)对程序进行保护(开启函数检查/字符串加密/字节码动态加密选项),命令参考:

"C:\Program Files\senseshield\Virbox Protector 3\bin\pyprotector_con.exe" <py-demo> --function-check=1 --str-enc=1 --bc-dyn-enc=1 -o <py-demo_protected>

5)对程序进行保护后,需要指定的python版本才能运行(比如指定版本为3.9,则必须python3.9版本才能运行加密后的py文件),命令参考:

"C:\Program Files\senseshield\Virbox Protector 3\bin\pyprotector_con.exe" <py-demo> --target-python-version=3.9 -o <py-demo_protected>

6)对程序进行保护,并将加密后的python打包成可执行文件,命令参考:

"C:\Program Files\senseshield\Virbox Protector 3\bin\pyprotector_con.exe" <py-demo> --pack=1 --interpreter="E:/Program Files/Python310/python.exe" --spec-path="D:/Desktop/python/main.spec" -o <py-demo_protected>

运行部署#

上述的保护方式不区分环境,保护后的py文件和保护前的py文件运行方式一样。

性能结果#

结果:

字符串加密、属性加密是最影响性能的,其他功能基本上没有什么影响。

是因为字符串加密、属性加密的数量比较多导致的,但是整个程序运行过程中,只解密一次,所以首次运行会有影响,运行过程中不会有影响。

以支持向量(support vector)算法为例,使用cProfile工具记录调用几百万次函数的时间对比结果如下:

注:黑色虚线为原程序运行结果,其他为加密时的各个选项功能的运行结果。

问题#

1.如何生成spec文件?

答:找到运行的主python文件比如main.py,执行pyintaller -F main.py,然后把生成的其他文件都删除,保留main.spec文件即可。

2.当py文件和资源文件同目录时,如何配置spec文件?

当py文件和资源文件不同目录,比如资源文件在res目录下,res目录和py文件同级目录,spec应该如何配置

比如文件层级目录如下,spec应该如何配置,参考如图所示:

比如文件层级目录如下,spec应该如何配置,参考如图所示: