简单介绍一下pyinstaller打包以及安全性的实现


Posted in Python onJune 02, 2020

pyinstaller打包问题

简单介绍一下pyinstaller常用的参数:

可选参数 示例 说明
-F pyinstaller -F demo.py 只在dist文件夹中生成一个程序demo.exe文件,适用于一个模块没有多依赖.py文件
-D pyinstaller -D demo.py 默认选项,除了主程序demo.exe外,还会在在dist文件夹中生成很多依赖文件,推荐使用这个
-c pyinstaller -c demo.py 默认选项,只对windows有效,使用控制台
-w pyinstaller -w demo.py 只对windows有效,不使用控制台
-p pyinstaller -p D:\project\demo.py 设置导入路径
-i pyinstaller -i D:\icons\demo.ico demo.py 给生成的demo.exe文件设置一个自定义的图标

部分参数可组合使用,比如打包成一个.exe,不使用控制台:

pyinstaller -w -F demo.py

关于pyinstaller如何把图片,音乐,字体等素材文件也打包进exe文件中。这里就不整那些花里胡哨的东西了,直接讲讲我们该怎么做才能实现这个功能吧,先声明一下,其实这东西官网里就有教程,不明白且想明白为什么这么做的自己看官网的介绍吧:

https://pyinstaller.readthedocs.io/en/v3.3.1/runtime-information.html

用表白小软件为例,有用的就这三个文件:

简单介绍一下pyinstaller打包以及安全性的实现

其中love.py是主程序,cfg.py是配置文件,resources文件夹里是一些类似字体,音乐等的素材文件。
先直接试试运行如下命令打包:

pyinstaller -Fw love.py

打包结束后根目录变成了这样:

简单介绍一下pyinstaller打包以及安全性的实现

dist文件夹里有打包好的exe文件。打开文件夹,直接双击运行一下,会发现报错:

简单介绍一下pyinstaller打包以及安全性的实现

原因很简单,因为你没把相关的素材文件打包进这个exe文件,而在该目录下根据程序本身的设定是无法读取到这些素材文件的。你需要先把该exe文件移动到love.py这个主程序所在的目录,然后双击运行:

简单介绍一下pyinstaller打包以及安全性的实现

想要把素材文件也打包进exe文件的话,得先修改下程序,把程序中关于素材资源加载路径的相关代码从(在cfg.py文件里):

# 背景音乐路径
BGM_PATH = os.path.join(os.getcwd(), 'resources/music/bgm.mp3')
# 字体路径
FONT_PATH = os.path.join(os.getcwd(), 'resources/font/STXINGKA.TTF')
# 背景图片路径
BG_IMAGE_PATH = os.path.join(os.getcwd(), 'resources/images/bg.png')
# ICON路径
ICON_IMAGE_PATH = os.path.join(os.getcwd(), 'resources/images/icon.png')

改成:

if getattr(sys, 'frozen', False):
 cur_path = sys._MEIPASS
else:
 cur_path = os.path.dirname(__file__)
# 背景音乐路径
BGM_PATH = os.path.join(cur_path, 'resources/music/bgm.mp3')
# 字体路径
FONT_PATH = os.path.join(cur_path, 'resources/font/STXINGKA.TTF')
# 背景图片路径
BG_IMAGE_PATH = os.path.join(cur_path, 'resources/images/bg.png')
# ICON路径
ICON_IMAGE_PATH = os.path.join(cur_path, 'resources/images/icon.png')

然后新建一个.spec文件,当然,为了方便,你可以直接打开刚刚生成的那个.spec文件(就是运行最前面那个打包命令时,也会根据你的命令来生成一个love.spec文件),类似这样:

简单介绍一下pyinstaller打包以及安全性的实现

打开该文件,可以发现该文件里的内容是这样的(为了方便某些懒癌患者复制粘贴,我就不截图而是直接把内容copy下来了):

# -*- mode: python ; coding: utf-8 -*-

block_cipher = None


a = Analysis(['love.py'],
       pathex=['C:\\Users\\xx\\Desktop\\NaughtyConfession'],
       binaries=[],
       datas=[],
       hiddenimports=[],
       hookspath=[],
       runtime_hooks=[],
       excludes=[],
       win_no_prefer_redirects=False,
       win_private_assemblies=False,
       cipher=block_cipher,
       noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
       cipher=block_cipher)
exe = EXE(pyz,
     a.scripts,
     a.binaries,
     a.zipfiles,
     a.datas,
     [],
     name='love',
     debug=False,
     bootloader_ignore_signals=False,
     strip=False,
     upx=True,
     upx_exclude=[],
     runtime_tmpdir=None,
     console=False )

通过修改该文件,可以将指定的素材资源全部打包进exe文件中,具体而言,修改后的文件如下:

# -*- mode: python ; coding: utf-8 -*-

block_cipher = None


added_files = [('C:\\Users\\xx\\Desktop\\NaughtyConfession\\resources', 'resources')]
a = Analysis(['love.py'],
       pathex=['C:\\Users\\xx\\Desktop\\NaughtyConfession'],
       binaries=[],
       datas=added_files,
       hiddenimports=[],
       hookspath=[],
       runtime_hooks=[],
       excludes=[],
       win_no_prefer_redirects=False,
       win_private_assemblies=False,
       cipher=block_cipher,
       noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
       cipher=block_cipher)
exe = EXE(pyz,
     a.scripts,
     a.binaries,
     a.zipfiles,
     a.datas,
     [],
     name='love',
     debug=False,
     bootloader_ignore_signals=False,
     strip=False,
     upx=True,
     upx_exclude=[],
     runtime_tmpdir=None,
     console=False )

其实就加了一行代码(第六行):

added_files = [('C:\\Users\\xx\\Desktop\\NaughtyConfession\\resources', 'resources')]

然后把(第十行)datas=[],改成了datas=added_files,

就这么简单就完事了,最后在命令行运行:

pyinstaller -F love.spec

同样地,在dist文件夹里会生成打包好的exe文件,双击运行一下,可以发现这个exe文件竟然可以直接运行啦:

简单介绍一下pyinstaller打包以及安全性的实现

至此,我们轻松地实现了将python程序的素材文件一起打包进exe文件的目标。当然,上面只是介绍了一种个人比较习惯且相对简单方便的解决方案,想了解更多相关内容以及原理,各位小伙伴还是自己去查阅官方文档吧:
https://pyinstaller.readthedocs.io/en/v3.3.1/index.html

pyinstaller安全性问题

以我们刚刚打包好的exe文件为例,就是它:

简单介绍一下pyinstaller打包以及安全性的实现

假设我们只把这个exe文件发给了心仪的小姐姐/小哥哥(然后人家拉黑了你)。那么对方能不能通过这个exe文件来获得你的源代码呢?可以。让我们一步步操作下去来实现这个目的。

先到这下载个解包工具:
https://sourceforge.net/projects/pyinstallerextractor/

下载后长这样:

简单介绍一下pyinstaller打包以及安全性的实现

再下载个十六进制编辑器,一会要用到:
https://wxmedit.github.io/downloads.html

然后运行如下命令:

python pyinstxtractor.py love.exe

运行后发现根目录变成了这样:

简单介绍一下pyinstaller打包以及安全性的实现

多了一个文件夹,打开后发现里面一堆ddl,pyd文件:

简单介绍一下pyinstaller打包以及安全性的实现

在这里面我们可以找到三个比较关键的文件:

简单介绍一下pyinstaller打包以及安全性的实现

其中love就是你之前打包的那个py文件对应的pyc文件。注意,如果exe文件名被改动过,比如一开始打包好的love.exe被改成了pig.exe,那么你找到的文件仍然是love.exe.manifest,而不是pig.exe.manifest

struct也是一个pyc文件。于是我们现在只需要反编译这些pyc文件就行了,随便搜索下就可以发现一堆相关的网站:

简单介绍一下pyinstaller打包以及安全性的实现

随便选一个就OK了:
http://tools.bugscaner.com/decompyle/

打开lovestruct文件(重命名一下加个后缀就变成pyc文件):

简单介绍一下pyinstaller打包以及安全性的实现

struct.pyc文件里的前12个字节复制到love.pyc文件里,love.pyc文件变成了这样:

简单介绍一下pyinstaller打包以及安全性的实现

保存,然后拿去在线反编译,即可拿到源码。
可以发现我们已经成功地通过exe文件获得了程序的源代码。

不过pyinstaller提供了?key这个选项,可以实现加密打包,但实际上它只对依赖库进行了加密,并没有对主程序做加密处理。

到此这篇关于简单介绍一下pyinstaller打包以及安全性的实现的文章就介绍到这了,更多相关pyinstaller打包及安全性内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python socket网络编程步骤详解(socket套接字使用)
Dec 06 Python
分享一个常用的Python模拟登陆类
Mar 29 Python
总结用Pdb库调试Python的方式及常用的命令
Aug 18 Python
git进行版本控制心得详谈
Dec 10 Python
python实现学生管理系统
Jan 11 Python
django manage.py扩展自定义命令方法
May 27 Python
flask框架实现连接sqlite3数据库的方法分析
Jul 16 Python
win7上tensorflow2.2.0安装成功 引用DLL load failed时找不到指定模块 tensorflow has no attribute xxx 解决方法
May 20 Python
使用python库xlsxwriter库来输出各种xlsx文件的示例
Sep 01 Python
浅析Python的命名空间与作用域
Nov 25 Python
Python+Opencv实现把图片、视频互转的示例
Dec 17 Python
Python字符串的转义字符
Apr 07 Python
Python几种常见算法汇总
Jun 02 #Python
opencv-python的RGB与BGR互转方式
Jun 02 #Python
解决pyinstaller打包运行程序时出现缺少plotly库问题
Jun 02 #Python
Pytorch 使用opnecv读入图像由HWC转为BCHW格式方式
Jun 02 #Python
基于pycharm实现批量修改变量名
Jun 02 #Python
pytorch读取图像数据转成opencv格式实例
Jun 02 #Python
Python使用jupyter notebook查看ipynb文件过程解析
Jun 02 #Python
You might like
php 图像函数大举例(非原创)
2009/06/20 PHP
php数组合并的二种方法
2014/03/21 PHP
PHP的Socket网络编程入门指引
2015/08/11 PHP
WordPress中转义HTML与过滤链接的相关PHP函数使用解析
2015/12/22 PHP
php函数传值的引用传递注意事项分析
2016/06/25 PHP
Prototype使用指南之range.js
2007/01/10 Javascript
js实现收缩菜单效果实例代码
2013/10/30 Javascript
JS动态修改iframe内嵌网页地址的方法
2015/04/01 Javascript
使用Jasmine和Karma对AngularJS页面程序进行测试
2016/03/05 Javascript
html中鼠标滚轮事件onmousewheel的处理方法
2016/11/11 Javascript
jQuery File Upload文件上传插件使用详解
2016/12/06 Javascript
Bootstrap表单使用方法详解
2017/02/17 Javascript
SVG动画vivus.js库使用小结(实例代码)
2017/09/14 Javascript
解决vue 路由变化页面数据不刷新的问题
2018/03/13 Javascript
快速解决bootstrap下拉菜单无法隐藏的问题
2018/08/10 Javascript
Node.js EventEmmitter事件监听器用法实例分析
2019/01/07 Javascript
JavaScript两种计时器的实例讲解
2019/01/31 Javascript
微信小程序实现搜索功能并跳转搜索结果页面
2019/05/18 Javascript
JavaScript函数式编程(Functional Programming)声明式与命令式实例分析
2019/05/21 Javascript
vue封装可复用组件confirm,并绑定在vue原型上的示例
2019/10/31 Javascript
微信公众号服务器验证Token步骤图解
2019/12/30 Javascript
python异步任务队列示例
2014/04/01 Python
跟老齐学Python之使用Python操作数据库(1)
2014/11/25 Python
python与php实现分割文件代码
2017/03/06 Python
Python cookbook(数据结构与算法)从字典中提取子集的方法示例
2018/03/22 Python
基于循环神经网络(RNN)的古诗生成器
2018/03/26 Python
python爬虫刷访问量 2019 7月
2019/08/01 Python
解决Pycharm 中遇到Unresolved reference 'sklearn'的问题
2020/07/13 Python
css3动画效果抖动解决方法
2018/09/03 HTML / CSS
HTML5 Canvas 绘图——使用 Canvas 绘制图形图文教程 使用html5 canvas 绘制精美的图
2015/08/31 HTML / CSS
学校欢迎标语
2014/06/18 职场文书
网络技术专业求职信
2014/07/13 职场文书
保密工作目标责任书
2014/07/28 职场文书
工作证明格式及范本
2014/09/12 职场文书
2015暑假社会调查报告
2015/07/13 职场文书
Go本地测试解耦任务拆解及沟通详解Go本地测试的思路沟通的重要性总结
2022/06/21 Golang