一、PyInstaller
1.切换文件目录
cd "D:\
2.打包
若代码为 import mysql.connector:
pyinstaller -F --hidden-import=mysql.connector jyw111.py
若代码为 import pymysql:
pyinstaller -F --hidden-import=pymysql jyw111.py
2# 运行 exe 并查看结果(若闪退,用此命令看具体报错)
.\jyw111.exe
# 安装 mysql-connector-python(对应 import mysql.connector)
pip install mysql-connector-python
5.验证是否安装成功
python -c "import mysql.connector; print(mysql.connector.__file__)"
显示安装路径为安装成功
第三步:重新打包(安装成功后)
powershell
# 1. 切换到 abc111.py 所在的真实目录(关键!别再在 demo\dist 执行)
cd "D:\aaa"
# 2. 删除旧打包文件(避免缓存)
rm -r build dist jabc111.spec
# 3. 带 hidden-import 打包
pyinstaller -F --hidden-import=mysql.connector abc111.py
第四步:测试 exe
powershell
# 进入新生成的 dist 目录(在 程序 文件夹下)
cd dist
.\abc111.exe
二、正确操作:用「单行完整命令」打包(复制粘贴即可)
步骤 1:先切换到 abc111.py 所在目录(关键!别在 dist 目录执行)
powershell
cd "D:\程序"
步骤 2:执行单行完整打包命令(包含所有依赖,无换行符)
pyinstaller -F --hidden-import=mysql.connector --hidden-import=mysql.connector.plugins --hidden-import=mysql.connector.plugins.mysql_native_password --hidden-import=mysql.connector.locales --hidden-import=mysql.connector.locales.eng abc111.py
四、完整流程(复制粘贴即可)
powershell
# 1. 切换到脚本所在目录
cd "D:\程序"
# 2. 删除旧打包文件(避免缓存)
rm -r build,dist,abc111.spec -ErrorAction SilentlyContinue
# 3. 完整打包命令(核心!一次性执行)
pyinstaller -F --hidden-import=mysql.connector --hidden-import=mysql.connector.plugins --hidden-import=mysql.connector.plugins.mysql_native_password --hidden-import=mysql.connector.locales --hidden-import=mysql.connector.locales.eng abc111.py
# 4. 切换到dist目录测试exe
cd dist
.\abc111.exe & pause
Python 打包生成的 .exe(基于 PyInstaller)可以被反编译,但反编译的难度和结果完整性取决于打包方式、是否做了加固,以下是详细说明:
一、为什么 PyInstaller 打包的 exe 容易被反编译? PyInstaller 本质不是「编译」,而是「打包」: 它会把 Python 字节码(.pyc)、解释器、依赖库打包成 exe; 运行时 exe 会先解压字节码到临时目录,再调用 Python 解释器执行; 反编译的核心就是提取这些字节码,再还原成 Python 源码。
二、反编译的具体步骤(以 PyInstaller 打包的 exe 为例)
步骤 1:提取 exe 中的字节码 用工具(如 pyinstxtractor)解压 exe,提取 .pyc 文件: powershell
1. 下载 pyinstxtractor(GitHub:https://github.com/extremecoders-re/pyinstxtractor)
2. 执行解压命令 python pyinstxtractor.py jyw111.exe 解压后会生成 jyw111.exe_extracted 文件夹,里面包含: 主程序的 .pyc 文件(如 jyw111.pyc); 依赖库的 .pyc 文件(如 mysql/connector/*.pyc)。
步骤 2:将 .pyc 反编译为 .py 源码 用工具(如 uncompyle6/decompyle3)还原字节码: powershell # 安装反编译工具 pip install uncompyle6 # 反编译单个 pyc 文件 uncompyle6 jyw111.pyc > jyw111.py # 批量反编译目录下的 pyc 文件 for /r %f in (*.pyc) do uncompyle6 "%f" > "%~pf%~nf.py"
三、反编译的局限性 代码完整性: 若代码中有混淆、加密(如 pyminifier 混淆),反编译后的代码会乱码 / 不可读; 若用了 --onefile(-F)打包,解压后需先修复 pyc 文件的头部信息(部分工具可自动修复)。 二进制依赖: C 扩展模块(如 .pyd/.dll)无法反编译为 Python 源码,只能看到调用接口; 加密的 .so/.dll 库(如商业 SDK)无法还原。 运行时动态代码: 若代码中有 exec()/eval() 执行的动态字符串,反编译后只能看到字符串,无法还原逻辑。
四、如何防止 / 增加反编译难度?
-
代码混淆(低成本) 用 pyminifier 混淆源码,让反编译后的代码难以阅读: powershell # 安装混淆工具 pip install pyminifier # 混淆代码(压缩+重命名变量+移除注释) pyminifier -O --rename-globals --remove-comments jyw111.py > jyw111_obf.py # 用混淆后的代码打包 pyinstaller -F jyw111_obf.py
-
加密字节码(中成本) 用 pyarmor 加密 Python 字节码,打包后 exe 运行时动态解密: powershell # 安装 pyarmor pip install pyarmor # 加密源码 pyarmor obfuscate jyw111.py # 用加密后的代码打包(pyarmor 会生成 dist 目录,里面是加密后的 .pyc) pyinstaller -F dist/jyw111.py
-
编译为 C 扩展(高成本) 用 Cython 将 Python 代码编译为 C 扩展(.pyd),再打包: powershell # 安装 Cython pip install cython # 编写 setup.py from setuptools import setup from Cython.Build import cythonize setup( ext_modules = cythonize("jyw111.py", compiler_directives={"language_level": "3"}) ) # 编译为 .pyd python setup.py build_ext --inplace # 改写入口文件(调用 .pyd),再打包 # 入口文件 main.py:import jyw111; jyw111.main() pyinstaller -F main.py
-
商业加固工具(最高成本) 用专业的 exe 加固工具(如 VMProtect、Themida)对 PyInstaller 生成的 exe 加壳,阻止解压和反编译。
五、总结
场景 是否可反编译 难度
原生 PyInstaller -F 是 低
加 pyminifier 混淆 是 中
加 pyarmor 加密 难(可破解) 高
Cython 编译为 C 扩展 几乎不可行 极高
核心结论: Python 打包的 exe 无法做到「绝对防反编译」,但可以通过混淆 / 加密大幅增加难度; 若代码涉及核心业务 / 敏感信息(如数据库账号),建议: 不要硬编码敏感信息(改用配置文件 / 环境变量); 至少用 pyarmor 加密字节码; 关键逻辑用 Cython 编译为 C 扩展。