PAYATHON 2026

为什么 mcafee 将 PyInstaller 生成的 .exe 标记为威胁?

排障赵师傅

结论

PyInstaller 生成的 .exe 被 McAfee 标记为威胁,多数情况下是启发式检测产生的误报。使用 --onefile 打包后,程序会在运行时解包并加载 Python 解释器、脚本和依赖,这与部分恶意软件的加载方式相似。文件缺少数字签名、样本流行度较低或使用了压缩工具,也可能增加触发检测的概率。

即使脚本是自己写的,也不能直接认定检测结果是误报。依赖包、构建环境和 PyInstaller 本身都要检查。比较稳妥的处理方式包括:在干净环境中重新构建,减少容易触发检测的打包特征,为程序签名,再向 McAfee 提交误报样本。

为什么 --onefile 更容易被标记

--onefile 会把 Python 解释器、业务代码和依赖库封装进一个可执行文件。程序启动时,PyInstaller 的 bootloader 会把这些内容释放到临时目录,再加载相应模块。

这个过程会产生一些杀毒软件较为敏感的特征:

  • 可执行文件中含有压缩或封装后的代码,静态分析难度较高。
  • 程序运行时会向临时目录写入文件并加载 DLL。
  • 大量 PyInstaller 程序使用相似的 bootloader 结构。恶意程序也可能用 PyInstaller 打包,所以病毒样本库中会出现这些特征。
  • 自行编译的程序通常没有 Authenticode 数字签名,也缺少下载量和信誉记录。
  • 启用 UPX 后,压缩产生的二进制特征和较高的信息熵可能进一步增加误报概率。
  • 第三方依赖可能带有原生二进制文件,其中也可能确实存在风险。

正常程序和用 PyInstaller 打包的恶意程序可能具有相似的文件特征或运行行为,启发式检测很难单凭打包工具判断程序的真实意图。

先修正并清理构建过程

一般不需要在命令末尾加额外的 .。可以使用:

pyinstaller --onefile script.py

新建虚拟环境,在其中安装核对过的依赖,再重新构建:

python -m venv .venv

在 Windows PowerShell 中激活环境:

.\.venv\Scripts\Activate.ps1

安装或更新构建工具:

python -m pip install --upgrade pip pyinstaller

如果项目有锁定的依赖文件,可按项目情况安装:

python -m pip install -r requirements.txt

清理 PyInstaller 缓存并重新生成文件:

pyinstaller --clean --noconfirm --onefile --noupx script.py

--noupx 会阻止 PyInstaller 调用 UPX。它不能保证消除误报,但可以帮助判断误报是否与二进制压缩有关。如果没有安装或使用 UPX,这个参数通常不会造成明显变化。

不要在添加杀毒软件排除项后直接发布程序。只有确认源码、依赖和构建环境安全时,才适合在本机调试期间临时使用排除项。

对比 onedir 构建结果

可以暂时改用 --onedir,检查目录模式是否仍会触发检测:

pyinstaller --clean --noconfirm --onedir --noupx script.py

目录模式不会把所有内容封装进单个文件,启动时也没有相同的自解包过程,因此误报有时会减少。

如果 --onedir 不报警,而 --onefile 报警,检测很可能与单文件封装或运行时解包有关。如果两种模式都报警,就要重点检查脚本行为、第三方依赖和构建环境。

检查文件和依赖是否真的安全

至少需要做以下检查:

  1. 使用最新版安全工具扫描源码目录、虚拟环境和构建机器。
  2. 核对依赖来源,不要从不可信的镜像、网盘或未知网站安装软件包。
  3. 查看实际安装的软件包及版本:
python -m pip freeze
  1. 检查依赖关系:
python -m pip check
  1. 记录生成文件的 SHA-256,以便比较不同的构建结果或提交误报:
Get-FileHash .\dist\script.exe -Algorithm SHA256

还可以使用多引擎扫描服务交叉检查,但上传前要确认程序中没有密钥、客户数据或其他敏感内容。多家引擎报毒不能直接证明文件是恶意程序,只有一家报毒也不能证明文件绝对安全。判断时还要结合检测名称、行为分析和构建来源。

为发布文件添加数字签名

如果程序要分发给其他用户,建议使用受信任证书进行 Authenticode 签名。签名可以证明发布者身份,也能让用户确认文件在签名后没有被修改。签名文件逐渐积累信誉后,误报概率通常会降低,但数字签名不能保证杀毒软件一定放行。

安装 Windows SDK 后,可以使用 signtool 签名。以下地址和证书选择方式需要替换为证书服务商提供的信息:

signtool sign `
  /fd SHA256 `
  /tr <RFC_3161_TIMESTAMP_URL> `
  /td SHA256 `
  /a `
  .\dist\script.exe

验证签名:

signtool verify /pa /v .\dist\script.exe

应在最终构建完成后签名。签名后再次修改文件会导致签名失效。

向 McAfee 提交误报

确认源码、依赖和构建机器没有问题后,记录以下信息,并通过 McAfee 当前提供的误报提交渠道发送样本:

  • McAfee 显示的完整检测名称;
  • 产品版本和病毒库版本;
  • 文件的 SHA-256;
  • PyInstaller 命令及版本;
  • Python 版本;
  • 是否使用 --onefile、UPX 或数字签名;
  • 可复现问题的最小样本;
  • 程序用途和运行行为的简要说明。

检测该文件的安全厂商才能修正误报规则。修改本地文件名、反复重新打包或改动 bootloader,也许能暂时改变文件哈希,但无法稳定解决问题,还可能让文件显得更可疑。

本机文件被隔离时怎么办

如果 McAfee 已隔离文件,先查看检测名称和事件记录。确认以下情况后,才适合从隔离区恢复文件或为开发目录设置临时排除:

  • 文件由可信源码在受控环境中构建;
  • 所有依赖的来源都可以核对;
  • 构建机器没有感染迹象;
  • 文件哈希与刚完成的构建结果一致;
  • 没有发现异常网络连接、进程注入、持久化或下载执行行为。

排除项只对当前设备有效,无法解决其他用户收到文件时的告警。向用户发布程序时,仍应采用干净构建和数字签名,并向安全厂商申诉误报。

备注:内容仅供参考。