分享

PyInstaller将Python文件打包为exe后如何反编译(破解源码)以及防止反编译 – Python量化投资

 大傻子的文渊阁 2020-03-27
kingmo888 @ Python量化投资 2018/8/29

PyInstaller将Python文件打包为exe后如何反编译(破解源码)以及防止反编译

在这里分享一些技巧和经验给大家。辛苦撰文分享,转载或引用请保留本文作者信息及文章链接。 作者的环境: win7+python3.5(anaconda3) 理论上,win7及以上的系统和python任意版本均可。 目录 一、基础脚本 二、使用PyInstaller打包为exe 三、反编译Pyinstaller打包的exe 四、将脚本编译为pyd以防止反编译 一、基础脚本 首先我们构建一个简单的脚本,比如输出一串数字、文本之类,这里我们输出一串文字的同时计算一下3次方好了。 # -*- coding: utf-8 -*- """ Created on Wed Aug 29 09:18:13 2018 @author: Li Zeng hai """ def test(num): print('num={n}, {n}^3={n2}'.format(n=num, n2=num**3)) if __name__ == '__main__': while 1: try: num = input('提示:输入"q"退出程序。\n请输入一个数字:') if num.lower() == 'q': break num = float(num) print(num) except: print('输入的数字不正确!') continue test(num) 把这段脚本保存为mylib.py,运行一下这个脚本: 可以看到,脚本正常运行了。 为了演示,我们把下面的脚本新建到main.py脚本文件中,并且从mylib中引入测试函数。 # -*- coding: utf-8 -*- from mylib import * while 1: try: num = input('提示:输入"q"退出程序。\n请输入一个数字:') if num.lower() == 'q': break num = float(num) print(num) except: print('输入的数字不正确!') continue test(num) 二、使用PyInstaller打包为exe 使用如下命令,将其打包为单一exe(去掉-F则不是单一exe) pyinstaller -F main.py 打包过程如下: E:\t>pyinstaller -F main.py 505 INFO: PyInstaller: 3.3.1 505 INFO: Python: 3.5.5 505 INFO: Platform: Windows-7-6.1.7601-SP1 505 INFO: wrote E:\t\main.spec 505 INFO: UPX is not available. 505 INFO: Extending PYTHONPATH with paths ['E:\\t', 'E:\\t'] 505 INFO: checking Analysis 505 INFO: Building Analysis because out00-Analysis.toc is non existent 505 INFO: Initializing module dependency graph... 521 INFO: Initializing module graph hooks... 521 INFO: Analyzing base_library.zip ... 6269 INFO: running Analysis out00-Analysis.toc 6269 INFO: Adding Microsoft.Windows.Common-Controls to dependent assemblies of final executable required by d:\anaconda3\python.exe 6956 INFO: Caching module hooks... 6956 INFO: Analyzing E:\t\main.py 6956 INFO: Loading module hooks... 6956 INFO: Loading module hook "hook-pydoc.py"... 6956 INFO: Loading module hook "hook-xml.py"... 7283 INFO: Loading module hook "hook-encodings.py"... 7533 INFO: Looking for ctypes DLLs 7549 INFO: Analyzing run-time hooks ... 7549 INFO: Looking for dynamic libraries 7720 INFO: Looking for eggs 7720 INFO: Using Python library d:\anaconda3\python35.dll 7720 INFO: Found binding redirects: [] 7720 INFO: Warnings written to E:\t\build\main\warnmain.txt 7751 INFO: Graph cross-reference written to E:\t\build\main\xref-main.html 7767 INFO: checking PYZ 7767 INFO: Building PYZ because out00-PYZ.toc is non existent 7767 INFO: Building PYZ (ZlibArchive) E:\t\build\main\out00-PYZ.pyz 8345 INFO: Building PYZ (ZlibArchive) E:\t\build\main\out00-PYZ.pyz completed successfully. 8345 INFO: checking PKG 8345 INFO: Building PKG because out00-PKG.toc is non existent 8345 INFO: Building PKG (CArchive) out00-PKG.pkg 9954 INFO: Building PKG (CArchive) out00-PKG.pkg completed successfully. 9954 INFO: Bootloader d:\anaconda3\lib\site-packages\PyInstaller\bootloader\Windows-64bit\run.exe 9954 INFO: checking EXE 9954 INFO: Building EXE because out00-EXE.toc is non existent 9954 INFO: Building EXE from out00-EXE.toc 9954 INFO: Appending archive to EXE E:\t\dist\main.exe 9954 INFO: Building EXE from out00-EXE.toc completed successfully. E:\t>     最终在目录下生成build、disk文件夹。其中exe文件在disk中。运行正常。如下图: 三、反编译Pyinstaller打包的exe 这样的exe已经可以被迁移到别的电脑上使用了,如果是为了方便其他电脑使用,到这一步就已经结束了。但有时候,我们可能是把这个功能给很多人用,但如果不想开源或者被别人破解,到这一步是还不够的。 因为到这一步的exe是可以被别人反编译出源码的。 此处用到的工具: exe反编译工具:pyinstxtractor.py:点击此处去下载 pyc反编译工具:Easy Python Decompiler 或者在线反编译pyc。 将pyinstxtractor.py放到exe文件相同目录,执行以下cmd命令: python pyinstxtractor.py main.exe 如果成功执行,将在同目录下生成新的反编译文件夹——main.exe_extracted,如下图:   同时,我们可以在下图圈起来的路径下,找到当时我们exe引入的mylib模块,其为pyc格式。     pyc格式的文件,反编译起来就非常简单了。用前文提供的工具或者网上找个在线的分分钟反编译出来,我们看下反编译的结果: #!/usr/bin/env python # visit http:///pyc/ for more information ''' Created on Wed Aug 29 09:18:13 2018 @author: Li Zeng hai ''' def test(num): print('num={n}, {n}^3={n2}'.format(n=num, n2=num ** 3)) if __name__ == '__main__': while None: try: num = input( '\xe6\x8f\x90\xe7\xa4\xba\xef\xbc\x9a\xe8\xbe\x93\xe5\x85\xa5"q"\xe9\x80\x80\xe5\x87\xba\xe7\xa8\x8b\xe5\xba\x8f\xe3\x80\x82\n\xe8\xaf\xb7\xe8\xbe\x93\xe5\x85\xa5\xe4\xb8\x80\xe4\xb8\xaa\xe6\x95\xb0\xe5\xad\x97\xef\xbc\x9a') if num.lower() == 'q': break num = float(num) print(num) except: None None None print( '\xe8\xbe\x93\xe5\x85\xa5\xe7\x9a\x84\xe6\x95\xb0\xe5\xad\x97\xe4\xb8\x8d\xe6\xad\xa3\xe7\xa1\xae\xef\xbc\x81') continue 可以看到,基本上完美的把源码反编译出来了。其中涉及到中文的地方,会因为编码问题有所改变。但是非中文部分,几乎一模一样。 就问你怕不怕!!! 四、将脚本编译为pyd以防止反编译 好怕怕 ,哈哈。 如何解决呢,可以考虑将模块py文件编译为动态链接库,这样破解难度将大大增加。其中,在python里,pyd格式即动态链接库。使用cython即可编译,如果是anaconda是自带,python有的可能不带cython,安装即可: pip install Cython 我们在main.py所在的文件夹新建py文件,在此处我命名为build_pyd.py,其内容如下: # -*- coding: utf-8 -*- """ Created on Wed Aug 29 13:33:20 2018 @author: Li Zeng hai """ from distutils.core import setup from Cython.Build import cythonize setup( name = 'any words.....', ext_modules = cythonize(["mylib.py", ] ), ) 然后执行以下cmd命令: python build_pyd.py build_ext --inplace 运行过程及生成结果如下图,其中红框的pyd文件即编译好了。因为我是64位的系统和python,所以会生成amd64后缀,我们把这个删掉重命名为mylib.pyd即可。 注:当同时存在mylib.pyd和mylib.py时,引入优先级是pyd>py,所以不用移除py文件,默认引入时就是pyd。   此时,我们删除build、disk文件夹,重复步骤二,再次编译为exe即可。 注意:编译需要相关的VC环境,因为python3.5是基于 VS14版本的,所以我这里安装的也是。不安装是无法编译的。 可以验证一下: 再次反编译main.exe后,原来的路径E:\t\dist\main.exe_extracted\out00-PYZ.pyz_extracted之下,已经找不到mylib.pyc了。 因为他已经不是可以直接反编译出来的文件了。 那么他在哪呢,他是作为pyd存在于上层目录中了。如下图:   pyd的反编译难度是相当高的,至此,就大功告成了! 托拉姆物语下载 0 收藏
扫描二维码继续阅读

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多