交付出去的 Python 项目,代码暴露有两个环节:磁盘上的源码可以被直接阅读,字节码可能被反编译;运行中的字节码可能在内存中被 dump 出来。只处理其中一个,另一个仍然可被分析。项目交给客户、集成商或合作方部署后,源码、算法和业务规则会离开开发团队的控制范围,交付形式可能是 .py 文件、编译后的 .pyc 文件,或经 PyInstaller 打包后的可执行程序。授权判断、核心算法、模型调用、接口地址和数据处理流程,都处在被反编译或修改的风险之中。
Virbox Protector(VBP)面向 Python 脚本提供字节码级别的保护,并提供多种可以组合的加密选项。保护前需要先确定要处理的 .py 文件和加密选项,目标运行环境也要一并确认。
Python 脚本为什么容易被反编译
Python 是一种高级的、解释型的、面向对象的编程语言,代码简洁易读,语言本身跨平台,拥有丰富的标准库和第三方库。作为脚本语言,Python 由解释器直接通过源码(字符流)解释执行。.py 文件中直接保存源码,阅读、修改和复制都不需要专门工具。即便是编译成 .pyc,也有工具可以直接反编译回 Python 代码,与源代码几乎大差不差。
dis 等 Python 标准库工具可以查看字节码,代码中的变量名、函数名、类名和调用关系也会保留下来,为分析者提供明确线索。
不同交付形态的暴露面并不相同:
| 交付形态 | 主要暴露内容 | 常见风险 |
|---|---|---|
.py 源码 | 完整业务逻辑、字符串和调用关系 | 可直接阅读和修改 |
.pyc 编译文件 | 序列化的 PyCodeObject(代码对象) | 可反汇编,多数逻辑可还原为 Python 代码 |
| PyInstaller 等打包程序 | 打包后的代码、依赖和资源 | 可被提取后继续分析 |
哪些 Python 项目和内容需要保护
不同项目交付的 Python 内容并不相同,需要保护的对象通常包括:
- 脚本源码与字节码:交付的
.py源码,以及编译、打包后仍可被还原的字节码; - 关键函数:授权判断、核心算法、模型调用、数据预处理和接口封装等逻辑;
- 字符串与类属性:接口地址、提示信息、协议字段、对象结构和配置字段;
- 导入的 Python 模块:会被加载执行的模块、插件和第三方组件;
- 局部变量与代码对象名称:函数内的局部变量名、代码对象名称等可以推断逻辑的信息;
- 交付脚本的完整性:防止在受保护脚本中添加其他代码。
需要重点评估保护的,通常是 Python 脚本交付后运行在开发方无法持续管理的设备或环境中的项目,例如:
- 商业软件,以 Python 交付其中的算法或业务规则组件;
- 企业应用,部署在客户本地服务器、隔离网络或边缘设备中;
- AI 项目,模型调用和推理调度随程序一起交付;
- 机器视觉与机器人项目,用 Python 协调设备、算法和业务流程;
- 工程脚本,交付给合作伙伴进行集成、二次开发或运维;
- SDK 组件,随产品交付给外部开发者调用。
这些场景的共同点在于,脚本会进入开发方无法持续控制的运行环境,服务器端的权限设置覆盖不到本地脚本,保护方式需要围绕运行环境来设计。
普通打包与数据文件加密的能力边界
面对这些需要保护的内容,先看两类常见做法能覆盖到哪里。
PyInstaller 打包的主要作用是方便程序的分发与部署,它会在打包时自动扫描程序中的代码,智能识别所有引用的 Python 库、必要的动态链接库和解释器本身,用户不必再担心缺少依赖环境。而 pyinstxtractor 这类脚本可以把打包后的程序反编译成 py 文件,从而引发安全性问题。
数据文件加密是另一类做法。DS Protector 可以直接对文件进行加密,应用场景不受文件格式限制,因此可以用于对 Python 脚本和 pyc 文件进行加密。这种方式下,加密后的脚本必须由保护后的 Python.exe 执行;程序运行时会恢复出解释器可以读取的内容,具备调试能力的分析者仍可将其转储为 pyc 文件,再用 uncompyle6、pycdc 之类的工具反编译。
以上两种做法处理的都是磁盘上的文件形态,脚本一旦运行,代码仍会以解释器能够读取的形式出现,运行中的脚本不在它们的覆盖范围内。
VBP 如何保护 Python 脚本
VBP 对 Python 脚本的保护对应交付后的两个环节:让磁盘上的字节码不可读,让内存中不出现完整的可还原代码,同时通过运行时校验识别对脚本和模块的修改。
字节码加密:磁盘上不留可读代码
VBP 的 Python 保护是一种字节码级别的保护技术:先把 Python 脚本编译为代码对象(Code Object),再对代码对象中的字节码进行加密。保护后的脚本在整个执行过程中都没有源代码的存在,Python 反汇编函数无法正常反汇编出字节码。
实时加密和解密:内存中不出现完整代码
执行保护后的代码必须依靠 virbox_pyruntime 包中的 C 扩展库,这个扩展库本身通常也做了代码保护。保护的 Python 文件执行过程如下:
受保护的 Python 脚本
|
v
加载 virbox_pyruntime 模块
|
v
调用 virbox_pyruntime 模块中的 virbox 函数,校验脚本是否被修改等,修复字节码加密函数、字节码解密函数、字符串/属性解密函数和检验函数
|
v
执行代码对象
|
v
在函数头解密字节码体
|
v
在函数尾加密字节码体
Python 字节码是被加密的,仅在执行之前进行解密,代码体执行完毕后会重新加密字节码,从而避免了脚本在内存中一次性全部 dump 出来;受保护脚本在内存中以代码对象(二进制)形式体现。
运行时校验与防篡改:识别对脚本和模块的修改
运行时校验会检查脚本是否被修改,覆盖函数、导入的 Python 模块和脚本本身的完整性,对应函数校验、模块校验和防篡改三个选项。
加密选项:八项能力按需组合
VBP 共提供八个加密选项,可以组合使用。字节码动态加密对应实时加密和解密机制,函数校验、模块校验和防篡改对应运行时校验,其余四个按内容类型叠加:
| 加密选项 | 作用 |
|---|---|
| 函数校验 | 运行时校验函数,防止在内存动态替换 |
| 模块校验 | 运行时校验导入的 Python 模块,防止被替换 |
| 字符串加密 | 加密 Python 代码中的字符串,提升逆向难度 |
| 属性名称加密 | 加密 Python 代码中的类属性 |
| 局部变量混淆 | 将 Python 函数中的局部变量重命名为无意义的字符串 |
| 字节码动态加密 | 仅在函数执行时解密 |
| 防篡改 | 禁止被保护的脚本添加其他的代码(注释可以添加) |
| 代码对象名称混淆 | 重命名代码对象的名称,防止推断代码逻辑 |
以支持向量(support vector)算法为例,使用 cProfile 工具记录调用几百万次函数的时间对比,字符串加密、属性名称加密是最影响性能的,其他功能基本上没有什么影响;原因是字符串和属性的数量比较多,但整个程序运行过程中只解密一次,所以影响集中在首次运行,运行过程中不会有影响。选择加密选项时结合调用频率评估,对调用频率很高的函数,应在目标 Python 版本、操作系统和 CPU 架构下实测保护后的性能表现。
保护效果如何验证
Python 脚本保护是否达到目标,可以通过以下几项检查:
- 打开受保护
.py文件后,是否还能直接阅读源码; - 使用
dis等反汇编工具,能否正常反汇编出受保护脚本的字节码; - 在函数执行前后 dump 内存,字节码体在函数执行结束后是否重新加密;
- 在受保护产物中检索字符串、类属性和代码对象名称,可检索线索是否已经减少;
- 修改脚本或替换依赖模块后,运行时校验能否识别这些改动;
- 目标 Python 版本、操作系统和 CPU 架构下,功能是否保持一致;
- 首次加载、核心函数调用和长时间运行场景是否达到性能要求;
- PyInstaller 等打包产物是否包含 pyruntime 库并能够正常启动;
- 交付产物中是否仍残留源码、调试文件、测试脚本或未保护模块。
验证时应同时保留未保护版本的功能结果和性能基线,对保护后的脚本执行完整回归测试。如果只检查文件能否打开或程序能否启动,无法覆盖模块调用、异常处理、并发执行和跨平台部署中的问题。
VBP 支持哪些 Python 版本和运行环境
保护阶段不依赖电脑系统上的 Python 版本,有无 Python 版本均可保护;该保护方式目前只支持 py 文件,不支持 pyc 的保护。
保护后的脚本可以在 3.6-3.14 之间的 Python 版本执行。如果操作系统本身不支持 Python 3.12、3.13 或 3.14,则无法加壳成功。
运行环境:
| 操作系统 | x86 | x64 | arm32 | arm64 |
|---|---|---|---|---|
| Windows | ✔️ | ✔️ | N/A | 暂不支持 |
| Linux | ✔️ | ✔️ | ✔️ | ✔️ |
| macOS | N/A | ✔️ | N/A | ✔️ |
N/A 表示该组合不在支持范围内。上述保护方式不区分环境,保护后的 py 文件和保护前的 py 文件运行方式一样。跨平台项目仍需要在目标操作系统、CPU 架构和 Python 版本上分别验证。
部署与兼容性注意事项
保护后的脚本大部分情况下能直接和之前未被保护的脚本无缝替换。实际部署和运行时需要注意以下几点:
- 运行时必须能加载
virbox_pyruntime包中的 C 扩展库,且该库需要有可写权限;通常将virbox_pyruntime文件夹放在执行的 py 文件同目录下,也可以放到 Python 环境的目录下,缺少该文件夹会运行失败; - 存在依赖关系的 py 文件分批加壳时,密码设置必须相同,否则保护后的文件无法相互通用;无依赖关系的文件不受密码影响;
- 使用 PyInstaller 等工具打包成可执行文件时,必须把 pyruntime 库一并打包进去,否则打包后的程序无法运行;VBP 提供打包选项,勾选后会自动将加密后的脚本和 pyruntime 打包进可执行程序;
- 字节码保护处理的是脚本被反编译和被修改的风险,运行时产生的输入输出、内存数据仍然可能被观察;调试、Hook 这类行为需要结合运行时防护一并评估。
对部署到客户现场、合作伙伴环境或离线设备中的 Python 项目来说,文件形态会被打包方式改变,运行时的代码形态才是判断保护是否有效的依据。
具体配置、命令行参数和部署方式可查阅 VBP 官方《Python 程序保护最佳实践》,也可通过 官方试用入口 进行评估。
相关阅读
- Virbox Protector 大模型安全:模型文件和 Python 代码怎么保护
- AI 模型交付安全:Virbox Protector 处理五类资产暴露点
- Virbox Protector 机器视觉安全方案:保护代码、模型、工程文件与训练数据
- Virbox Protector 机器人算法资产交付安全方案:二开生态的价值前提是边界可控
深盾科技 · Virbox | 让数字世界充满信任
Virbox Protector(VBP)是一套面向软件交付安全的全栈软件加密与应用加固解决方案,广泛覆盖本地程序、移动应用、Java/.NET/Python、Unity、SDK、静态库、目标文件与 AI 模型等软件资产,帮助企业在交付之后依然保持代码、算法、资源和业务价值可控。
